From 95f06fb8ae6caab7c8f39a0f7aafee69c4ea8e33 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 17 Aug 2013 15:03:00 -0400 Subject: [PATCH 001/245] Add migration guide stub for 2.5 --- en/appendices.rst | 9 +++++++++ en/appendices/2-5-migration-guide.rst | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 en/appendices/2-5-migration-guide.rst diff --git a/en/appendices.rst b/en/appendices.rst index 9cbb3d4ab..c2c6a841e 100644 --- a/en/appendices.rst +++ b/en/appendices.rst @@ -4,6 +4,15 @@ Appendices Appendices contain information regarding the new features introduced in 2.0, and the migration path from 1.3 to 2.0. +2.5 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-5-migration-guide + + 2.4 Migration Guide =================== diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst new file mode 100644 index 000000000..5162ab499 --- /dev/null +++ b/en/appendices/2-5-migration-guide.rst @@ -0,0 +1,7 @@ +2.5 Migration Guide +################### + +CakePHP 2.5 is a fully API compatible upgrade from 2.4. This page outlines +the changes and improvements made in 2.5. + + -- GitLab From ba8ab70bc2fca9a16f6e18dfb61736237d42ba79 Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Sun, 18 Aug 2013 16:14:41 +0700 Subject: [PATCH 002/245] Docs for `connectOptions` with Router::mapResources() --- en/appendices/2-5-migration-guide.rst | 7 +++++++ en/development/rest.rst | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 5162ab499..7d2b98f2b 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -4,4 +4,11 @@ CakePHP 2.5 is a fully API compatible upgrade from 2.4. This page outlines the changes and improvements made in 2.5. +Routing +======= +Router +------ + +- :php:meth:`Router::mapResources()` accepts ``connectOptions`` key in the + ``$options`` argument. See :ref:`custom-rest-routing` for more details. diff --git a/en/development/rest.rst b/en/development/rest.rst index e70f4f4fa..85060794e 100644 --- a/en/development/rest.rst +++ b/en/development/rest.rst @@ -200,6 +200,7 @@ this method you need to set *all* the defaults you want to use:: By overwriting the default resource map, future calls to ``mapResources()`` will use the new values. +.. _custom-rest-routing: Custom REST Routing =================== @@ -209,6 +210,18 @@ for you, use the :php:meth:`Router::connect()` method to define a custom set of REST routes. The ``connect()`` method allows you to define a number of different options for a given URL. See the section on :ref:`route-conditions` for more information. +.. versionadded:: 2.5 + +You can provide ``connectOptions`` key in the ``$options`` array for +:php:meth:`Router::mapResources()` to provide custom setting used by +:php:meth:`Router::connect()`:: + + Router::mapResources('books', array( + 'connectOptions' => array( + 'routeClass' => 'ApiRoute', + ) + )); + .. meta:: :title lang=en: REST :keywords lang=en: application programmers,default routes,core functionality,result format,mashups,recipe database,request method,easy access,config,soap,recipes,logic,audience,cakephp,running,api -- GitLab From fe6369b922c0598763dabc46117f2392ed6f1aee Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 24 Aug 2013 21:53:35 -0400 Subject: [PATCH 003/245] Update docs for new Hash feature. --- en/appendices/2-5-migration-guide.rst | 9 +++++++++ en/core-utility-libraries/hash.rst | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 7d2b98f2b..63bbd032a 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -12,3 +12,12 @@ Router - :php:meth:`Router::mapResources()` accepts ``connectOptions`` key in the ``$options`` argument. See :ref:`custom-rest-routing` for more details. + +Utility +======= + +Hash +---- + +- :php:meth:`Hash::insert()` and :php:meth:`Hash::remove()` now support matcher + expressions in their path selectors. diff --git a/en/core-utility-libraries/hash.rst b/en/core-utility-libraries/hash.rst index 1118e2031..851f026b9 100644 --- a/en/core-utility-libraries/hash.rst +++ b/en/core-utility-libraries/hash.rst @@ -37,8 +37,11 @@ elements. You apply matchers to expression elements. | ``Foo`` | Matches keys with the exact same value. | +--------------------------------+--------------------------------------------+ -All expression elements are supported all methods. In addition to expression -elements you can use attribute matching with methods like ``extract()``. +All of the above expression elements are supported by all methods. In addition +to expression elements, you can use attribute matching with certain methods. +They are ``extract()``, ``combine()``, ``format()``, ``check()``, ``map()``, +``reduce()``, ``apply()``, ``sort()``, ``insert()``, ``remove()`` and +``nest()``. +--------------------------------+--------------------------------------------+ | Matcher | Definition | @@ -63,6 +66,9 @@ elements you can use attribute matching with methods like ``extract()``. | | the regular expression inside ``...``. | +--------------------------------+--------------------------------------------+ +.. versionchanged:: 2.5 + Matcher support was added to ``insert()`` and ``remove()``. + .. php:staticmethod:: get(array $data, $path) :rtype: mixed @@ -91,8 +97,7 @@ elements you can use attribute matching with methods like ``extract()``. :rtype: array - Inserts $data into an array as defined by $path. This method only supports - the expression types of :ref:`hash-path-syntax`:: + Inserts $data into an array as defined by ``$path``:: $a = array( 'pages' => array('name' => 'page') @@ -117,12 +122,15 @@ elements you can use attribute matching with methods like ``extract()``. $users = $this->User->find('all'); $users = Hash::insert($users, '{n}.User.new', 'value'); + .. versionchanged:: 2.5 + As of 2.5.0 attribute matching expressions work with insert(). + + .. php:staticmethod:: remove(array $data, $path = null) :rtype: array - Removes all elements from an array that match $path. This method supports - all the expression elements of :ref:`hash-path-syntax`:: + Removes all elements from an array that match $path.:: $a = array( 'pages' => array('name' => 'page'), @@ -142,6 +150,9 @@ elements you can use attribute matching with methods like ``extract()``. Using ``{n}`` and ``{s}`` will allow you to remove multiple values at once. + .. versionchanged:: 2.5 + As of 2.5.0 attribute matching expressions work with remove() + .. php:staticmethod:: combine(array $data, $keyPath = null, $valuePath = null, $groupPath = null) :rtype: array -- GitLab From 9065d7d5593d561381fd45758b5b81fb92e76415 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 26 Aug 2013 16:30:45 -0400 Subject: [PATCH 004/245] Update pagination docs to not use deprecated Controller::paginate() --- en/core-libraries/components/pagination.rst | 24 ++++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/en/core-libraries/components/pagination.rst b/en/core-libraries/components/pagination.rst index 62f337cb0..4bfd01384 100644 --- a/en/core-libraries/components/pagination.rst +++ b/en/core-libraries/components/pagination.rst @@ -30,6 +30,8 @@ here that the order key must be defined in an array structure like below:: class PostsController extends AppController { + public $components = array('Paginator'); + public $paginate = array( 'limit' => 25, 'order' => array( @@ -43,6 +45,8 @@ You can also include other :php:meth:`~Model::find()` options, such as class PostsController extends AppController { + public $components = array('Paginator'); + public $paginate = array( 'fields' => array('Post.id', 'Post.created'), 'limit' => 25, @@ -63,6 +67,8 @@ pagination:: class RecipesController extends AppController { + public $components = array('Paginator'); + public $paginate = array( 'limit' => 25, 'contain' => array('Article') @@ -95,25 +101,27 @@ adds PaginatorHelper to the list of helpers in your controller, if it has not been added already.:: public function list_recipes() { + $this->Paginator->settings = $this->paginate; + // similar to findAll(), but fetches paged results - $data = $this->paginate('Recipe'); + $data = $this->Paginator->paginate('Recipe'); $this->set('data', $data); } You can filter the records by passing conditions as second parameter to the ``paginate()`` function.:: - $data = $this->paginate('Recipe', array('Recipe.title LIKE' => 'a%')); + $data = $this->Paginator->paginate('Recipe', array('Recipe.title LIKE' => 'a%')); Or you can also set ``conditions`` and other keys in the ``$paginate`` array inside your action.:: public function list_recipes() { - $this->paginate = array( + $this->Paginator->settings = array( 'conditions' => array('Recipe.title LIKE' => 'a%'), 'limit' => 10 ); - $data = $this->paginate('Recipe'); + $data = $this->Paginator->paginate('Recipe'); $this->set(compact('data')); ); @@ -199,7 +207,7 @@ the keyword in controller's ``$paginate`` class variable:: * Or on-the-fly from within the action */ public function index() { - $this->paginate = array( + $this->Paginator->settings = array( 'MyModel' => array( 'limit' => 20, 'order' => array('week' => 'desc'), @@ -218,9 +226,9 @@ Control which fields used for ordering By default sorting can be done with any column on a model. This is sometimes undesirable as it can allow users to sort on un-indexed columns, or virtual fields that can be expensive to calculate. You can use the 3rd parameter of -``Controller::paginate()`` to restrict the columns sorting will be done on:: +``PaginatorComponent::paginate()`` to restrict the columns sorting will be done on:: - $this->paginate('Post', array(), array('title', 'slug')); + $this->Paginator->paginate('Post', array(), array('title', 'slug')); This would allow sorting on the title and slug columns only. A user that sets sort to any other value will be ignored. @@ -306,7 +314,7 @@ block and take appropriate action when a `NotFoundException` is caught:: public function index() { try { - $this->paginate(); + $this->Paginator->paginate(); } catch (NotFoundException $e) { //Do something here like redirecting to first or last page. //$this->request->params['paging'] will give you required info. -- GitLab From 46611e5a07298b5813b1d5f6a9198402cb556ca2 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 Aug 2013 09:42:55 -0400 Subject: [PATCH 005/245] Update migration guide for new feature. --- en/appendices/2-5-migration-guide.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 63bbd032a..b21fba1db 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -4,6 +4,15 @@ CakePHP 2.5 is a fully API compatible upgrade from 2.4. This page outlines the changes and improvements made in 2.5. +Network +======= + +CakeRequest +----------- + +- :php:meth:`CakeRequest::addDetector()` now supports ``options`` which + accepts an array of valid options when creating param based detectors. + Routing ======= -- GitLab From 8375482437d6d3a53f914440d206702b7540fd03 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 31 Aug 2013 12:43:50 -0400 Subject: [PATCH 006/245] Update docs for new option. --- en/appendices/2-5-migration-guide.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index b21fba1db..2cbfb7428 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -4,6 +4,16 @@ CakePHP 2.5 is a fully API compatible upgrade from 2.4. This page outlines the changes and improvements made in 2.5. +Console +======= + +SchemaShell +----------- + +- The ``create`` and ``update`` subcommands now have a ``yes`` option. The + ``yes`` option allows you to skip the various interactive questions forcing + a yes reply. + Network ======= -- GitLab From 170c9c17ae738ed84a7c151e51508001e08a00a6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 31 Aug 2013 13:47:45 -0400 Subject: [PATCH 007/245] Update docs to mention new memcached adapter. --- en/appendices/2-5-migration-guide.rst | 8 ++++++++ en/core-libraries/caching.rst | 9 +++++++-- en/development/sessions.rst | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 2cbfb7428..2a92a0d39 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -4,6 +4,14 @@ CakePHP 2.5 is a fully API compatible upgrade from 2.4. This page outlines the changes and improvements made in 2.5. +Cache +===== + +- A new adapter has been added for ``Memcached``. This new adapter uses + ext/memcached instead of ext/memcache. It supports improved performance and + shared persistent connections. +- The ``Memcache`` adapter is now deprecated in favor of ``Memcached``. + Console ======= diff --git a/en/core-libraries/caching.rst b/en/core-libraries/caching.rst index 658b2e535..c0b28ce70 100644 --- a/en/core-libraries/caching.rst +++ b/en/core-libraries/caching.rst @@ -31,6 +31,8 @@ to implement your own caching systems. The built-in caching engines are: * ``MemcacheEngine`` Uses the `Memcache `_ extension. Memcache provides a very fast cache system that can be distributed across many servers, and provides atomic operations. +* ``MemcachedEngine`` Uses the `Memcached `_ + extension. It also interfaces with memcache but provides better performance. * ``RedisEngine`` Uses the `phpredis `_ extension. Redis provides a fast and persistent cache system similar to memcached, also provides atomic operations. @@ -40,6 +42,9 @@ to implement your own caching systems. The built-in caching engines are: had difficulty setting up and deploying APC correctly both in cli + web. Using files should make setting up CakePHP simpler for new developers. +.. versionchanged:: 2.5 + The Memcached engine was added. And the Memecache engine was deprecated. + Regardless of the CacheEngine you choose to use, your application interacts with :php:class:`Cache` in a consistent manner. This means you can easily swap cache engines as your application grows. In addition to the :php:class:`Cache` class, the @@ -233,7 +238,7 @@ After setting an integer value, you can manipulate it using .. note:: Incrementing and decrementing do not work with FileEngine. You should use - APC, Redis or Memcache instead. + APC, Redis or Memcached instead. Using groups @@ -391,7 +396,7 @@ Cache API .. php:staticmethod:: clear($check, $config = 'default') Destroy all cached values for a cache configuration. In engines like Apc, - Memcache and Wincache, the cache configuration's prefix is used to remove + Memcached and Wincache, the cache configuration's prefix is used to remove cache entries. Make sure that different cache configurations have different prefixes. diff --git a/en/development/sessions.rst b/en/development/sessions.rst index 076b37f2c..7332bac9f 100644 --- a/en/development/sessions.rst +++ b/en/development/sessions.rst @@ -175,7 +175,7 @@ Cache Sessions -------------- The Cache class can be used to store sessions as well. This allows you to store -sessions in a cache like APC, memcache, or Xcache. There are some caveats to +sessions in a cache like APC, Memcached, or Xcache. There are some caveats to using cache sessions, in that if you exhaust the cache space, sessions will start to expire as records are evicted. -- GitLab From 67b1b19ed16e83b1c00629f550381be819488231 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 2 Sep 2013 11:23:44 -0400 Subject: [PATCH 008/245] Add new method docs + update migration guide. Change the wording around Security::cipher to more strongly discourage its use. --- en/appendices/2-5-migration-guide.rst | 17 +++++++++ en/core-utility-libraries/security.rst | 51 +++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 2a92a0d39..4c9e907c7 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -22,6 +22,16 @@ SchemaShell ``yes`` option allows you to skip the various interactive questions forcing a yes reply. +Controller +========== + +CookieComponent +--------------- + +- :php:class:`CookieComponent` can use the new AES-256 encryption offered by + :php:class:`Security`. You can enable this by calling + :php:meth:`CookieComponent::type()` with 'aes'. + Network ======= @@ -48,3 +58,10 @@ Hash - :php:meth:`Hash::insert()` and :php:meth:`Hash::remove()` now support matcher expressions in their path selectors. + +Security +-------- + +- :php:meth:`Security::encrypt()` and :php:meth:`Security::decrypt()` were + added. These methods expose a very simple API to access AES-256 symmetric encryption. + They should be used in favour of the ``cipher()`` and ``rijndael()`` methods. diff --git a/en/core-utility-libraries/security.rst b/en/core-utility-libraries/security.rst index 841c82171..4f1cbcc24 100644 --- a/en/core-utility-libraries/security.rst +++ b/en/core-utility-libraries/security.rst @@ -22,8 +22,10 @@ Security API // Later decrypt your text $nosecret = Security::cipher($secret, 'my_key'); - ``cipher()`` uses a **weak** XOR cipher and should **not** be used for - important or sensitive data. + .. warning:: + + ``cipher()`` uses a **weak** XOR cipher and should **not** be used. + It is only included for backwards compatibility. .. php:staticmethod:: rijndael($text, $key, $mode) @@ -49,6 +51,51 @@ Security API .. versionadded:: 2.2 ``Security::rijndael()`` was added in 2.2. +.. php:staticmethod:: encrypt($text, $key, $hmacSalt = null) + + :param string $plain: The value to encrypt. + :param string $key: The 256 bit/32 byte key to use as a cipher key. + :param string $hmacSalt: The salt to use for the HMAC process. Leave null to use Security.salt. + + Encrypt ``$text`` using AES-256. The ``$key`` should be a value with a + lots of variance in the data much like a good password. The returned result + will be the encrypted value with an HMAC checksum. + + This method should **never** be used to store passwords. Instead you should + use the one way hashing methods provided by :php:meth:`~Security::hash()`. + An example use would be:: + + // Assuming key is stored somewhere it can be re-used for + // decryption later. + $key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA'; + $result = Security::encrypt($value, $key); + + Encrypted values can be decrypted using :php:meth:`Security::decrypt()`. + + .. versionadded:: 2.5 + +.. php:staticmethod:: decrypt($cipher, $key, $hmacSalt = null) + + :param string $cipher: The ciphertext to decrypt. + :param string $key: The 256 bit/32 byte key to use as a cipher key. + :param string $hmacSalt: The salt to use for the HMAC process. Leave null to use Security.salt. + + Decrypt a previously encrypted value. The ``$key`` and ``$hmacSalt`` + parameters must match the values used to encrypt or decryption will fail. An + example use would be:: + + // Assuming key is stored somewhere it can be re-used for + // decryption later. + $key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA'; + + $cipher = $user['User']['secrets']; + $result = Security::decrypt($cipher, $key); + + If the value cannot be decrypted due to changes in the key or HMAC salt + ``false`` will be returned. + + .. versionadded:: 2.5 + .. php:staticmethod:: generateAuthKey( ) :rtype: string -- GitLab From 737e3ad289a24226419b0d4724350f1fd6b9df50 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 2 Sep 2013 11:27:45 -0400 Subject: [PATCH 009/245] Update cookie component docs for aes encryption. --- en/core-libraries/components/cookie.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/en/core-libraries/components/cookie.rst b/en/core-libraries/components/cookie.rst index 4fbbcba29..a8e163cd7 100644 --- a/en/core-libraries/components/cookie.rst +++ b/en/core-libraries/components/cookie.rst @@ -27,7 +27,7 @@ allows you to define how the CookieComponent works. | | | the value written to the cookie. | | | | This string should be random and difficult to guess. | | | | | -| | | When using rijndael encryption this value | +| | | When using rijndael or aes encryption this value | | | | must be longer than 32 bytes. | +-----------------+--------------+------------------------------------------------------+ | string $domain | '' | The domain name allowed to access the cookie. e.g. | @@ -65,6 +65,7 @@ a secure connection, is available on the path ‘/bakers/preferences/’, expires in one hour and is HTTP only:: public $components = array('Cookie'); + public function beforeFilter() { parent::beforeFilter(); $this->Cookie->name = 'baker_id'; @@ -74,6 +75,7 @@ a secure connection, is available on the path $this->Cookie->secure = true; // i.e. only sent if using secure HTTPS $this->Cookie->key = 'qSI232qs*&sXOw!adre@34SAv!@*(XSL#$%)asGb$@11~_+!@#HKis~#^'; $this->Cookie->httpOnly = true; + $this->Cookie->type('aes'); } Next, let’s look at how to use the different methods of the Cookie @@ -107,12 +109,9 @@ The CookieComponent offers a number of methods for working with Cookies. All values in the cookie are encrypted by default. If you want to store the values as plain-text, set the third parameter of the - write() method to false. The encryption performed on cookie values - is fairly uncomplicated encryption system. It uses - ``Security.salt`` and a predefined Configure class var - ``Security.cipherSeed`` to encrypt values. To make your cookies - more secure you should change ``Security.cipherSeed`` in - app/Config/core.php to ensure a better encryption.:: + write() method to false. You should remember to set + the encryption mode to 'aes' to ensure values are securely + encrypted:: $this->Cookie->write('name', 'Larry', false); @@ -168,13 +167,16 @@ The CookieComponent offers a number of methods for working with Cookies. .. php:method:: type($type) - Allows you to change the encryption scheme. By default the 'cipher' scheme - is used. However, you should use the 'rijndael' scheme for improved - security. + Allows you to change the encryption scheme. The 'cipher' scheme is used for + backwards compatibility. However, you should always use either the 'rijndael' or + 'aes' schemes. .. versionchanged:: 2.2 The 'rijndael' type was added. + .. versionadded:: 2.5 + The 'aes' type was added. + .. meta:: :title lang=en: Cookie -- GitLab From f2b666e4fa72299cc99325d447f82ef6626b7ba6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 11 Sep 2013 12:26:59 -0400 Subject: [PATCH 010/245] Add docs for new features on View. --- en/appendices/2-5-migration-guide.rst | 10 ++++++++++ en/views.rst | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 4c9e907c7..d3da00043 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -65,3 +65,13 @@ Security - :php:meth:`Security::encrypt()` and :php:meth:`Security::decrypt()` were added. These methods expose a very simple API to access AES-256 symmetric encryption. They should be used in favour of the ``cipher()`` and ``rijndael()`` methods. + + +View +==== + +View +---- + +- :php:meth:`View::get()` now accepts a second argument to provide a default + value. diff --git a/en/views.rst b/en/views.rst index 3f8c12255..2278178f2 100644 --- a/en/views.rst +++ b/en/views.rst @@ -653,10 +653,23 @@ To call any view method use ``$this->method()`` Then in your layout the ``$activeMenuButton`` variable will be available and contain the value 'posts'. +.. php:method:: get(string $var, $default = null) + + Get the value of a viewVar with the name of ``$var``. + + As of 2.5 you can provide a default value in case the variable is not + already set. + + .. versionchanged:: 2.5 + The ``$default`` argument was added in 2.5. + .. php:method:: getVar(string $var) Gets the value of the viewVar with the name $var + .. deprecated:: 2.3 + Use :php:meth:`View::get()` instead. + .. php:method:: getVars() Gets a list of all the available view variables in the current -- GitLab From b566eb06fe9aeb21de67f4cf8536d3dfb111fbe3 Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 13 Sep 2013 02:25:54 +0200 Subject: [PATCH 011/245] removed log engine autocreate --- en/appendices/2-5-migration-guide.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index d3da00043..b3ef5317f 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -66,6 +66,14 @@ Security added. These methods expose a very simple API to access AES-256 symmetric encryption. They should be used in favour of the ``cipher()`` and ``rijndael()`` methods. +Logging +======= + +FileLog +------- + +- CakeLog does not autoconfigures itself anymore. Log files will not be auto-created anymore if no stream is listening. +So make sure you got at least one default engine set up if you want to listen to all types and levels. View ==== -- GitLab From 3378b1f86f5ca654d6a8441ea63333300bbcd327 Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 13 Sep 2013 02:39:57 +0200 Subject: [PATCH 012/245] wording --- en/appendices/2-5-migration-guide.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index b3ef5317f..450a82d4b 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -72,8 +72,9 @@ Logging FileLog ------- -- CakeLog does not autoconfigures itself anymore. Log files will not be auto-created anymore if no stream is listening. -So make sure you got at least one default engine set up if you want to listen to all types and levels. +- CakeLog does not auto-configure itself anymore. As a result log files will not be auto-created + anymore if no stream is listening. So make sure you got at least one default engine set up + if you want to listen to all types and levels. View ==== -- GitLab From a1b11d4cfa8b7f95133d2b816dd043b10db9ff67 Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 13 Sep 2013 02:54:03 +0200 Subject: [PATCH 013/245] additional note --- en/core-libraries/logging.rst | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/en/core-libraries/logging.rst b/en/core-libraries/logging.rst index 03c85bb8d..7eaa48d9e 100644 --- a/en/core-libraries/logging.rst +++ b/en/core-libraries/logging.rst @@ -223,11 +223,20 @@ CakeLog::write():: $this->log("Something did not work!", 'debug'); All configured log streams are written to sequentially each time -:php:meth:`CakeLog::write()` is called. You do not need to configure a -stream in order to use logging. If no streams are configured when -the log is written to, a ``default`` stream using the core -``FileLog`` class will be configured to output into -``app/tmp/logs/`` just as CakeLog did in previous versions. +:php:meth:`CakeLog::write()` is called. + +... versionchanged:: 2.5 + +CakeLog does not auto-configure itself anymore. As a result log files will not be +auto-created anymore if no stream is listening. +So make sure you got at least one ``default`` stream set up if you want to +listen to all types and levels. Usually, you can just set the core ``FileLog`` class +to output into ``app/tmp/logs/``:: + + CakeLog::config('file', array( + 'engine' => 'File', + 'path' => LOGS + )); .. _logging-scopes: -- GitLab From 1d85266e4bfd6169e54099b8a169bb86e8f055f1 Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 13 Sep 2013 23:20:42 +0200 Subject: [PATCH 014/245] correct example --- en/core-libraries/logging.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/en/core-libraries/logging.rst b/en/core-libraries/logging.rst index 7eaa48d9e..d1efb9ad6 100644 --- a/en/core-libraries/logging.rst +++ b/en/core-libraries/logging.rst @@ -229,13 +229,12 @@ All configured log streams are written to sequentially each time CakeLog does not auto-configure itself anymore. As a result log files will not be auto-created anymore if no stream is listening. -So make sure you got at least one ``default`` stream set up if you want to +Make sure you got at least one ``default`` stream set up if you want to listen to all types and levels. Usually, you can just set the core ``FileLog`` class to output into ``app/tmp/logs/``:: - CakeLog::config('file', array( - 'engine' => 'File', - 'path' => LOGS + CakeLog::config('default', array( + 'engine' => 'File' )); .. _logging-scopes: -- GitLab From 140ec4a52f6c62a7f648cc42beab5f6e60714563 Mon Sep 17 00:00:00 2001 From: euromark Date: Wed, 18 Sep 2013 17:06:07 +0200 Subject: [PATCH 015/245] wording --- en/appendices/2-5-migration-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 450a82d4b..50ad7a2ec 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -73,7 +73,7 @@ FileLog ------- - CakeLog does not auto-configure itself anymore. As a result log files will not be auto-created - anymore if no stream is listening. So make sure you got at least one default engine set up + anymore if no stream is listening. Please make sure you got at least one default engine set up if you want to listen to all types and levels. View -- GitLab From 222529cdc917280862a9d1fa53b4ad18cc03d9e0 Mon Sep 17 00:00:00 2001 From: euromark Date: Tue, 24 Sep 2013 02:19:41 +0200 Subject: [PATCH 016/245] inList(), multiple()() and case sensitivity --- en/appendices/2-5-migration-guide.rst | 9 +++++++++ en/models/data-validation.rst | 10 +++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 50ad7a2ec..89c7ea9ae 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -53,6 +53,15 @@ Router Utility ======= +Validation +---------- + +- The third param for :php:meth:`Validation::inList()` and :php:meth:`Validation::multiple()` has been + modified from `$strict` to `$caseInsensitive`. `$strict` has been dropped as it was working incorrectly + and could easily backfire. + You can now set this param to true for case insensitive comparison. The default is false and + will compare the value and list case sensitive as before. + Hash ---- diff --git a/en/models/data-validation.rst b/en/models/data-validation.rst index 9d0b98c38..036af2bca 100644 --- a/en/models/data-validation.rst +++ b/en/models/data-validation.rst @@ -899,7 +899,7 @@ with usage examples. .. versionadded:: 2.3 This method was added in 2.3 -.. php:staticmethod:: inList(string $check, array $list) +.. php:staticmethod:: inList(string $check, array $list, boolean $caseInsensitive = false) This rule will ensure that the value is in a given set. It needs an array of values. The field is valid if the field's value matches @@ -916,6 +916,8 @@ with usage examples. ) ); + Comparison is case sensitive by default. You can set ``$caseInsensitive`` to true + if you need case insensitive comparison. .. php:staticmethod:: ip(string $check, string $type = 'both') @@ -975,7 +977,7 @@ with usage examples. .. versionadded:: 2.2 - This rule checks for valid mimeType + This rule checks for valid mime types. Comparison is case sensitive. :: @@ -1021,7 +1023,7 @@ with usage examples. ) ); -.. php:staticmethod:: multiple(mixed $check, mixed $options = array()) +.. php:staticmethod:: multiple(mixed $check, mixed $options = array(), boolean $caseInsensitive = false) Use this for validating a multiple select input. It supports parameters "in", "max" and "min". @@ -1039,6 +1041,8 @@ with usage examples. ) ); + Comparison is case sensitive by default. You can set ``$caseInsensitive`` to true + if you need case insensitive comparison. .. php:staticmethod:: notEmpty(mixed $check) -- GitLab From 53f38cb380e0df024c564ae43d620501ce3ecac6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 4 Oct 2013 09:14:56 -0300 Subject: [PATCH 017/245] Update docs for new folder feature. --- en/appendices/2-5-migration-guide.rst | 6 ++++++ en/core-utility-libraries/file-folder.rst | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 50ad7a2ec..56849b1bd 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -59,6 +59,12 @@ Hash - :php:meth:`Hash::insert()` and :php:meth:`Hash::remove()` now support matcher expressions in their path selectors. +Folder +------ + +- :php:meth:`Folder::addPathElement()` now accepts an array for the ``$element`` + parameter. + Security -------- diff --git a/en/core-utility-libraries/file-folder.rst b/en/core-utility-libraries/file-folder.rst index a79f402d4..caa634ee5 100644 --- a/en/core-utility-libraries/file-folder.rst +++ b/en/core-utility-libraries/file-folder.rst @@ -68,10 +68,17 @@ Folder API Returns $path with $element added, with correct slash in-between:: - Date: Sat, 5 Oct 2013 18:13:16 -0300 Subject: [PATCH 018/245] Update migration guide. --- en/appendices/2-5-migration-guide.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 56849b1bd..7b0a51d53 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -11,6 +11,7 @@ Cache ext/memcached instead of ext/memcache. It supports improved performance and shared persistent connections. - The ``Memcache`` adapter is now deprecated in favor of ``Memcached``. +- :php:meth:`Cache::remember()` was added. Console ======= -- GitLab From 9b086cc0a27e1278b093ea51f396e0c162a0a75f Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 5 Oct 2013 18:22:20 -0300 Subject: [PATCH 019/245] Update caching docs. --- en/core-libraries/caching.rst | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/en/core-libraries/caching.rst b/en/core-libraries/caching.rst index c0b28ce70..aa56edf1c 100644 --- a/en/core-libraries/caching.rst +++ b/en/core-libraries/caching.rst @@ -213,6 +213,21 @@ You could improve the above code by moving the cache reading logic into a behavior, that read from the cache, or ran the associated model method. That is an exercise you can do though. +As of 2.5 you can accomplish the above much more simply using +:php:meth:`Cache::remember()`. Using the new method the above would look like:: + + class Post extends AppModel { + + public function newest() { + $model = $this; + return Cache::remember('newest_posts', function () use ($model){ + return $model->find('all', array( + 'order' => 'Post.updated DESC', + 'limit' => 10 + )); + }, 'longterm'); + } + } Using Cache to store counters ============================= @@ -419,6 +434,27 @@ Cache API Retrieve group names to config mapping. +.. php:staticmethod:: remember($key, $callable, $config = 'default') + + Provides an easy way to do read-through caching. If the cache key exists + it will be returned. If the key does not exist, the callable will be invoked + and the results stored in the cache at the provided key. + + For example, you often want to cache query results. You could use + ``remember()`` to make this simple. Assuming you were using PHP5.3 or more:: + + class Articles extends AppModel { + function all() { + $model = $this; + return Cache::remember('all_articles', function () use ($model){ + return $model->find('all'); + }); + } + } + + .. versionadded:: 2.5 + remember() was added in 2.5. + .. meta:: :title lang=en: Caching :keywords lang=en: uniform api,xcache,cache engine,cache system,atomic operations,php class,disk storage,static methods,php extension,consistent manner,similar features,apc,memcache,queries,cakephp,elements,servers,memory -- GitLab From dab9365bdd5009a8f288234534c4fd5740d092f4 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 6 Oct 2013 19:41:38 -0300 Subject: [PATCH 020/245] Fix coding standards. --- en/core-libraries/caching.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/core-libraries/caching.rst b/en/core-libraries/caching.rst index aa56edf1c..9597307ed 100644 --- a/en/core-libraries/caching.rst +++ b/en/core-libraries/caching.rst @@ -446,7 +446,7 @@ Cache API class Articles extends AppModel { function all() { $model = $this; - return Cache::remember('all_articles', function () use ($model){ + return Cache::remember('all_articles', function() use ($model){ return $model->find('all'); }); } -- GitLab From edfd7e15ddeccf356d39e869b470a0ff91b332b1 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 6 Oct 2013 20:13:12 -0300 Subject: [PATCH 021/245] Fix other coding standards error. --- en/core-libraries/caching.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/core-libraries/caching.rst b/en/core-libraries/caching.rst index 9597307ed..3feada89a 100644 --- a/en/core-libraries/caching.rst +++ b/en/core-libraries/caching.rst @@ -220,7 +220,7 @@ As of 2.5 you can accomplish the above much more simply using public function newest() { $model = $this; - return Cache::remember('newest_posts', function () use ($model){ + return Cache::remember('newest_posts', function() use ($model){ return $model->find('all', array( 'order' => 'Post.updated DESC', 'limit' => 10 -- GitLab From 538eac9583cf986e847cde933d07902150984890 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 11 Oct 2013 16:16:31 -0400 Subject: [PATCH 022/245] Add note about completion shell. --- en/appendices/2-5-migration-guide.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 743f314f3..a8f556bec 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -23,6 +23,13 @@ SchemaShell ``yes`` option allows you to skip the various interactive questions forcing a yes reply. +CompletionShell +--------------- + +- The CompletionShell was added, this allows integration with autocompletion + libraries for shell environments like bash, or zsh. No shell scripts are + included in CakePHP, but the underlying tools are now available. + Controller ========== -- GitLab From 0d0201ffc3ebab3702dbf81273a1ca95027330a6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 14 Oct 2013 23:11:10 -0400 Subject: [PATCH 023/245] Fix wording. --- en/appendices/2-5-migration-guide.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index a8f556bec..3786bbf86 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -26,9 +26,9 @@ SchemaShell CompletionShell --------------- -- The CompletionShell was added, this allows integration with autocompletion - libraries for shell environments like bash, or zsh. No shell scripts are - included in CakePHP, but the underlying tools are now available. +- The CompletionShell was added. It aims to assist in the creation of + autocompletion libraries for shell environments like bash, or zsh. No shell + scripts are included in CakePHP, but the underlying tools are now available. Controller ========== -- GitLab From bb0aa952053f3f482086e392b8e1ebca30a9f0c1 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 17 Oct 2013 12:06:26 -0400 Subject: [PATCH 024/245] Update docs for new formhelper feature. --- en/appendices/2-5-migration-guide.rst | 6 ++++++ en/core-libraries/helpers/form.rst | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 3786bbf86..58a54baf3 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -107,3 +107,9 @@ View - :php:meth:`View::get()` now accepts a second argument to provide a default value. + +FormHelper +---------- + +- FormHelper will now generate file inputs for ``binary`` field types now. + diff --git a/en/core-libraries/helpers/form.rst b/en/core-libraries/helpers/form.rst index a5bb203ea..57264bfa1 100644 --- a/en/core-libraries/helpers/form.rst +++ b/en/core-libraries/helpers/form.rst @@ -312,6 +312,8 @@ field. Internally ``input()`` delegates to other methods in FormHelper. day, month, year, hour, minute, and meridian selects time hour, minute, and meridian selects + binary + file The ``$options`` parameter allows you to customize how ``input()`` works, and finely control what is generated. @@ -322,6 +324,9 @@ field. Internally ``input()`` delegates to other methods in FormHelper. been loaded during this request. Or be directly associated to the model supplied to :php:meth:`~FormHelper::create()`. + .. versionadded:: 2.5 + The binary type now maps to a file input. + .. versionadded:: 2.3 .. _html5-required: -- GitLab From e7998ba6eaa2052165336073b832ca4f985a863b Mon Sep 17 00:00:00 2001 From: euromark Date: Thu, 24 Oct 2013 18:37:05 +0200 Subject: [PATCH 025/245] Migration update for pagination helper and lock --- en/appendices/2-5-migration-guide.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 58a54baf3..d17546c5e 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -113,3 +113,8 @@ FormHelper - FormHelper will now generate file inputs for ``binary`` field types now. +PaginationHelper +---------------- + +- :php:meth:`PaginatorHelper::sort()` now has a ``lock`` option to create pagination sort links with + only the default direction. -- GitLab From 3105ee1bd5e44cf89a43be002d3596ffc80ec240 Mon Sep 17 00:00:00 2001 From: euromark Date: Thu, 24 Oct 2013 19:00:15 +0200 Subject: [PATCH 026/245] wording --- en/appendices/2-5-migration-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index d17546c5e..aa1220c7c 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -117,4 +117,4 @@ PaginationHelper ---------------- - :php:meth:`PaginatorHelper::sort()` now has a ``lock`` option to create pagination sort links with - only the default direction. + the default direction only. -- GitLab From b334107a7699723b8935bee57e1355a58f72e75b Mon Sep 17 00:00:00 2001 From: Bryan Crowe Date: Thu, 24 Oct 2013 23:20:32 -0400 Subject: [PATCH 027/245] Add lock option, add missing direction option --- en/core-libraries/helpers/paginator.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/en/core-libraries/helpers/paginator.rst b/en/core-libraries/helpers/paginator.rst index 0de26b641..f4a4d6cac 100644 --- a/en/core-libraries/helpers/paginator.rst +++ b/en/core-libraries/helpers/paginator.rst @@ -31,6 +31,10 @@ Accepted keys for ``$options``: * ``escape`` Whether you want the contents html entity encoded, defaults to true. * ``model`` The model to use, defaults to :php:meth:`PaginatorHelper::defaultModel()`. +* ``direction`` The default direction to use when this link isn't active. +* ``lock`` Lock direction. Will only use the default direction then, defaults to false. + + .. versionadded:: 2.5 Assuming you are paginating some posts, and are on page one:: @@ -73,6 +77,10 @@ Output: User Id +The lock option can be used to lock sorting into the specified direction:: + + echo $this->Paginator->sort('user_id', null, array('direction' => 'asc', 'lock' => true)); + .. php:method:: sortDir(string $model = null, mixed $options = array()) Gets the current direction the recordset is sorted. -- GitLab From 8260801c6e41b82380777e378c1a83d1c7a72a46 Mon Sep 17 00:00:00 2001 From: Bryan Crowe Date: Fri, 25 Oct 2013 00:06:58 -0400 Subject: [PATCH 028/245] Add note about lock to version add --- en/core-libraries/helpers/paginator.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/en/core-libraries/helpers/paginator.rst b/en/core-libraries/helpers/paginator.rst index f4a4d6cac..eda15fee6 100644 --- a/en/core-libraries/helpers/paginator.rst +++ b/en/core-libraries/helpers/paginator.rst @@ -35,6 +35,8 @@ Accepted keys for ``$options``: * ``lock`` Lock direction. Will only use the default direction then, defaults to false. .. versionadded:: 2.5 + You can now set the lock option to true in order to lock the sorting direction into the + specified direction. Assuming you are paginating some posts, and are on page one:: -- GitLab From a8528875ee0f321ada2e41136ea634f8c87a3f5a Mon Sep 17 00:00:00 2001 From: Phally Date: Sat, 26 Oct 2013 15:33:17 +0200 Subject: [PATCH 029/245] Adds docs for File::replaceText(). Refs cakephp/cakephp#1665. --- en/core-utility-libraries/file-folder.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/en/core-utility-libraries/file-folder.rst b/en/core-utility-libraries/file-folder.rst index 9d0af27a0..583151c81 100644 --- a/en/core-utility-libraries/file-folder.rst +++ b/en/core-utility-libraries/file-folder.rst @@ -609,6 +609,14 @@ File API Get the file's mimetype, returns false on failure. +.. versionadded:: 2.5 ``File::replaceText()`` + +.. php:method:: replaceText( $search, $replace ) + + :rtype: boolean + + Replaces text in a file. Returns false on failure and true on success. + .. todo:: -- GitLab From d7e81a042d33510fabdb0d45cd651e44399ea8bb Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Fri, 1 Nov 2013 07:37:27 +0700 Subject: [PATCH 030/245] Add note for selecting `database` with RedisEngine See: cakephp/cakephp#2254 --- en/appendices/2-5-migration-guide.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index aa1220c7c..3dd38838d 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -12,6 +12,8 @@ Cache shared persistent connections. - The ``Memcache`` adapter is now deprecated in favor of ``Memcached``. - :php:meth:`Cache::remember()` was added. +- :php:meth:`Cache::config()` now accepts ``database`` key when used with + :php:class:`RedisEngine` in order to use non-default database number. Console ======= -- GitLab From e7c68afb27b3105eb5afcad6c9bbd882a41d86de Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Fri, 1 Nov 2013 07:39:44 +0700 Subject: [PATCH 031/245] Fix sphinx warning and remove trailing space --- en/getting-started/cakephp-conventions.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/en/getting-started/cakephp-conventions.rst b/en/getting-started/cakephp-conventions.rst index 921845745..a14818db2 100644 --- a/en/getting-started/cakephp-conventions.rst +++ b/en/getting-started/cakephp-conventions.rst @@ -38,22 +38,22 @@ will not be accessible directly from the web but is available for internal use. For example:: class NewsController extends AppController { - + public function latest() { $this->_findNewArticles(); } - + protected function _findNewArticles() { // Logic to find latest news articles } } - + While the page http://www.example.com/news/latest/ would be accessible to the user as usual, someone trying to get to the page http://www.example.com/news/\_findNewArticles/ would get an error, because the method is preceded with an underscore. You can also use -PHP's visibility keywords to indicate whether or not a method can be +PHP's visibility keywords to indicate whether or not a method can be accessed from a URL. Non-public methods cannot be accessed. URL Considerations for Controller Names @@ -84,7 +84,7 @@ For more information on CakePHP URLs and parameter handling, see .. _file-and-classname-conventions: File and Class Name Conventions -============================== +=============================== In general, filenames match the class names, which are CamelCased. So if you have a class **MyNiftyClass**, then in CakePHP, @@ -94,7 +94,7 @@ classes you would typically use in a CakePHP application: - The Controller class **KissesAndHugsController** would be found - in a file named **KissesAndHugsController.php** + in a file named **KissesAndHugsController.php** - The Component class **MyHandyComponent** would be found in a file named **MyHandyComponent.php** - The Model class **OptionValue** would be found in a file named @@ -155,7 +155,7 @@ as a normal model. E.g.:: id INT(10) NOT NULL AUTO_INCREMENT, post_id INT(10) NOT NULL, tag_id INT(10) NOT NULL, - PRIMARY KEY(id)); + PRIMARY KEY(id)); Rather than using an auto-increment key as the primary key, you may also use char(36). CakePHP will then use a unique 36 character UUID -- GitLab From 09b6dd398b9e02c538ea38354472e5b7ac92e8a6 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 11 Nov 2013 12:16:25 -0500 Subject: [PATCH 032/245] Update docs for event manager changes. --- en/appendices/2-5-migration-guide.rst | 14 ++++++++++++++ en/core-libraries/events.rst | 14 +++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 3dd38838d..750661b9a 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -42,6 +42,20 @@ CookieComponent :php:class:`Security`. You can enable this by calling :php:meth:`CookieComponent::type()` with 'aes'. +Event +===== + +EventManager +------------ + +Events bound to the global manager are now fired in priority order with events +bound to a local manager. This can cause listeners to be fired in a different +order than they were in previous releases. Instead of all global listeners being triggered, +and then instance listeners being fired afterwards, the two sets of listeners +are combined into one list of listeners based on their priorities and then fired +as one set. Global listeners of a given priority are still fired before instance +listeners. + Network ======= diff --git a/en/core-libraries/events.rst b/en/core-libraries/events.rst index 989311304..02596d634 100644 --- a/en/core-libraries/events.rst +++ b/en/core-libraries/events.rst @@ -92,11 +92,9 @@ In addition to instance level event managers, CakePHP provides a global event manager that allows you to listen to any event fired in an application. This is useful when attaching listeners to a specific instance might be cumbersome or difficult. The global manager is a singleton instance of -:php:class:`CakeEventManager` that receives every event **before** the instance -managers do. In addition to receiving events first, the global manager also -maintains a separate priority stack for listeners. Once an event has been -dispatched to the global manager, it will be dispatched to the instance level -manager. You can access the global manager using a static method:: +:php:class:`CakeEventManager`. When an event is +dispatched, it will be dispatched to the both the global and instance level +listeners in priority order. You can access the global manager using a static method:: // In any configuration file or piece of code that executes before the event App::uses('CakeEventManager', 'Event'); @@ -112,6 +110,12 @@ order to prevent some bugs. Remember that with the flexibility of using the global manager, some additional complexity is incurred. +.. versionchanged:: 2.5 + + Prior to 2.5, listeners on the global manager were kept in a separate list + and fired **before** instance listeners are. + + Dispatching events ================== -- GitLab From 62f224beac9bd22bf6b655060e3f619c3cac8f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20J=C3=B8rgensen?= Date: Fri, 22 Nov 2013 23:37:31 +0100 Subject: [PATCH 033/245] Update plugins.rst --- en/plugins.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/en/plugins.rst b/en/plugins.rst index fc5958125..2b25c6832 100644 --- a/en/plugins.rst +++ b/en/plugins.rst @@ -200,6 +200,16 @@ Please refer to the chapter :doc:`/console-and-shells/code-generation-with-bake` if you have any problems with using the command line. +.. Warning:: + + Plugins do not work as namespacing to seperate code. + Due to PHP lacking namespaces in older versions + you cannot have the same class, + or same filename, in your plugins. + Even if it is two different plugins. + So use unique classes and filenames, possible prefixing + the class and filename with the plugin name. + Plugin Controllers ================== -- GitLab From f3a20cd3d1230271154c922e3a11e2427a1e9c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20J=C3=B8rgensen?= Date: Sat, 23 Nov 2013 12:59:44 +0100 Subject: [PATCH 034/245] Fix bad edit of plugins.rst Warning changed to warning. My bad :) --- en/plugins.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/plugins.rst b/en/plugins.rst index 2b25c6832..c1026817f 100644 --- a/en/plugins.rst +++ b/en/plugins.rst @@ -200,7 +200,7 @@ Please refer to the chapter :doc:`/console-and-shells/code-generation-with-bake` if you have any problems with using the command line. -.. Warning:: +.. warning:: Plugins do not work as namespacing to seperate code. Due to PHP lacking namespaces in older versions -- GitLab From b46150beaa733a073763bc3b6dc7a5725cf8594d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20J=C3=B8rgensen?= Date: Sat, 23 Nov 2013 15:00:36 +0100 Subject: [PATCH 035/245] fix spelling error in plugins.rst --- en/plugins.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/plugins.rst b/en/plugins.rst index c1026817f..49310853d 100644 --- a/en/plugins.rst +++ b/en/plugins.rst @@ -202,7 +202,7 @@ have any problems with using the command line. .. warning:: - Plugins do not work as namespacing to seperate code. + Plugins do not work as namespacing to separate code. Due to PHP lacking namespaces in older versions you cannot have the same class, or same filename, in your plugins. -- GitLab From c897fe7f3aa465011fe50b7f3681d7f3199580de Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 27 Nov 2013 20:18:56 -0500 Subject: [PATCH 036/245] Update migration guide for unsigned int. --- en/appendices/2-5-migration-guide.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 750661b9a..a2bd3504d 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -56,6 +56,13 @@ are combined into one list of listeners based on their priorities and then fired as one set. Global listeners of a given priority are still fired before instance listeners. +Model +===== + +- Unsigned integers are now supported by datasources that provide them (MySQL). + You can set the ``unsigned`` option to true in your schema/fixture files to + start using this feature. + Network ======= -- GitLab From d2feced3bfd14c3b5bc2ff0bc6e397d80c31766e Mon Sep 17 00:00:00 2001 From: Brian Porter Date: Thu, 5 Dec 2013 22:24:47 -0600 Subject: [PATCH 037/245] Added version change warning about baked tests in 2.5. See also: https://github.com/cakephp/cakephp/issues/2437 --- en/console-and-shells/code-generation-with-bake.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/en/console-and-shells/code-generation-with-bake.rst b/en/console-and-shells/code-generation-with-bake.rst index 989f5ed4d..d3afc06c8 100644 --- a/en/console-and-shells/code-generation-with-bake.rst +++ b/en/console-and-shells/code-generation-with-bake.rst @@ -60,6 +60,10 @@ command line:: $ cake bake all +.. versionchanged:: 2.5 + Test files produced by ``bake test`` include calls to `PHPunit's markTestIncomplete() `_ to draw attention to empty test methods. Before 2.5, empty tests pass silently. + + Modify default HTML produced by "baked" templates ================================================= -- GitLab From 1efc5ab0b5416d2e907625456e0d50f51e2f86fa Mon Sep 17 00:00:00 2001 From: ezrabynx Date: Fri, 20 Dec 2013 14:34:44 -0500 Subject: [PATCH 038/245] Marked scaffold as deprecated. --- en/controllers/scaffolding.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/en/controllers/scaffolding.rst b/en/controllers/scaffolding.rst index e27eb653f..a4234fc3a 100644 --- a/en/controllers/scaffolding.rst +++ b/en/controllers/scaffolding.rst @@ -1,6 +1,9 @@ Scaffolding ########### +.. deprecated:: 2.5 + Dynamic scaffolding will be removed and replaced in 3.0 + Application scaffolding is a technique that allows a developer to define and create a basic application that can create, retrieve, update and delete objects. Scaffolding in CakePHP also allows -- GitLab From 202b60048a03f23c365de2b5f4b883e168d4386f Mon Sep 17 00:00:00 2001 From: ezrabynx Date: Fri, 20 Dec 2013 14:44:42 -0500 Subject: [PATCH 039/245] 2.5 Migration Guide; Scaffold Added scaffold to the 2.5 migration guide. --- en/appendices/2-5-migration-guide.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index a2bd3504d..6cb12914b 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -42,6 +42,10 @@ CookieComponent :php:class:`Security`. You can enable this by calling :php:meth:`CookieComponent::type()` with 'aes'. +Scaffold +-------- +- Dyanmic Scaffold is now deprecated and will be removed in 3.0. + Event ===== @@ -141,3 +145,8 @@ PaginationHelper - :php:meth:`PaginatorHelper::sort()` now has a ``lock`` option to create pagination sort links with the default direction only. + +ScaffoldView +------------ + +- Dyanmic Scaffold is now deprecated and will be removed in 3.0. \ No newline at end of file -- GitLab From e9374ee4c9e21210fd4077ab35a4ddf7ae67ea81 Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 3 Jan 2014 16:55:00 +0100 Subject: [PATCH 040/245] error handling --- en/appendices/2-5-migration-guide.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 6cb12914b..dd20e736a 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -126,6 +126,15 @@ FileLog anymore if no stream is listening. Please make sure you got at least one default engine set up if you want to listen to all types and levels. +Error +===== + +ExceptionRenderer +----------------- + +The ExceptionRenderer now populates the error templates with "code", "message" and "url" variables. +"name" has been deprecated but is still available. This unifies the variables across all error templates. + View ==== -- GitLab From 9989cf9ac915bf1a6a101c2c6e73e55f073079a4 Mon Sep 17 00:00:00 2001 From: euromark Date: Tue, 7 Jan 2014 22:07:33 +0100 Subject: [PATCH 041/245] deprecated notice --- en/appendices/2-5-migration-guide.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index dd20e736a..c4968da96 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -35,6 +35,10 @@ CompletionShell Controller ========== +AuthComponent +------------- +- ``loggedIn()`` is now deprecated and will be removed in 3.0. + CookieComponent --------------- -- GitLab From 8d57d447c74d63a5751b0ef66f9f7ee01f97e1dc Mon Sep 17 00:00:00 2001 From: euromark Date: Thu, 9 Jan 2014 13:36:27 +0100 Subject: [PATCH 042/245] Use fetch(title) instead --- en/appendices/2-5-migration-guide.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index c4968da96..7d352f092 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -145,6 +145,7 @@ View View ---- +- ``$title_for_layout`` is deprecated. Use ``$this->fetch('title');`` instead. - :php:meth:`View::get()` now accepts a second argument to provide a default value. -- GitLab From 77e4195f47eda27f820ebe0394b9670303d384fb Mon Sep 17 00:00:00 2001 From: euromark Date: Thu, 9 Jan 2014 15:18:30 +0100 Subject: [PATCH 043/245] update docs --- en/core-libraries/helpers/rss.rst | 2 +- en/views.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/en/core-libraries/helpers/rss.rst b/en/core-libraries/helpers/rss.rst index 818985545..39fef73b2 100644 --- a/en/core-libraries/helpers/rss.rst +++ b/en/core-libraries/helpers/rss.rst @@ -90,7 +90,7 @@ An Rss layout is very simple, put the following contents in $channelData = array(); } if (!isset($channelData['title'])) { - $channelData['title'] = $title_for_layout; + $channelData['title'] = $this->fetch('title'); } $channel = $this->Rss->channel(array(), $channelData, $content_for_layout); echo $this->Rss->document($documentData, $channel); diff --git a/en/views.rst b/en/views.rst index abaf009a8..cad3cae55 100644 --- a/en/views.rst +++ b/en/views.rst @@ -312,7 +312,7 @@ might look like: - <?php echo $title_for_layout?> + <?php echo $this->fetch('title'); ?> method()`` .. php:method:: get(string $var, $default = null) Get the value of a viewVar with the name of ``$var``. - + As of 2.5 you can provide a default value in case the variable is not already set. -- GitLab From d956d422188c292c4289db9e6be601fda185fc4b Mon Sep 17 00:00:00 2001 From: euromark Date: Thu, 9 Jan 2014 15:35:39 +0100 Subject: [PATCH 044/245] also correct content_for_layout --- en/core-libraries/helpers/js.rst | 2 +- en/core-libraries/helpers/rss.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/en/core-libraries/helpers/js.rst b/en/core-libraries/helpers/js.rst index b7dd2d578..2b1ffcaa6 100644 --- a/en/core-libraries/helpers/js.rst +++ b/en/core-libraries/helpers/js.rst @@ -835,7 +835,7 @@ indicator effects yourself:
- + fetch('content'); ?>
Html->image( diff --git a/en/core-libraries/helpers/rss.rst b/en/core-libraries/helpers/rss.rst index 39fef73b2..cfefb5477 100644 --- a/en/core-libraries/helpers/rss.rst +++ b/en/core-libraries/helpers/rss.rst @@ -92,7 +92,7 @@ An Rss layout is very simple, put the following contents in if (!isset($channelData['title'])) { $channelData['title'] = $this->fetch('title'); } - $channel = $this->Rss->channel(array(), $channelData, $content_for_layout); + $channel = $this->Rss->channel(array(), $channelData, $this->fetch('content')); echo $this->Rss->document($documentData, $channel); It doesn't look like much but thanks to the power in the ``RssHelper`` -- GitLab From 81382b4356381e9aee79347e88b7c99ff2e5f83f Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 17 Jan 2014 22:28:37 -0500 Subject: [PATCH 045/245] Add docs for cakephp/cakephp#2501 --- en/development/dispatch-filters.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/en/development/dispatch-filters.rst b/en/development/dispatch-filters.rst index 02cf756e5..bb0ac0f69 100644 --- a/en/development/dispatch-filters.rst +++ b/en/development/dispatch-filters.rst @@ -104,6 +104,21 @@ Feel free to remove the default attached filters if you choose to use a more advanced/faster way of serving theme and plugin assets or if you do not wish to use built-in full page caching, or just implement your own. +If you need to pass constructor parameters or settings to you dispatch filter +classes you can do that by providing an array of settings:: + + Configure::write('Dispatcher.filters', array( + 'MyAssetFilter' => array('service' => 'google.com') + )); + +When the filter key is a valid classname, the value can be an array of +parameters that are passed to the dispatch filter. By default the base class +will assign these settings to the ``$settings`` property after merging them with +the defaults in the class. + +.. versionchanged:: 2.5 + You can now provide constructor settings to dispatch filters in 2.5. + Filter Classes ============== -- GitLab From cc3aa4525e0694ab926ced6c8d45c02407dfd501 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 28 Jan 2014 11:05:38 +0530 Subject: [PATCH 046/245] Fixed typos. --- en/appendices/2-5-migration-guide.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/en/appendices/2-5-migration-guide.rst b/en/appendices/2-5-migration-guide.rst index 7d352f092..dad50c728 100644 --- a/en/appendices/2-5-migration-guide.rst +++ b/en/appendices/2-5-migration-guide.rst @@ -48,7 +48,7 @@ CookieComponent Scaffold -------- -- Dyanmic Scaffold is now deprecated and will be removed in 3.0. +- Dynamic Scaffold is now deprecated and will be removed in 3.0. Event ===== @@ -163,4 +163,4 @@ PaginationHelper ScaffoldView ------------ -- Dyanmic Scaffold is now deprecated and will be removed in 3.0. \ No newline at end of file +- Dynamic Scaffold is now deprecated and will be removed in 3.0. -- GitLab From 78f4f5c565d5a99d8f40010a912b7b22ecbeb2ce Mon Sep 17 00:00:00 2001 From: Aleksa-Savic Date: Fri, 31 Jan 2014 18:41:29 +0100 Subject: [PATCH 047/245] Added Serbian skeleton --- sr/_static/img/basic_mvc.png | Bin 0 -> 30422 bytes sr/_static/img/code-coverage.png | Bin 0 -> 82337 bytes sr/_static/img/typical-cake-request.png | Bin 0 -> 19786 bytes sr/appendices.rst | 71 + sr/appendices/2-0-migration-guide.rst | 1292 ++++++++++++ sr/appendices/2-1-migration-guide.rst | 363 ++++ sr/appendices/2-2-migration-guide.rst | 327 +++ sr/appendices/2-3-migration-guide.rst | 326 +++ sr/appendices/2-4-migration-guide.rst | 294 +++ sr/appendices/cakephp-development-process.rst | 56 + sr/appendices/glossary.rst | 70 + .../migrating-from-cakephp-1-2-to-1-3.rst | 778 ++++++++ sr/appendices/new-features-in-cakephp-1-3.rst | 544 +++++ sr/appendices/new-features-in-cakephp-2-0.rst | 296 +++ sr/appendices/new-features-in-cakephp-2-1.rst | 213 ++ sr/appendices/phpunit-migration-hints.rst | 200 ++ sr/cakephp-overview.rst | 24 + .../understanding-model-view-controller.rst | 108 + .../what-is-cakephp-why-use-it.rst | 62 + sr/cakephp-overview/where-to-get-help.rst | 102 + sr/console-and-shells.rst | 1008 ++++++++++ sr/console-and-shells/acl-shell.rst | 81 + .../code-generation-with-bake.rst | 233 +++ sr/console-and-shells/cron-jobs.rst | 23 + sr/console-and-shells/i18n-shell.rst | 101 + .../schema-management-and-migrations.rst | 193 ++ sr/console-and-shells/testsuite-shell.rst | 17 + sr/console-and-shells/upgrade-shell.rst | 81 + sr/contributing.rst | 19 + .../cakephp-coding-conventions.rst | 430 ++++ sr/contributing/code.rst | 141 ++ sr/contributing/documentation.rst | 376 ++++ sr/contributing/tickets.rst | 54 + sr/controllers.rst | 821 ++++++++ sr/controllers/components.rst | 303 +++ sr/controllers/pages-controller.rst | 28 + sr/controllers/request-response.rst | 832 ++++++++ sr/controllers/scaffolding.rst | 139 ++ sr/core-libraries.rst | 75 + sr/core-libraries/behaviors/acl.rst | 120 ++ sr/core-libraries/behaviors/containable.rst | 442 +++++ sr/core-libraries/behaviors/translate.rst | 357 ++++ sr/core-libraries/behaviors/tree.rst | 819 ++++++++ sr/core-libraries/caching.rst | 419 ++++ sr/core-libraries/collections.rst | 170 ++ .../components/access-control-lists.rst | 869 ++++++++ .../components/authentication.rst | 979 +++++++++ sr/core-libraries/components/cookie.rst | 181 ++ sr/core-libraries/components/email.rst | 52 + sr/core-libraries/components/pagination.rst | 359 ++++ .../components/request-handling.rst | 315 +++ .../components/security-component.rst | 332 ++++ sr/core-libraries/components/sessions.rst | 172 ++ sr/core-libraries/events.rst | 459 +++++ .../global-constants-and-functions.rst | 328 +++ sr/core-libraries/helpers/cache.rst | 150 ++ sr/core-libraries/helpers/form.rst | 1762 +++++++++++++++++ sr/core-libraries/helpers/html.rst | 1108 +++++++++++ sr/core-libraries/helpers/js.rst | 881 +++++++++ sr/core-libraries/helpers/number.rst | 31 + sr/core-libraries/helpers/paginator.rst | 592 ++++++ sr/core-libraries/helpers/rss.rst | 278 +++ sr/core-libraries/helpers/session.rst | 125 ++ sr/core-libraries/helpers/text.rst | 95 + sr/core-libraries/helpers/time.rst | 55 + .../internationalization-and-localization.rst | 244 +++ sr/core-libraries/logging.rst | 405 ++++ sr/core-libraries/toc-behaviors.rst | 17 + sr/core-libraries/toc-components.rst | 17 + sr/core-libraries/toc-general-purpose.rst | 10 + sr/core-libraries/toc-helpers.rst | 24 + sr/core-libraries/toc-utilities.rst | 22 + sr/core-utility-libraries/app.rst | 404 ++++ sr/core-utility-libraries/email.rst | 423 ++++ sr/core-utility-libraries/file-folder.rst | 564 ++++++ sr/core-utility-libraries/hash.rst | 868 ++++++++ sr/core-utility-libraries/httpsocket.rst | 384 ++++ sr/core-utility-libraries/inflector.rst | 76 + sr/core-utility-libraries/number.rst | 364 ++++ sr/core-utility-libraries/router.rst | 16 + sr/core-utility-libraries/sanitize.rst | 30 + sr/core-utility-libraries/security.rst | 134 ++ sr/core-utility-libraries/set.rst | 1596 +++++++++++++++ sr/core-utility-libraries/string.rst | 297 +++ sr/core-utility-libraries/time.rst | 436 ++++ sr/core-utility-libraries/xml.rst | 336 ++++ sr/deployment.rst | 80 + sr/development.rst | 26 + sr/development/configuration.rst | 833 ++++++++ sr/development/debugging.rst | 205 ++ sr/development/dispatch-filters.rst | 229 +++ sr/development/errors.rst | 131 ++ sr/development/exceptions.rst | 448 +++++ sr/development/rest.rst | 214 ++ sr/development/routing.rst | 1110 +++++++++++ sr/development/sessions.rst | 327 +++ sr/development/testing.rst | 1327 +++++++++++++ sr/development/vendor-packages.rst | 17 + sr/getting-started.rst | 35 + .../a-typical-cakephp-request.rst | 56 + sr/getting-started/cakephp-conventions.rst | 202 ++ .../cakephp-folder-structure.rst | 89 + sr/getting-started/cakephp-structure.rst | 109 + sr/installation.rst | 216 ++ sr/installation/advanced-installation.rst | 183 ++ sr/installation/url-rewriting.rst | 270 +++ sr/models.rst | 136 ++ .../additional-methods-and-properties.rst | 114 ++ .../associations-linking-models-together.rst | 1130 +++++++++++ sr/models/behaviors.rst | 344 ++++ sr/models/callback-methods.rst | 231 +++ sr/models/data-validation.rst | 1267 ++++++++++++ .../validating-data-from-the-controller.rst | 81 + sr/models/datasources.rst | 319 +++ sr/models/deleting-data.rst | 73 + sr/models/model-attributes.rst | 254 +++ sr/models/retrieving-your-data.rst | 1100 ++++++++++ sr/models/saving-your-data.rst | 972 +++++++++ sr/models/transactions.rst | 63 + sr/models/virtual-fields.rst | 216 ++ sr/pdf-contents.rst | 26 + sr/plugins.rst | 445 +++++ sr/tutorials-and-examples.rst | 25 + .../blog-auth-example/auth.rst | 411 ++++ sr/tutorials-and-examples/blog/blog.rst | 204 ++ sr/tutorials-and-examples/blog/part-two.rst | 721 +++++++ .../part-two.rst | 199 ++ .../simple-acl-controlled-application.rst | 405 ++++ sr/views.rst | 807 ++++++++ sr/views/helpers.rst | 304 +++ sr/views/json-and-xml-views.rst | 131 ++ sr/views/media-view.rst | 97 + sr/views/themes.rst | 87 + 133 files changed, 44467 insertions(+) create mode 100644 sr/_static/img/basic_mvc.png create mode 100644 sr/_static/img/code-coverage.png create mode 100644 sr/_static/img/typical-cake-request.png create mode 100644 sr/appendices.rst create mode 100644 sr/appendices/2-0-migration-guide.rst create mode 100644 sr/appendices/2-1-migration-guide.rst create mode 100644 sr/appendices/2-2-migration-guide.rst create mode 100644 sr/appendices/2-3-migration-guide.rst create mode 100644 sr/appendices/2-4-migration-guide.rst create mode 100644 sr/appendices/cakephp-development-process.rst create mode 100644 sr/appendices/glossary.rst create mode 100644 sr/appendices/migrating-from-cakephp-1-2-to-1-3.rst create mode 100644 sr/appendices/new-features-in-cakephp-1-3.rst create mode 100644 sr/appendices/new-features-in-cakephp-2-0.rst create mode 100644 sr/appendices/new-features-in-cakephp-2-1.rst create mode 100644 sr/appendices/phpunit-migration-hints.rst create mode 100644 sr/cakephp-overview.rst create mode 100644 sr/cakephp-overview/understanding-model-view-controller.rst create mode 100644 sr/cakephp-overview/what-is-cakephp-why-use-it.rst create mode 100644 sr/cakephp-overview/where-to-get-help.rst create mode 100644 sr/console-and-shells.rst create mode 100644 sr/console-and-shells/acl-shell.rst create mode 100644 sr/console-and-shells/code-generation-with-bake.rst create mode 100644 sr/console-and-shells/cron-jobs.rst create mode 100644 sr/console-and-shells/i18n-shell.rst create mode 100644 sr/console-and-shells/schema-management-and-migrations.rst create mode 100644 sr/console-and-shells/testsuite-shell.rst create mode 100644 sr/console-and-shells/upgrade-shell.rst create mode 100644 sr/contributing.rst create mode 100644 sr/contributing/cakephp-coding-conventions.rst create mode 100644 sr/contributing/code.rst create mode 100644 sr/contributing/documentation.rst create mode 100644 sr/contributing/tickets.rst create mode 100644 sr/controllers.rst create mode 100644 sr/controllers/components.rst create mode 100644 sr/controllers/pages-controller.rst create mode 100644 sr/controllers/request-response.rst create mode 100644 sr/controllers/scaffolding.rst create mode 100644 sr/core-libraries.rst create mode 100644 sr/core-libraries/behaviors/acl.rst create mode 100644 sr/core-libraries/behaviors/containable.rst create mode 100644 sr/core-libraries/behaviors/translate.rst create mode 100644 sr/core-libraries/behaviors/tree.rst create mode 100644 sr/core-libraries/caching.rst create mode 100644 sr/core-libraries/collections.rst create mode 100644 sr/core-libraries/components/access-control-lists.rst create mode 100644 sr/core-libraries/components/authentication.rst create mode 100644 sr/core-libraries/components/cookie.rst create mode 100644 sr/core-libraries/components/email.rst create mode 100644 sr/core-libraries/components/pagination.rst create mode 100644 sr/core-libraries/components/request-handling.rst create mode 100644 sr/core-libraries/components/security-component.rst create mode 100644 sr/core-libraries/components/sessions.rst create mode 100644 sr/core-libraries/events.rst create mode 100644 sr/core-libraries/global-constants-and-functions.rst create mode 100644 sr/core-libraries/helpers/cache.rst create mode 100644 sr/core-libraries/helpers/form.rst create mode 100644 sr/core-libraries/helpers/html.rst create mode 100644 sr/core-libraries/helpers/js.rst create mode 100644 sr/core-libraries/helpers/number.rst create mode 100644 sr/core-libraries/helpers/paginator.rst create mode 100644 sr/core-libraries/helpers/rss.rst create mode 100644 sr/core-libraries/helpers/session.rst create mode 100644 sr/core-libraries/helpers/text.rst create mode 100644 sr/core-libraries/helpers/time.rst create mode 100644 sr/core-libraries/internationalization-and-localization.rst create mode 100644 sr/core-libraries/logging.rst create mode 100644 sr/core-libraries/toc-behaviors.rst create mode 100644 sr/core-libraries/toc-components.rst create mode 100644 sr/core-libraries/toc-general-purpose.rst create mode 100644 sr/core-libraries/toc-helpers.rst create mode 100644 sr/core-libraries/toc-utilities.rst create mode 100644 sr/core-utility-libraries/app.rst create mode 100644 sr/core-utility-libraries/email.rst create mode 100644 sr/core-utility-libraries/file-folder.rst create mode 100644 sr/core-utility-libraries/hash.rst create mode 100644 sr/core-utility-libraries/httpsocket.rst create mode 100644 sr/core-utility-libraries/inflector.rst create mode 100644 sr/core-utility-libraries/number.rst create mode 100644 sr/core-utility-libraries/router.rst create mode 100644 sr/core-utility-libraries/sanitize.rst create mode 100644 sr/core-utility-libraries/security.rst create mode 100644 sr/core-utility-libraries/set.rst create mode 100644 sr/core-utility-libraries/string.rst create mode 100644 sr/core-utility-libraries/time.rst create mode 100644 sr/core-utility-libraries/xml.rst create mode 100644 sr/deployment.rst create mode 100644 sr/development.rst create mode 100644 sr/development/configuration.rst create mode 100644 sr/development/debugging.rst create mode 100644 sr/development/dispatch-filters.rst create mode 100644 sr/development/errors.rst create mode 100644 sr/development/exceptions.rst create mode 100644 sr/development/rest.rst create mode 100644 sr/development/routing.rst create mode 100644 sr/development/sessions.rst create mode 100644 sr/development/testing.rst create mode 100644 sr/development/vendor-packages.rst create mode 100644 sr/getting-started.rst create mode 100644 sr/getting-started/a-typical-cakephp-request.rst create mode 100644 sr/getting-started/cakephp-conventions.rst create mode 100644 sr/getting-started/cakephp-folder-structure.rst create mode 100644 sr/getting-started/cakephp-structure.rst create mode 100644 sr/installation.rst create mode 100644 sr/installation/advanced-installation.rst create mode 100644 sr/installation/url-rewriting.rst create mode 100644 sr/models.rst create mode 100644 sr/models/additional-methods-and-properties.rst create mode 100644 sr/models/associations-linking-models-together.rst create mode 100644 sr/models/behaviors.rst create mode 100644 sr/models/callback-methods.rst create mode 100644 sr/models/data-validation.rst create mode 100644 sr/models/data-validation/validating-data-from-the-controller.rst create mode 100644 sr/models/datasources.rst create mode 100644 sr/models/deleting-data.rst create mode 100644 sr/models/model-attributes.rst create mode 100644 sr/models/retrieving-your-data.rst create mode 100644 sr/models/saving-your-data.rst create mode 100644 sr/models/transactions.rst create mode 100644 sr/models/virtual-fields.rst create mode 100644 sr/pdf-contents.rst create mode 100644 sr/plugins.rst create mode 100644 sr/tutorials-and-examples.rst create mode 100644 sr/tutorials-and-examples/blog-auth-example/auth.rst create mode 100644 sr/tutorials-and-examples/blog/blog.rst create mode 100644 sr/tutorials-and-examples/blog/part-two.rst create mode 100644 sr/tutorials-and-examples/simple-acl-controlled-application/part-two.rst create mode 100644 sr/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.rst create mode 100644 sr/views.rst create mode 100644 sr/views/helpers.rst create mode 100644 sr/views/json-and-xml-views.rst create mode 100644 sr/views/media-view.rst create mode 100644 sr/views/themes.rst diff --git a/sr/_static/img/basic_mvc.png b/sr/_static/img/basic_mvc.png new file mode 100644 index 0000000000000000000000000000000000000000..099d13461e324b0239c37102694b1804f5f432d1 GIT binary patch literal 30422 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 VMbs^E5d#AQgQu&X%Q~loCIIfhudo0B literal 0 HcmV?d00001 diff --git a/sr/_static/img/code-coverage.png b/sr/_static/img/code-coverage.png new file mode 100644 index 0000000000000000000000000000000000000000..5eff05469abfca7ffb505e5ee2812708ce5105a9 GIT binary patch literal 82337 zcmeAS@N?(olHy`uVBq!ia0y~yV76mmVB+IoVqjqSw#0uL1A};2rn7T^r?ay{Kv8~L zW=<*tLj~j2$n*#i@6GRSo?!BhQfXIxKBw5t$b(NwN5@j%@uZ^*3kxfYipLZMEw(15 z1qxkUN@_kQ8k;#dxK^-qmS1>md4KQyzyI#qm(NSDy0>=Kx_5I|t$VkMv7xq6L{6?J zfk8pVq$_E6{QMVh9(f(v#~jiiWx&j;;P|PJ=lbT28yWt8jFM%&AoqFam3iy_Ykb>p zEOF9q;ynfjGlSdRGB0JB9)~dq{JQsWiUz}k*9Nsu3PLP;0{Iip_%y0>Jl<&g<~z6k z+r;(rC3=5pCg*1}FwEj*(25f3e8kQWC$LO7dC%Vj+X`m}1D}OY8Uh$N&KX?$_Dy{v zV}gETs*1DIp>GBDJ+6EIx%S`RpCEMdb^ctHN%!ynxL)5_eTZ3_&83Zfa#H=jANzBh znifC&{`GTGQ}nG139D^yZ#eK>XJ$$UpZ(4U)#^4smY+?K>^Q7`^;p=nb)B1@R};Y`p6E55MR6#M{4V#Jv#C{1WXSs&F#rd|HXY zUn$jF*BFmA8SE35OipJ>zOi@#f8oDxe)T77)PGC-b9Gm!Veav*KdCT-X_3$OV@Ykf z=j27w_L;L+=(HFaupd0Y?!wG9 z&#@!>pYZ(aP5QHWzWkl{`?FP;@*~WCy*I4yb!$2PXRR^Agv39y{hE&7c>MOP-X&#) zxAP6_z2Ch2Z7F>-?WX0;wfBpiI2S(&^wOxEBIYH%l&wQUOoV-cljfq3z$y*dDQstg znU6hSUUT#PcbV^B+G9TVYI1gmmVasAS^fX+Yjbgne^dB={QkcGECUOVeu>VXd5jE! zcJ2>K85$fTDs)s2oVV{P2lFv5esTEqGQ zBa?$j-T6-rk{JxK2`pzCOgFIWJrH>dUSfJl z^kw%Fg~<~lPbj7Eelpr5Y}ruLH^)Iwp?-mZ22)qZq^7@DSe`a~a&uiUDZp|?P>Av> z*{l6keY0G27nWV9FcFVpTH9ylYQ6aHh4zb*FO*7bck$Np{}rV~L@Y#mPN*0TrZ9gRD3@0i_TzvSyHGgefr ze6q4`2+vQ`48*$9ds9HJw3e zFVhlJ2~#vv>JtbT`Yx_7T(8tPAz&KEgcTDiv^uASOy-%oW@3%1tM*cLQRS;TrkZD! zauw&Q-BtYS>K1S;^x2j(4QKk+Ov>4iGxv?PrJAMjPLrK}JJ)}D^y%KG)KB^%AGnTj zo#ZkXnI@_#QY&&^b6=Q}Mx>T(_^aSsVPS#GG~&bN1q+6J4ABg)TzYCv*5X-w23 zUABJOnrlnHImbrYdi|aCYf;-2w+Y8sdn0`XedW(uoz>K>)14Hy^;(Nr;O*euUe!+R z{_RVG7k^&9u0bzydtAAjzmI;v`$hM}Ya?sB>Sq6&)ws)X(Lq_~B@gQk>l{v0R#RqQ z9JIJFxh~oMaoXdhf4zP`{(j%karTVabIdAJPvySKy_K>nWm(d+jBELR*?H-4S^t)| z?qEH-=(12^W?E!|WtwV=Xx7z4-Zj2!x!2sk-EqU^#vQ8$%Y@Ck--n%L+MD=Gt1nbfuvu5V$ab!censBIHJ+wRMD>H$ z7p+&#XMUgbzH*b^&IvZp7eAf+-uUtAr?cN%zh3?{{DJxN^^fD9>=#H72$0$!lOYr# zxkD^P_KLt3={F*Ggq%blNfsGT(KON6V&9|w#^c82g3b>;A38a{b{GqKixhj+s))Rl zt5oiiw3Fd;?RJyzp4W4+PqRDH{!PV?UxLS!7rM749ZmK>a_)%a@wxr(N2`y2SN)*6 zM9oL-m1>x}qi39F?MbGSFHc_9{2eS6yfU~sNPhXrWlxva+P^Bvd(KylXtUiK)!N6cpI`LcIayV`ytuZw{qvO1 z=jI-o!)0q)74^I%*)F**=3hu-s$;d{MuXKKeoOWn^LLAMYjv;eUfiwjrQ?-1N7SbJ z)tj)D^)F8w{oORJXx%5_r`e)Uy3(JQoR3}iWZju{cUEw%sEXaYf7f2O9m`gT1xpA2 z-gs_f-h(}_elDx(`}OA6+qMgBoo=^}{ZpH|Y#Dcq_@`NdXD^;D7Uz$X*_l%D@>uH1 z(^qwMbZ>?qnEFC{{<^9-*}Z9XYv1pB_4V{xr?pRWTeht!TVcDccIDyy$&cDj_bxX- zoA<3Wt7O~VN&Bu|IC?$w+TQin>)Us!?@j++cIWL>>xboHRe!6N|FZdY?{4Y7-;4e` z{QqG4xtjl-^!@$T3(O0CH(qOA*Zzt>-!7>3is1^I8+J=fu6&DlS$KQHr-I+YQ`ODg zuDDsv&$4@4x$N_r?>irU{;ls5&$Dk!)z6YEiC@01ZeFhzH#z?NKF+$$f6Sh}eYSgw z;g^VO)otHhAICg4t?&4I(P*K~McYgZ%P-6C&VRpb&+=#XE_F9%`Tg(sA7OIX`m%|( z{cY298}m;m-(LPw^W)Dmr(@~I&OeQJ*}p~al^&n2rM|Cz@U-&%&uWtYU;7aIvHE`3 z*;7BVPP}>+buJtqP(m$nEOJ&<(fsZN48%!y%25~Vr*u3SHUK6Ui!kc&;;ep(~I^z zNqSuNeC4yhCzhX>uW&*Ch(eBHlFlmaWma01>3PafAGEX1hWxT2XcS_W}3nwp~FgsId zBROgI)aw!llo%?rv>){cWvR?wq$XzJ2XGDm_2% zT9^z7i}&{bs(OF#)&9!$pZ~pWWapQ&m#HS!{Nw9~wd&8^ zx#p$WdDqVSr1UrSUB<`Nv#w9SccmdmEivU9C}7yB;W zcAM(n-M=sY<8hFfap31k(G6_#p9C#<&SB|dIf-*-dy=#1BHj!04OAn%wRo=9-to*5 zmlB*+dMojd=q{mOJZ%=oB$h=u85N(~r!~#*n)#as=Q)=fwOe<$rZ;swzx<3}%tLqy z$4zeS?hV~J9ev$jyUjhHc)EG+^vFJ0a60GYzKPk>?biyd$ym}7^eWgd@M5s*YQEJ| zSF&fl$k>!wcUkIU-o=wwc`t9i8g8N>QDcx}*kx*V^Zd^Lvrle#sd_`2FM5KG?%I&G ztho}oW&AapWVfu|w%lTdg^=v_x&I3Gy)U}@bYmag8%1CIL0zOxPzo-OCz zXYM25(;_rqeX3gZvJ*>^g6)^t+TEIauk1~g+wG6%&fF8`-`uvjz37&o*b}$sm2)=P ztew3+azSiH#j#Z<)>^Dkd6-j{85vo&v%dADiRzJy$zRUSq_r>cy z*0ucg@u>$sAM9)om)k27Q-8+3=7Hz06K~TW?EKliYI^qiIq~23h}MQ%Y_rh&(SF+H z;*%>=j<%c2Yp1<_wsHRQX~|)B`Eh?T>#Gj%syyU5C}MHgGQsWzTfBni3l5VG0rxqr zdl!hPHty>Fc4UF!*$C@5W}&+0n6|s!^?2-e+R3_0fBEOd;fV`UXC&@9e#OP&sLXc# z2}h@1?eT4noz&bv`M}S)tEXB|aqmf=w0+KtL&r~jpYwmq0Y*o*gU6j_9%?&uTWReg z$E2DMotj=u`WIC)bu6_@gQ7gEoYca@!pmIOMc(snjD0vWsc({D&9RlihCwsK&W215 zs$NeOHxk+NzI#>rQ{XZd+bY-gkbto!mS7 zWwpK)d`S5$qi$N^TJ?I;$0z1?rTZS%O{#nRPn~%Sa~Sh_mR6S2tn1tFaGvEW<`U=n zFI6~ulH^LspQ@|0ZfUkDroAY*Cipp`=8Z>;;~r-w??V}nW~zKonJMCPYW~Xd%dh&M zEjupv`Q!%MbyGE~nm!)Mx;FdGxj9{vSMF4-e78KuKl<5h(HUa1<{D}m>6vL~un3o?Ik2}b|V4hr% zr@Rkex<%j?>)duZ zhxbV#h7)Jl=`g--f4eMc8CTolUIsl;bI)9lyDo=aCcAu|c}@76dG;UUT?|zY@kbO6 zUN~IQP&ld6$wA=L%+?wC?>65tKRW5esgu8&bm!mgVm^NHwB%{kv!+L5&m^DY{&-KJ z?Q`d++6U{KlY<&2Ox>`CWAcebFBU}XtytC4zGRn3`;}#1s%O^Sl-pVOQ`a?2H8a&# z)H+muYrxlvUg23wqjYcamoEEi@>QBAvxlkYx6cjV<}+5hD|GIz(Yv{TZ$ggxTTed! zIW2QE^}=J8^BL_}E&u7ui7$KHs@|V`P`ycgRW?h{zd;W5rJ^v2v-%)=u_vX*l2hA7e zpT56-4a+*C_21U)Tyu8q@xKoLJnk|`drEiDW;d75U70gAKR0i8&ixyScX#f1{lU0y z!{LpO6+D=(E|5RtR5C&637>5HI%na6vh{r*+(ne%DThr|@<_LEfA6HX=tp4RhPS^1 z>@R$Jp-{qH#dWw{F>zhe%8mPO)M+WMdK~iEBKnT5g|ObDg9jzwv%M9(CI7?4Dr^^D zRr)V^9@U<#p7k>pah_=jOH+U5Tk+g5F)}qb**oR>^8*Do56(O?dU~wT{=vy7rs_rl z?mxADIQW7R7EHGwwKN->xGyqu!~+TzmO`@-U)4hCKH*9_h1urzLK z?Av+2xO@9&y}otEs%Y1{DqS`UXY<9~$6l+sEvrn+*JaUNyjJeU2RV<8i?`XoKJlvL zOy#}M`?~)h>~?nH-;^%=a`SdB%e(1!^_3eG4fG|%CkgygykqjnNhNeje#!mBd&-#` zFMllT%<`Nc{ONK^|2H|~Q!mbjSQgsN)>QxYM85L3f9$z%?H_f|qBh=-Ty{zNX_;v8 z)WWMFraw#fJeQVwBE4JhhG~Axs_czBHr2fKSzUBHgPnC-b?o%S?@!)7iEG@~Sa+)S z(Sg(Lnaz)!{o4+^ub3ZZJH6_nmDc}NUwgmYzGb-W`_0F*g%?iF4xYZOIsHfa{5q~# z|NqVWvNX9cedg=cU(8$I+uSb?V+$|7-gDhw zPOnZop7i{0-V6WVs}F8nQgeZGS;FmXhl2%MpYt|xCU%~1`J$}2gwIIuX78Q0)vYU6 zRA)$Sk=?~)+a1`pTI2NxuX^`X=dTRu9j}|ie=76}pVi4VnkRhUyS(RKPh($Vi{bo} zeGUpeM&WNhCr(Uu-I%vw?I!)gGX;Hxyv6q)?mSoB7;!lKV7%@HWedeE+J`h(DWqw= z(-hQ?RJp2XtJXbr^R)FLGr}i@_66)*wQGUiD#vR!>$fggyexX5e%^(&B?)(O4kgb@ z-j?UMttK%yvH1S99Q{`Y&qLlNz5Dev;hv&rzhh8?x$Mtn`Ah2q6TCLmukhSqz$$7f zYg@C!dYkdTm?V!)UZ<{aIsI}8&!Lb1gxxoZ7Ks&G`^`P^UF(WolJ-2i>Ww-(oIc!% zxH?m++iKV6!@RD(Pts0%pVDp74!$lGZF}pb)w;V|UjDf;_1@vq-FvSu%-_2IUEKrb ztL>+oQ~R&B$@fOs%hs&>yQp%?yU;VQH*U9jpLPFokNdxm&zBsWe>6DwvX#95**&wB z>o(2qkMQ^}^IbI|FhBGDrPEIrt)CTte4lEad%gY6P5G+jsp+OUrAcQC)@J2q->uv$ z8h81bJy(5CE=O)l-jJ`ZaKSW?Y6i3=5CAK zZ@Xjfj>CHv?|ZzxIBj`;dg1i!>p9;)YAVR{IXSce-Gq; zdF{Hok4J1Rk1NZR;KM%!EKg{*&1jkNM&{48dk+N^8W%Jyx%aw1CH-yn-S2zrs-54h z+4^nQ{K_966lcv`bp3Uy)!j2M0Ney*W$IW+_kn&H{uu5_qLp(;&yA+ zndY0;$33DA>%GEy2FC0wod{57#O)5mn~D9=&>c? zAd}f_+si%~#<>a0zRZ3Se*Wo{?V7%7xo6i3wK(l9ypy(BsIYm_&0lR{rcQH3U8_VM zq{=?@eIVcaT71id#t8@bA8q3_IH;)rGd$rN$Ac3`EV<|Q{>n?0*FU9pH$C5@@~rIs z+iP4j9+j^&Z2woIp)B8hMCI*grP&UQ5a)ojH+&YXIJQ#VhjVR|_l$@d#_4uV_tI45 zCI)L??Kt{8y1UP$Ng1RL>IWO8#+!2tN^b?4cjm`%+Qjz*;6`)kr8g{gN+;xFTO?mSYU{*@UqM8HB-yW zwM~wgtenlA#c@YjG;v;BI7hFS`B|;y*BvjwEKKkdE_ifYgrhR_+x>H%Pph_-pOOFe zXLp2yU24|qNgC%*?yD)}(G`zUuK5Z-U9;Bf@!j}YHsZ%UR3@eG z72U*UdH3QD-s~$O)23*tA6}3%Nvq}I?CWbM|1h$?Ejqc=e&^@3P}k6%hYmXGw;8C} z7=>8mGEQ6c(2cS0b_-K%v1?-D+ci&aRuru`Xao(k#+ix_F8nxsW=37i+JCQu?=37b zc*L|m{@qpOmhYS!Lr>l#Ou{Yjr_Seo6S>|3kzuayM` zsvWnldiki;CS}U~9aYh<9|`U}v3YUSDg%YS@QO!5`!`N{w`(Y~UaagEr zjY=1CUDxyJ;mtQ)i?(jswDEYucbCLVnKJuBKPD~Sv)5Vg`0v|WubQsDsdhwwjdjQ6 zH&N?#R!uFoh_T-{y+Nud)yZj#{ob{!rp8DfFX)}(a_;)q(7V%==6^V05N{qXEV2Nh^8)Vbt(jo# zYUq9B%BK`5Z(J~wo*A zKfE;enq^(8SmD#LENilud9c)syerbDLth+S>UncwXW*4pM)MuNCaYvJJ+!%Uj{CzG z=>^x%eddhtkX|uKvsB~2F)tIg_WlBs$V`y}$(->20fJ>skHrO_tM8u{zBfYYqfFnK1~yTuxvl~Oe}KqmL-v5JIbccNcC3l-($!3HTK?O^~~3zUoY8N-R)U^@OPEz ziE{=|67(PNaxj34x`xTZ5T?jBMra_Q7E(-!>oG;8AF%}b}q zontDDDDiQ*vgv~>cct*L9coVmg*>u%$Ev(FUNQAb@Uk?S&*D|hc5%W&X zOY(el>#KHhji6?d=8ulY5AB4SZ%$ERKk1`ptkiz+Oxj{e^F^26#Mt{e{8;25IM3VE zeusYk>h*6nt?hc}Gr6jI+3I7hhA0Wb)3# z>5!uR$5g=?21+we*P5POUl;!3+w83u?biH?R^@1|di+ps_S9){0=)L73reGzmtRnq zx~|_L<1F-p)#panQ_V+HR>zp-+{@8*OJCIYimN|W&}Py4O<|2K4|!zk9vpOi@$8gA zcFHC`o3*Qy&*-$xG{`FSS$h2yhuETx78du6Uwt@oKf?1Cvyt1Sz=_ix^IblFFtX9@ zt6!0D>Xy;ZIk}a&d;NW!)~JhTzJDTmjsHbY$KeBwQza$YOstgKUrgGnb(1lWanHwV zg$!;lI9!wqQc@}wmnVfxXX3mOl zIoLhZK2#)RmF-35W$`H|9t6)UX*>`U8q?8R*wUyy{ny5fJSD%t(1)QhkCg-rd~J`~ z8&7A?_I`abwV?JW>(?Fk;x}b&obXi6#P8A(;|J|L0hPY}?DCpRwtkY>qvCh**6Qw0 zGV*IKe9(xGc1@JdYj~c^+W2qUU$2OHN&0@do{q}vmKHNDj+phWYf<5~kCTOuvWhnQ zH(Z+@v({ZE(1*uAtb6{#fGOLmkJ#^s?PlkB?Je!{S}93b)pY-r^0L(hBIXyCZLxmQ z7QyJ9)WU3g=~vwP10SXyth3Mv+j?)?(#se3-B+9!D`ix$dr^SfH=%M5jc=R(USKPg zi-R?({z!4yeE#t8u;i=uxb@dxrj>DXIIX@Wq$U=B;HYr9^HESsM)|`nooQ3=O!%{9 z&trDo*HYHJCgS@y1Snd5OIfq8>~i*9t@DMqIM1{kOtcg*w$`&e$6+MZ%frUIf0kgg zsY!mepz-9XCN*U>tBBj^rq{WsL!s#Qzi6RrbMb>;8F859C&I{663Fud0g67S^tOV8Sw|;?R@{;i>=M&IwtU zUVZ#e;`#mEtWPd4Hq)NCOZWNy^CBlhPK3_+^J-m${PF40lBQm|r>{=+dYt)x5v(mX zC(*;A$nu*(b71A}RbCQvH5L}x^!&&PyYpkCPp^exwy>>w z#f*|Aj53IpOCDDzUOP|%hxFV zK5to(9Mj&tY}1mGpvu(AA&NZr_vFnzGX3UFzr0IkTa&^;y&%Frv(c%S{PW;rZfom@A|pkzp_2)a0mCEx}D+u0&+f^Ls#y* z+;HUN>ODW0*56;_aGkqq>xsH$XA^Hh+hKl@0kw~3Wj1Ur`Kx6u`J(skTxKQ1-3!+^ zEHfx@nZmaC&#|kwqs049xXzQk8nkD+?s09K!p`}Ah09lMit}`{^|`o6HIUJ1?Vi2P zecx}HBDJBkrM*t2?3y6T>G*6}wyM#x1NE7AlIH2oHDs#H+&fAC$!ig=J(8Un7dNe7 zI9MRRhOaGN~O<6njYHybI^a5?)>eRrsa}GcJ z^>HtYvvXg|roF3Han2U}RV7&3 z;g_>pQtc6@6M0~p_-cu#Z#SJ=m-ltggr^64c)h`hg4AFRs2O*w(%!-RBp(mGJS?+5h%b`nX27 z-@F_D^Dh?X%+z`ZJxE?_dA?@V~xwbyYJ|j?FIIzw_z7@Q&?kGkv6Hr{?6p zfBZv_>vPHDO>DPzO}W>-s5Ya#UMn}Hy4^cT$;M*Wv0rU<)24r~5lfcy*Lbq}mbH&u z9e3=BANSVmEZ(}~-NM=bHz(=)Mtkp{sK~`ru(ACJ<30r@XqY_+cXn79@Zo2T-t^N6 zXMQZ0A?!b6()HQz#P+}a=@A|>G2CQMZC%aMZSv>&yJ|UAA^gL*kqKz!@$3 zlysX0N-_bnFr5 z-Mt#}8!RG4*6KzSrLMVg`Le!Qq9*&yXSZ0^AN8+bg=U=(uhk4HU5u9h_J7`;EFACY z>r~D?yDfS9#;LbnWp6rhS915HvVD_xN}I;4lb$wbNB$hvM;l(u=va~Zuv_et8qXr% z6Ur(Ru9fZfxRoBD-9FFgXrj#V!?h|0HO_7AYxb4PmlI!pGGTX{UX+Nei*MeeBOyC_ zxLQx}TZG$$=3Dy8PG0y>W9}4*xz_zs8OqW=C62X66g_TUS{-b5lFdc1v3XI+trccz zhbJgc`+jip6L!Ap2~4?8QeyrOMWGEm27wujOpEtzO?UX;v(n_``gx}{^Mhyk+?oYx z@l4G#(-utH5LoSPE%$NKYTjv6|Y+JyfZGT*IsU%FmHpkr*APY zM~PvG$bAW;0C`zjSiR+mu@sb2sf>cl^nt=Z78B-WWT+C|HtNvA|Tw>QKfr zPF9b*5qH-q^xXQErMWGALw?5>IWA~T$EaYy%reKkedVuL@pk8?K5Q2*NX+**S>boa z{Y08-ka^7CA1UixO^UoK2zml^oL;9PoKWK@Xx55sOU89nO|h!-xG_M>HV7& z+TD6%#h#si%8KV7wVJCe;_m)?V&KA^dpB*^*6zjP^_<1c^T@oIt8-61`X#61nQr9E z#$3etr+59UXBKl;U7PgCP3G0b!@`f`r-+`~z_;xEtx~~nPQHt_KU?0#*Z-jXOB=>*!?MG6F;wYZq>gjp5a!xr^dFLk>$d+XlP z-nneEy5l2OOfXKgNH%-LVcdK)sb`vz^v4@Ay@|2eCPEcgXO^DrIOuMFNI8q=T!#3` zk2cCu?=M>@FIh12SmME!mlh@gj1a5+4H-G^&U@6&AIlESG7KzpdJp8ZlW^b zN-S6Ia}VR@Z3HO>nZl@$Fug(8Ud!Xe>P`R4{Isrb-diZQre2);gu8ogm{RHKo$L2& z?pq3 zgirnQJFm*R_C8lgq0wu#naNy=(NkRxUXP!;Nc8umVDYWboW|I#_wQbz*nke+E>&32lad$a1Hb3+G z%wTMDrS{OZ0wE4WQ|+?G?ZmOX`!{7*+dd+X!nrw-S+v%OIJ(zMw@MogD0YQ@9dO7}QcoSWtLL~v)pr^4NwQxAK>8;=Ye zK64M8NVs(6w%tWBwVzjuEuZFkP4ek_kp;>vySZ|vFU4tTJ=9k{^EHLNo1h5roaqaCgo<&&FRHaIu~!Qcpvud zH>+|2Ld(RQlFmxDR%X0a;WvHDnb+&w?ycQqW|OF$TP|C<`sxYwDNU0hv1%}vWsXJ3Yt*sO zvlA!uWLVbjV|sb}WX#f#iPPtt)N?xdJ7~J*y82JKKTAH%p1kXh^7P6J6D!|rO=Z!E z-(8kFhy8Af#A7pX+gnTKUU|itm!5W7vsYF5*lAy1=Nqw6>4?_V*D7b#EONmO^<(`8 zw)5r-OO(90vL$-^b>Eh%?7R@u-XqRkZPKhqgJuOR$X=(Rvu5r^+47RTTaW%ws2c!paphTeH(OJho*O%{cR!lg;8n^$>YWEYH{5^io%nvwI^u6oa z!V|vL+Up(nC@WvPZ~N;iuWS9jOHN1F?31P#$)1o8bx(hKK8W@5{rT7LUt4NwY}>4? z)O=?uuWG7M?1`=xh2qOwg(QO?>^I3X>_3)h>}#uQx^}MeB#Q})4I_5k@42WrciG-e zE5gn_Ecp8)j_KM1%ejlT?%5QW>rm3iec3^$CsuWv?2XLXr|Vyay_)bdE_Ujvo{C2^ zIOgh3KU03n`}Ncs#rWj`F9c$@WJHEA>@@#W;k@tJJU+|5D4*QYvsv3X4O<);-`&ui zU6=KA?bNGF=5rXjc29F*t4q}apPbT=zgIC`C$^NIH@z(6>UTD`$|5#v z`-ii4_s`c(|DtQU&}I&#bJciU<-wEx#hu$Ow;S7?oOo0vf5VYnm)rK6rJdqEquK-x zO8k0Ny}yye|?h~|?+T0(@O}?vR{vFF;tTxNOMy4f~U-X!S|G#m=4;u?} zRx9T6>?>fDe&2rP;ZEHMg@VVAZ=7G|z0NMNk!f>KBFCg7uD^?SznX0l(R!^-@iFt( zP4V9Iu0Y3Xb+#S|UNr+(T_);puus?^o$-XJ5ZzX7c2n^8WtqeLbJzrK;~F z3z_Bn#Jo9bnDKSVd^7EndDoQZzt}2mzOF|s(f+ix>9<{-r5d+V)KtF6O72go{Qa3% zcKhdgz3g|%I%4`q>bHE`mATB&)>$cBMaAX!<=d;GINJyDjUxI2+4&22B|%w9eYzXi;G&|D$H$>VAsoMRS#1a+|Y zxa%uz^-p`}`+s+`&06y6-Gp|Q-TY4@C1wW9)jsEck)JKRY&9vnN=asPtPRF>2CY7c$l;Yj4!a@YK43(LfnCr%s^y;abOKA_t^ zqea(w-8{jasqSH4=fz_Ev)}vU>V2z~4ZWQc8l&V> zUcC?V{n2U?T<6yxXZ(&gH)G%AqlfMuYL$6y7|piq%wo3V8Cwo^pHARyUB6_{S?#<` z`--kBZt`M_f4UrH<5c@0Z+Tu$q)Srh`?x~D1 z(_6Q&Tg;U`u(RZCnXux%ZqdTz?8uY0eg0EYuKrrOFJr;oPc|oiArQ>|K$SLjf9$rHW}o@ae{?#L?~z2Q9hjoHx! z&}PxHxd%R&f7y~fFR>M))ncP^l;`~uZrH)TI*J~d{0D7?$ zStU`a>8Wccy>sN-Dak48m{E8j;mS*nxqV$SXMQv&lvwOAu(>da$!+t2YDJ^ctM>vW z&bo!>XFJBlrLMm_^<&!NJO*u}*PgwHgV$B;D(>;-U^h@}o_8hr+QXf$Zf`>$t)k zc6ox^+1k|Hhg(0rdUgA%Y{xsl-r}1NGOs+0%n)BVTl?^umlH}SEa5c%$dGOH=xRsA zR>%JSmnW9YPd~4E$xiRbc{cZIVbL}Pjl$1figDA`w^!%;T#-8mElCy&ZTOY@e}&dO zA8RY=uXj(`#ZB>@1)8_+owaUp@y{BUpz>ozu(beNYATJyuRlu@U1PC<_ju;P=zr-x zALsX{h$udpH)rFqnd%iUm>PGk+9B}0PnjoX=M{eWA8l2oSHfeaK0NxVLgrjZ{LLeU zuhqoQOaId9`n7=}SU^Jlb@Q37OY=`%`C&Y7gSOrZ_lkQ(u5;$E+p!?&!|v_-o@CiR z>PQk=e59~jZpxMEUlSB%xGP#(ZpLn0x2tw*grnD0u|FZ*piL}G zXx)`7Pk!VDG0DiqWnb$re^DU+=XDCJPNyK>7mwG~dzlW0v;BS;9d)(pc9?my%bZ24 z4y}&p?RIFGAENp1<`Lru>2^rN{Nj6Nz2p11CU?3AJBMZ8v1k1Mv=p@8h>3~&U+b6q zzD1i`9a`SZf(*202APKSf`{6_iCZoV&E^#D);|!hI9b$bb;d+HLW#g>8V{5zm$4S<^R|~KGopxC@w>mB{H{njz$Ck}crbxw>)*Wnqu*2f?pY>bQEZ9JO zW}8%`;rLTCX1@EiB%a0i?SbT%>4iUaR_AZ$EZxY`bX=-(X28#!Id9hJy)t^S>(gh! zS^AO6l9ddC(&+{{-`)l;Hd|$F!gl;wF)!b@t9{;PQMV1BtoU4UTKL?R{N&AntFJD+ zsO*-u_~e%ll4`|Qw3uvGo_ti0>*mDsO7fYZ?AA!nZ?`_?U1|wT{F9Vv{IL1BbbEJp z$`_l9BLiT3*48=u^2Ui$jOG1UNQWQ1{8d|z>UjlwK# zH;&$*)SK5^jtOzZE|*(-W@_IVR{Ne)*XpNkSzs7A>);Oo+h+63&EEvh84WL zlitq%e{<_C|7;h5zGn=Ki$9fxhBl|pzv)fWY0;xk*W%Wec~u=-G5616w|l+ce-~`X*!_Cl)2E_WCj72~uYpPM zJ<#dA{oSfbb@zSqm%op0)bdNaE7N(mW7_5C+7tHGT7+lTXO}u(|68qfmHBbU6jN4< zx=Ab&hh}^@5%BuUw=~c)jigNz4X#h%C|ZB}qJO8~or(8mNr(C>f1I%Bp_}8zDQY4w zW@&SAXQ!8_OULHte%${`hMS*r<`&+{)}t)k>hJjGK!!jYmrrOAwqO1NG>-AA%MiSJ zT)DRHuA>hOFGUJ6T@MYU} zrJ3GtkvOz~q5KcG^YRSc^*JHZALRDx`7m!ZD4QB_BI)rLq2BG>dD^8Nnq2+8pB4-G z+C6d8W<18%-0gpX~Xe7<6^+r%P3;@h7fpideab>qd!* zI=s5FCH(%Hr9l&w`s%-2ItpDBl43Aph8|O&=h|yCT_$QTuBm{n&9EuUyf|q^!@&=y zZB6Ff3=F+5EsSP=#r{i*v3S+Zeg z`1y+1?QQE7W^NTcl_Owqsy_2gVZY~%J%)uF#g8wzsyuJH`Tc~1UwV8`G^?MwT|aO% z&V*U0iaRo9y}-#!M`h+lnND#z{lj7H8};OzwafPJkH5LT%As#x=IwgDY!ePA741hy z-kHoj`JutDjyf%_=5keE%0M5V>7r z_~^-p3iqVh&lf-&Kl6&1{N#3By!&Xot^CU_txsJm*5`hmD*W@_`TUPgQl>$rLNNSrT4D$ zyjrsI){>*Gt)aQh9d~~8stKHPF4@lDZ~tb`Z2tpJ=YM*vobo+Dxwy)8Z^*4>7m|1G zySMNHui>-Zg%kX&3tiH#eGB_nvzXsdcc$0;15cS@qZ8XXEvjD}6F;uDZ_=!mcVcD_ zZ}h&H^y=c>?)fP)f5gtukNfi~e{R@D>2nsIPp{6qE&k;C16goWwxj*{D!Dt;w_gn} zdnw@k;&IZeRqNj$`5SyfDz)gz+qYI%!cQ+UTOB=7DsZvTGXAayQ`kD}bR0f+cJWGi zT|Sb+f3|*6Vx!{G$M=8g9lm6tS&iP@UD9&X=lQwCOg5LaR$g9{sXOh|ogXV)iUMIei9G$f(SRDZ&L0Zs+9*8DY#&NCt$tWxg-xzcjZLPrkOM%JszQ?AK=xO}KI6#tzkk76&8`@b?(B++%VMpKhdLHD~FI zpjjURr1yP4WARYU@kPO&Wboucl0n8{$H_>u6kd(rol;({+Pm0bR`05N*P8b1ITiOO zfU!|sjJN93OQy|!`EF@{TdaE~2u`m$kagkoik<7%==+gi}|AN;~2NS2Th`u zUtDomIbF}mJiIOPvf^unwSsAn7_X&V2~?cp*x�&f2wOopY<*zNue4b#mM$ z^Cf$p`N>__S!1UZwa;c|xBU}HOVqtYH@vUDbZ*r;gWuSf8O zXxO}V(T3ijlOim?f|XO^?BsgA<{o#NxN=*Vy2!+A;oeV=nz{~hECn?+{kkM4OFZp_ zudJB1u$XCa1W%(y-o@rgzc$UQ3R>Ci?lD8%{btOicKa(~CtS5fwr3Y6gvCdxM~NrC zzg1LGu{P5F-onGRAJ(O#H3t)?hpgQWZ=D*f*zCAP&*O;ZDy=Ez*B`6x-ZNJ#sjfXWG-DUG{ecN;B)`1;g`BKWRhdvj#;ppp@Hoa-pXlua=8I|>)!Ju-e z=nK<^9W{*%kIdW)&(4x*uGt~(9-G{xBh`0%1HVa(z0A3r-#NF-i*66pwVdPLd;7$* zLn{pG=5ML|a+qh`#EXo4JDMYw1p`;6w6$Kx3!hpEt@aK4tn$d>uGpiUw`QM_y+7kZ=1RwX zH@}zc(GP$QA5RvTaW>GLyh661u3MI1z_~)=NU3PQO)?WR3cCV~` z+Sv^C+xGBUD1ofYtCt)iQkzh{`+vzOZzK7DcP+$Y78 z#k#KoCn@JX;NUo;!RY(B@9b{<>#KF#X8oI`CAjQ5@A9Y_ZkHGH`YuiifQET-V}o#e z-rZ2uzx!t2^Si&DDRj=6U6w)<1$CF74_BzQzQ-|5>y>x?xoK5v7pr*h|Mlzn!j3$> z5A5>uq?l~_Q?}@sr5LokyvUYc;->W2XN{?B?u(TVxn;raBO6`Nc=G4?`Jc|MbCK7t z_l!|^^$OHJTKeaVxklPf>m**cypH{E|9=1f<5ZQ-&)HLxO8jj@?5{A~n;*uss;x;` z-$TX8^V7RCU#_m)$(!=5d0*4!lTMq2`nzH^l+FJhb)8nNHg%OxouZ|w?)6EEj#mpF z2d~=cGNZ~Y-i_1m!y~cH^;h>ijOaCtmoO;!{ixhM&ciQmZk^folb>!UTdnCgbE#aC zt7}{QqWg|?tnd%^<=`f?!vReWi^3OfpHy%8$)Ee7;x0CM&%sTnwJv@;|EBFi_@rqM zi=RA83VF!I@?_fHW#{(K&rfh?k9>RFN`oQaUzxG;rL^{?cWeK>s7dv^b*%FG($u{v zdDTJI`8?m5S_ZqcE8AMTxA7`9Vn#)>yL>Yupo{q1<{e_TMoZrWja@S@``s$<1I<`fmb^@IjSCDqQXI2n zUy;)N-#<(AuPk<3^^UL7W5e%&d8~_G%(g!r;B)L8$M07U&IG$SOe^0excBSV>XZxe zJD%_NdtrNZUCyfiJ}*yR?|-+DPdMqM`MEy@Eq!TqDi=Vr^ z^-tVk{`migl7tgEYC~^K7V0maVHL$wej)n0-Q9gGx8rLbh8+K9d-S(RBgff}()p&E zyUXr<`M3SZ!Jkp?wJes9TsoteWsYsheVp9Wt@5Hf z{;%$be#sEFs-H{G+wH3}FS`FQHe}Uh%W}yB3va3?9LbhbZr^@l>G6FNn`#Y8#dGeL zJ^1VW{C>C4%h~$5che&!UhXn{UVOjLT6XTN-J!0LnfHHhOWCdYOOT73r(pj2i%MeO z*A~zJ-28X>EpD;m57SxOy>hLJuic$?;JJH&;9Y(?E1b>mzQ(va8G@9 zYbry1+RTRgvwS_OzSQjV$-hz_Dz=1MHC-#T>S%1swywi2Imz)K@Ap5*{Qg@?_>##x z|EkLZKVwc+Yi7RR-xQGSzyF?oov7V|u0>{VZfr6$JaeIB_l_vTRy_%Jle`x%CjMXd zI_&HAY4tOwh;FMFtUk8J{I995X5#T>zV{EFwQtR4Sp@P$qowD8O!vDla;}tX|E>r$ z>zuk*@u_K+Men(%p9L>|dU`S@X7=pR4UZ0(>0Jy|RcMcVud}*`D9G7grydUU>J~-rXvfl5dxPF+#^nEGSXaKSyA&6Rw1iY#(@*>=xMQ}^8aCtm%!+Y&>}#{@2b=0a0S=vi zoKeRlu*=sz_yS@z7DJmN z)P-9z|6bE;X2LtKnG2c|y+I{9#th+&Ug!*AsdMGCw_fL#YBTQpbBgnW&7_N)ZcI3s z9`36DM^W_u3W-z84CdC#=Vn-$HtRu6WCodtR!3arzo=vXnYSzQU0;OrMCncHmRFeW z%@2ZB2_IgB!>WWQ5)ttSZ>A_lY6>ok*N{G=p?}(TvRA0u{t0ttP0NV@j5u z;IesVr~9&9)J^-ps#1CP@tqvP7rv|SKM*N%;u)*#v}a}|uV(cn@ZY!i>FxVde9F!* z$x9<{v^`nCp3F0G>#b{-jNA8}*n81bgDD>p2@ke_9IZT4ICnXJdd(!|Zcnwz9l@gi z&*X8`s%A>s9hdkyYm1_1=i$@AJ`Qoej&*IRUTtp`KXdZ7!h5Bek?)y}ZkZd!)|J0H z(%PoIysy~)&K!TY%w5aQm&-<1zx9fIf3-*4`Lx&6B{Dbv_7TdB-rf25 zN$)|6^L)YI+P=r}ZN2qu`pYgU|Ce!E`wAWf_b>L`X`#9*cdpF)@NR#VD>YlyAC`Xk zG+lkuy?DKE8+0u*D%L2*+%0-|Il2DVvjf|-n?G+Yi)qP%#=~!xHH&BOeE-&hpWrMJ zf9gL;ZA(AV5Svt%l*)AJi_!7>-P!&&R{wk5axeI8mZ#Z)Df4RnzL4W`chdQJY^HqQ zg^OqOO;^`e%1xA)nX*ISO6a%sZY|U9Xa9KkIzA#tiRbwitv8;X-xtiX{F1bzIqvMu z-7#<4{`_CA^7gQwZ`ZkP=h9staZHr1GJpTdTgc}AE}7p~rvAP=WzFw3o;SCCUiN*z zYTw=L8;bsp&?PI+1Q^r#@BVmn!)2qq^5e&+eQ!NqBpDlIJ1PE;%44O@ACJQ8x&I`y zO>LA@{FQOCaQCD03$vNlo#A3suIo~rWSY_?_uGxj&J44vsJwEtH2K`~eX`|NR;J~v zyEa|g_dWMyS@46zO&bm{eE%t>n^bt;>bs@=je3vSi{JnG**tTlz^wk;FW$Z~5zIKd z`F!7z*l()2v&*7|{{P2@yxuCK=~ zN@%CVt3_T4-uA$IgKDY1OU!vEo?p6W`lN6Fv^h+_eR=)&QTRjVbsAZR z`*gE~5A*nL?_Mn$Tv+O$==$pS_d?;xLACOC!?S(1l}de$>UFx@f2CGy&OMQIo1;g! zEvfzNTkq@bbz@`Z<#OW>E~{%-7qCHAv!pdNT<+TiUlAh21zHjE?g``E)6bO`Jv}{n z=MU$+u!CL9w|8t)^~}`pH)brmFl|opUQg?CnZ+78cmH4frn)X>%fq|(v_HH z-Cfm*a<}(&hfffF*n6SRILQ{_{yfX-RgagJ&gKi4nz+B#^z8)o(ia!J zkMsZkD=Ow=_3O@EXW#elj&7cx|L^#BR{K2`aq0KJPL3|GbJmL8B)31uw(j4Bbq-Y* zuB<6`NoqNDNT~f9|AbcyAggj3f`uxcJv`iQ{A34s{Je}k2)0yRcJjgMnCWU0a*WJ- zh12PY7aqAgPBP)^P-~a4^4V*j^`AahIJeLH(MH?3br#IE8oFN!=eB%<6e$U= z3s$c5R1wmR*wAoRE{-#~v?_{!?Y{NPLf^m9NG|-Tb3AOVrJkkryymGpof;07iS~SL z)s~11O|v}yY(jlk&bb}C&xU>8_-fg&n_xQxGgom3e`S3FS+ta}PO#wC*1Td~l^@KI zz81*V#+m95?kvtTKF_Yh&={}Scsxdh;q%)4hpL%&v9L5Wd=_X3G=IJ`?13hvLSbN3 z_;5wI;lkUM`&k(d=s+r-v~N4-X1?s){KHarE~_fYRL1AZ4~{I9R$OoOw=m7k&Fxuw zB=4z-Z$AG}`Z6UYHDzAj=A7kLC4o6%d~;jM6$}oun4GmXd%rKn{;5xhZ@ur)n<1}F zF29?%YMqbSoS)?`zZd_qT*TN1X_+Ueaat6HY4PZ@<)P2OK@QX14N1>5E0b zYFICAf4$)7}TLL&D{;2v;!~50(iD~V=X~Pl&bsaJOzMTU#cUlF?T-=HTQ?o-`LyYd z@yd|YPuwS0X6~FehhKo->dE^I5*~az`o3?^ggJYx{^sNf|I~K9Uc$2b@3E8dS*P|dsPV85 z>stLgo2@$K?WG^5{>{2{XTSKP9D$$rpFRISVfK9gmq*^7GEHAQdnGS-5jfPe+!E3B$vLNWp}?c=j~SQ)V<-xaXh-(p_7VIKAT@Wy_~Bm zKknS^vXbY0lg-&4+gSVDl)hJOIpx-~>H7?df|DX65BxqEZDXx9`^&#hN%rT{7fuyg zcx9QNnwIr9`O3iebrU}BpDuIv>m_&l69UJ7UwtIZX&V35vqE<7pQoK`zEAJA^?A!W zTj7nJv z|9v^zm>a&#=C1V`CO&9Vo5jK7YJPc1-nOe3K%=nzda-LxXnS>4^mShe_j^)pKmT28 z)fJDccNO_LkIk&l2|KrKc|!g=!3j_2=DOt9{*{yb!v5~(df_Vnt*cYHbC!L1^4k4- zz(2Jklk(^Me8?et_D|5}ThpHl{ygZ|$?X)I`v1_))krns!u4F$L62-#q)pyept`@F z`)%?$_phC=CIzZo&3-wYzFLzm5YrK_WzTg^1<=fyr(;)<)q_&eS7eIcfZ*BTV&G_!Tjc`EncZ6tNEHYS~?%-n4i>{!n@PC zzgC%5e)cZzZTZ$8{w@9d-nH|~+3DNfZMJ#!h{!Hj`xf7S=VG@Mt^V?Y|3AN!hLC>7alb zlU0qm=i$9Khug~+ib3nHi4B+iX3Tnmw!Qn~1Qu8ooX{2>^!?Z4_tvwgZtjrqIqS<* zmu;r_^5W;8MtcMAhel4&n=)r*$V<`k!nX3l86CNAwEz7Uw0T<>pX@a2*k8|lDW&<| zmHMi0|Av1M+BmOnZ~PyvnggP)xi>bZ<|fTp__C~UYZ903QKUfd0FgWe+cYxeQy~xycfDU9OE@mvisC*8*D$Kw7Nje>Q#n@zZ%X(@sJCdFO-Pcz9WP&2xz6 zuiIDet{~3Zw_e5n^P$Up>u&Du$>~$NE@QWEuFZyE3nd$?2(f7$)8(O)j*aR*4`#OW z%b%OTU9~rE`Rtpr92;JL`Wb+gNX72%maIdao;ziPAfCoA@8msg|- z*|V&=yxEfHPnJ`T-tkv?o3GwUJnyTu^kV1%vzJ?{*rr>*X^@?(CMy?{ykYIy+gn`t zPP`O6p4v0tOzR`d#%3$clMh+GP2f1KRBk!+J!4uRD?RkbRrIlFF z(XX7ln7{*&2{&?_Y#`lJgXNqDR@|Pm&*p&)H0Oi*r)xMJUZnXl_cb0k1F!jIyFYJE z%Xk*imC+8L)Ub{RQ}mMX8Jf1hr~pZIh${dt#F`_Tss9B1TU zLzVsBs;N^R<}9&@&zhUY6dzKWy6K_LUf~lHm%ovmwM23bcu4>Q<8y@vM;1nxhkEXR zzij*E?`s`I)i>w$9m#V!{qnP@$NjvUdUEmYzssdX<|$5^F(ZAt9`Dzqo;?c~8Y9)A zEdn=n`vY+XO!vcM>a>MyXB<#|eE06`@7sfZzw=WttvEGr;mPPG7KraH7(qj?f37dz zvswG%@ze1_;vKuH+K;Q8I$zVAG;O!?wG-xZ8Gp7Ow~fNNHwo0Spi)Fkgf`9lXcF?u&%XuJXt2v$7rU@oK-*4%bZ_m zd!GJadF;b=mB|y*>We;{IPT7uHb*C8A+kNlu6n;9EFeklTr}}WUemh_8=j>PeCho||KRszl{`$Sg{(U@A?!40Fc=Yv? zx3f>ZOPH(MTUt8RwAAdJum;}cRqfWt)9UG9g$AZ6Ds%=Xb##K z@WU%hXjk-&mUj0Jy_Irz_x|uab};|rpO;71|GVaSR`+9VQ{kPqkH7z@&FkG&FikU>Z( zFDv{~U+Q+%kNfMZuNP-Czn#+#9a|`nV)B#TH4~*){bTx~m)$=?@wd^*N%JQUdseyk?r-j#CI5e+yVAV};>#|_s1%f_ar{_&vt^0<`RAv)Atv_Inqpz6iN>lWAty_4r@c_s6-v zXmrcJZ55Vfa?d?=Z>-kdO{+~_pSgL5Z}+4!n~Y!CQ9+0Ld}r_5yyntoW!9^Z^7H`< zi<|EOi^lzj^)A6H$~Mr5Y5AuH_=xErMf24OM;mivOaf;8T|335o4eXOi|x#`s0f>< z>)$NUwR~PRx$K>VTjPyg{};dYj@g-Uc=vwWUG6oK*K_ag_ExgpRx7?dPas|Lwx{dp=iP>Rasms9M?1 z^8W8#ysz!|oOs&0TsCHN`OT^zv!b&PAK%_7xb4r8NzS*9?SXcHPkv>Fu30*;lGCF6 zS0${=JNJ#W=jt$FHR0*{3B8kBzI^tpWw&4V*=?^^a?Auwu^BOFIpUDaW`-F-(SVVv+ebcw@EviHm?48 zGvvbIXFa<+b4<(UNX|Vho6WiK<27Bb!Uw6M#*<3FspMK2$ZWr9!wo$(nT07V6tR1(MJz!~@jHLR~+# zc;DVC_(1H|2^Y%ZtbQ7bojY;nm89xx1q}garha#a%X^YPzdQZ4e_E$kXt>(ujgz;m zd%N^(^}f~86)xxHPA_%e!g&_bU3p-LwP*ZM0@^c<-nKxUQBb$u^2hVnE-6`6$9_wC z#wE|YTQlX*_mp_ipp|`CCsdGq}+v{3Z8X=Y8E{l{@8D z+Vpw%rwB+vSA#wV?Q1z(Uwg`Ww@~e#KdOa|D^{0R_$-1??$uwuS~Fku^Sz=E^|{>N zio_47DfZW2{}W}hLW-+zkHSO_)swr8FNZIGW;S6b+b^zjYTPHiIt~6h-Ar(+jC?mU zWR=m+)+blC#CZELg&ywpU-?WZ@zu?mn<*i8lD@5!Qw-}}?LwTH{CUagmWb8&-r>`(Q{tt;ot{bE|)J%MBL z`Df)3KP|7R)_C2Hs(N-oe5d)YHAfx@K&q5y0-$=|qYJT4>7>e|kfZjSA-fmO8?xGjzzn^e7MS{s>-47Z;QQ?EOCO8PI3yklYAv>cD!_3&dw#1w_l%f_n=j@ z)azGT*{^2((w#V~;N`W?t&(>CfA}qv`g1cWOaI1{32kwIJ{6t5y7~FFr0M%KUI?%K z6?^L5@5uUH|APw8t$ZBlUS5~~^l8L&4{dQf+i%PB`EquD$}rwt_KOc%v>D{GtYKqZ z=KEYnYtinb`PFi9o#Vu(b7qUS@2l(Q`NjPG&vnkd%Wqwsl+&PT`}5aD z+bPF6H$IV0ud{G+H{O3`&9|qOE_DR~P3aoDPyM^vap6-nuYJv5?rz@}#V?_W{$6|7 zubw$LePdhBE|sWHNl{59hga^qZvW@}(XjgUCG*@9TCx*VF7ZTW|8W=d`k_#JzUU5b zKd*jm^@rbg-Mi!eCRR86|0BLRE?)1O!@>R2-<*DP@y~Mh{1s<+lp|&!-DlmDUCyTk z$z2J%I3sFBeYU^4dBGjDcpuw5$KQ6@ zOW$ki-RT0ZjgL6)T?(p=54taV*Yx%_-=6xHf2sqOYCkVs`&*}f*N(h1KksaR?B~Ax zSzc&h*sbsTbZ_Q$)wLXAV!rb{drQaB+ShlU|4I0-m^*p@ZIhJCszK9JZ>q`VO8@?z zHPd?Qs?yY`T89<&4CY3!Vr%XeZt+~U(LKYiGGYG?-Om4iZ!78@Z2ac>fCo}G*?2M$ z7ju&%komWdOJlCaU%k`mY$6L>PMa4(Ap-xvmSegKtuAEaIC!>}m z{k!Xb9gF|&`^Tg6Go-$&@6GI}(R;dg%9ii(2Tz}?`t`N$Bz7Nk3Q2qw{@Yn)Q) ztlE4zhYO>Qybns|`};G%&2C+f=dI_iW{sb=2q&=Tp0vC^drR?g!>%LO{>taZKRV?q zeedtvi?)wW@5p<7FIMQ~#<#mGSR)1Ran$a}yWBoyNy__&QynelzL>Uoxm8@$_LmHy zlHYEJU*@X}YUkTqpqwN5>*3LldJ|t&Jj`Uj{w8+YJe$6l;vYZCmSmsdxmP>)PtS#O zOY#MxJ|EAwuY7#;b7YsSr>FbMS8Lhr@9$UMp#A;w-g+(Pdav&6AE)=0e}Ck8&;0-6 zpo9GSw|@UUB-kma#qGT$Oe&!20V}l36KPDBv#YUi=6m_IYHr@Fas}DPTF})&5B&Ds zZ}(gqqAYgK$v*7L$0ZKQYYrceXJ%X+x72WBWz4p#>m_U!v|6l-S?$jC#maW};REZ{ zjyx+`lcyMcR`$5jJ%O9o`urf1t6NKFPwT1Dl?#8oqvzA*WlQFI#(#x8$8*2s9*~4o zSnUa$)^^Hp)t)j=EiB7cHS=oDv`(Sna z!zK115A&=GGOqucT3A@v=yN1a(m(f}_2ZO-2kxk24v?n_KnKWG4}IZIZQgk+b!U3e z%2Q9oCk0pOiC|SUGw583Uy&ImA{p ziEcR9r4+GJY-xlZdsX8lG5e!jYx|QoeEIQU@t+3|_KRKob;POv#Z$JZ9W??WD@1IU zbntKJ5Ix1pr=&2korP(cr%&Gh&E-rgDeQ|`RZ`#j+gV$0zJ6xS*SR-Oo;q`HvsM+S zrP6P)FNs#mKf66ty}x9^0h3GqLFcDD`}?!KtoigGtG0dn8;|#K?>DKB=E=U@wB*7A z{m-)tarz-P_HfvR-Rt{_eWj(Wx`>|ugSe>d8ZvRUN3#ZptkP5ssH-R_J4jo zlap=<$#O4gYgRri@^(jw<&4hf(RV%O7N{z#l&&e*qo*!io^HNQc-H4-zYk@`eDP%d z|GsS1ss2R^Tf<#4F7#Ude`q-~t<3$RIAj;*G8sl)`O?dVMFn5~Xk3!tI^FcqLqWss zZY{UY%lF)z-uT@A{PI7K4}Op>c=7IO(G1`r3 z)O_FZ?##|RMO#0d(mQh4slvEU`+bJf2b(*GZ@vFxtf%qKPhaTk2Z2r7XJ*?Kx1B68 zp1t;_`(@^}SFbOta_j28Ce3p?Ex}0Ed&SDR7RqjM+~R!I!BZx=q^}qB7A$<<5TP{5 zPB59dbmf%eOs~v>)4zY;*1B)+CAYZ@OCX!%4|J<8*t%}^mfuBXaiQMpL$p@xEfrSW zZCUZb>HXBR8;^*|K5X9j%f&5{-*%$Hy8r36O*b!z-@dID`Zg?Xb)avMpXX)|rAJ}K zi_XqSU;T5@yfT^cdk5z^PA-Z4Zzs6hp_Vzw%*vqsnYv($8v^b#ZgGchAok z@q{fy)o*FI<~QTjg@Eg8&m=#c$znFE{K)YqhuN)4l$HOqyga!@X-?FUXF7KuciUR+ z;heR4_r%LeGjvrm5AX>uxcTczYWXjARyoDOHFtk5oxj;ow(@<%bdh%f9ha}UwHjsj z{b-dcx>2Dfbad}dtG+2IZmK$)k3Mv%-E`@8)BTve?LJ%Lw>OH~ciUX4NtfT{B=T;L zRQiWo^8$8U?p>F?II8-cS)Rj%%tZmuLo2p_i}0&i!FxB*^?bs`U!Q^_6fEyn?o_vW z`+M(qQSTPN>33pRt+EN6HOqJY!-jyRd!K)p%a+BWC<&?R<9HhDfB*e{|M<$Zi5@B< zeeb!JBsuPP(79@CBsr&C>Zr)dh@LNB+T0$tsY?G}U-*Mr#@CcdNU+|)%XrCUk$*=Y z9MoNs?;~Hcgh5%5)77LlcF%Mrso401;(@8xc@}D9*EV_A{izYnym~9t&Q}%%i%9`LvFf@xqsdH z>dLw$n}W75{m=byLi67lw}ZYRYv-u+5r zHScOXAg}P@)$ZGy!(0SeUq~5<{Mlw7pppV!$I8&C>BtbXUGw6ZgeNJ=4)r%Ly?c6c znMkXh{OqxP%z4=W>}@&ESE|FFP=B zWN0($&NC1#zkl+NdztU{4zuG=n?L+7F_5f#xBju(?}USs&u)~DJT2$@BLC#?^_!ob ztx0(!uu1XCRi~$E#ksk57o<6Q6b`Ik{bpn8t)Ab^ei?_fq!JZsz&|Z}b#t#&_SU zPr^#SnG_WoyH_>ukN^Aq^~C1upKiLTb>EBV3J6wTBW!)zIeh7E=ndn7k$zRkQXlO6enY^n^>uIWJ z;^Iq>`lp8oSsh}71o#w|EjLP)-w1A>)*LU+-z>1by4XzhPO|c^4=GyJ(`O&{xe~iE z^Ce0>x+OdI(7S85PW`^IVp-d+U9WEKa+CY_J!xxEtcF(Y1?5W{qqhBba(d}m#?Ck0 zHB>G6=WfBk+BeR%2d{s=)W3I{NQvKEX4go;)R|Yd25ahPcYj-Ctl92Yzj4`w^|HCl zQQ-4{;usip_g(K@ur&GAyWf1f3jTdtT2z00`^y#kEw-kdv%a`F(B1x#ea`E;R5`)( z?gtJRFWHiLdD%nj`!2Q2E;rtbH%P5wVLI>LaIT;rWyT`e>3ZzOAEOTDt>Y-{E|UIm zaq+J|`R`v{Jo1fW>6B8J8o2|XVnXKM+iLi3^H1mSZ9CWY3QIW%Ey>P#oOayBWlr^; zS?jZAT9mH)`i0?}+ac3A-{p#nbB-TKH|F&$d@6f*@+zfQMy{*27Hiip3b$I+k*AKNG z{@1gjy?w&ovoW7vGBYi4zdx(?O2#}>M)$I2b-7&WeVaOWI~?`*C=yDP|LOP6ZCaqM=$ z`{v9Izj{e~DpywiU6&JieBX|JiMuJ|opVv}$oBpIDN{^;URkNfyVY##qx%!yRr_+B zHIV$j{C(SxLyQ7H7PF`*9dtO)!2h-UW8sA$!AkDsQ-2rL_)E|IIIDcYc`yIp>b>^y z|ChF}@KAc`Jaul&z7^A>58BNRy`r}IZ(Z?j52Y2SeywBt`jy{fWB;-!HMvRe-dEqb z?_N=U>E1s(r=k~pL6L@B)mOV#oL1S?vm$owr-tkbRp>vj^T~6U-MhI zXF?c=vN*3@T;i% zxW`k?(=9HbdgMTe>VmuLZinQWZjk2qqscjgZI0EC25 zL54FJI2alWRTpgapV6l+sv!f)XyC3Y1JmS53_J2BZ;Eu#1Q`t71{@%G;SpzW;rF>` z>Qk1vqSNUO8>` zcGvv4uDsVx}s! z&oOV(zil)5^5_1H>AbAqGO>X{V8$g-`Mx<$^yBpa|L&XD&ZwGo+_v2EuKMcD%O{SW zm3cYw^ts2^rheJ7IF-@v+UDo1IUn3ikNR44Xy!cjatN=#7PC6jLqjg7xo|Bn7j&{z z!Jw2QW8-T#lSwD8K>p25p^v7?8@+yO_o-fX{$<%Yymcof?(PaycD*#K zE52~q!HYXqUOuIND2S71$6k&%0qUTxKLf{~o17UtUoQg{+I^D^ch#BR4d%5%VSpiQ1pwmJ=f=mWFMy^s)XTWVY@T${) zJS+!Fe;aR6x&h6z4h$SVf=p31t5x6aoBXr?&8$4Z+`iN75C6YRaI#6gRcQRazTgDQ z9<|m8n_|y^3r5_V6pw~hsvDiYooN;~+x+J_xvzy+G%tNfP=olFfl*;WFUyvSD{mjp zoo#da>g`45`mWnA-!MNhBYegBz5CLyY5RyzZ|xSp9VvBU){@`PZk{O;*<|_Y>%2?N zlA*V5_$`2+dab~~V!)^?R|?8~;hT6%r{9<&R@Nn;bd9sJX^q$poh?@dU(cL<;ySP3 zon0aC1tcD4 zn9gL+J~6GJLfz<4v7Fr>-*k#EiB1ktJmP42uvA&_ARoMhyP(GuWs~UDaLusv zd+qU)5_k87=qVgDzT;&6-piuk!2z@S<-b0=>Tb#md35E2peBbk+=YNcGNmFMZuN+x@PG7O0AwdeeW`#ED)~)2y^V!CDf%1q4z)V1_E)#%i~ARrOVRQ5m5d>gA%CMZZ7?HL&*N`DKR zD9u3138G97cKJ@7Hm|^%wRdXyPUhs@LZ2$8SQaL*@b9dVIr-Sq{Oz{Cmc4B`AR`zR z7C1R{$C?*@pKHvXl$?~5#J~A<^;12k<7f8>xBCm+et7uiQ~s21UcaL)#5eJ)tNgj3 z(!Fy*6Qj_vISm_BD|{>R?j|p7YRyeIZ#6hO9_4p}G;j3H4*Kbm| z)FU~UZ@b|NWtNwqtX;|!^=6mtp5n>rJFB9)+4(%60i@>cdAz z%cikydiM10@1^r@fA2W|-`8kcvqSLS?>%Yz_vO09z1scxsjtH1oYS@?PYN>AF0JMIJ$23*Hs<++p40@Y)jMI=y=EP=ZmAlDO(Su zE?j(AY1#7CTRYcOo)!P;=8_ZPgDN{2}@Y=scHWCXGW7ZmmS>{6t(GF-DZj3n<0Htfh>)a8k#5dwKOwT{)bA;s9aE- zd3-TvsPbluTqEIs9dElAKiaOB#a|qEG-m#pmCsK7+imjv!Na{TCWWp15+`^}Xz%U@ z6{oY4LEYUa&MQJL=>&VqR_;D<_ROXof3j5lCmIEY@jb138l7+8fjLHL-hu>A@Jno23K9(7j;Uf4Wm&@eX_X{~6Z_U{x(cQiC?4N}{9cCR( zdOp2ZuxQKt_s`zE$VoMLb@=RA`)6hgc)exYY|LE(mu>i%@nYiC@Gfm@{o^b*Lc_lB z{p?)z%yXIKp4s!F0^;Y?^~h~s)>824%X74m-_vIk)k>A*6oOB_laaA`o|M{rTgZFK z<1gwu zGdw&U^x@6A8(T`ae;LfZT)Fter2L?Ogj-wnvOFbAoPRG+m{PJRX~o0Nlv6G<|D4#n zVmX`s*0ocrmvGd8OEsTdrp5p2{OU}smc85eegXIM{CKVJ?gO~h}}?VvaQhRhP=d`7oYd;{Te+pby4a)yRzoatoy3W zu_sQ37H*rm$mj1%ZUL_@TgwfHE)^`he6QBWwQ}mB0MDYZm`dtENak_e6J5v4QKg_r{Th{A@}-yc3sg zzTkDoYr_3}Y4^Jfl;iyypoElEi+Jl|n*pqIL-U&h5H=!lm@4?q7Sp zA1WW}Kjps9*Sk|)+dpZW*QsuckH_P?l30)L`gc4&W_tCUOsf~0F9`G(P1N|{$0=kq z%PvIdW#Gxs%LmG86N~F2_pY=Fm*+qG&s#(7-kF^xSM1k`EIg4Pr2l)jl<-x-!+l9N z9k#gKP+#BFv^mpnf_jJ(dG@~B{$Xn`Mwu}w{eC$%+y#P@lEaJ z`!(l|^(~q{Q88w@SIPtMNw^LZ8%~L@d35q*jn3PBbE4CJ9XsVJR`tL7wVG2|@rG`- zw`=!aHaeX5FGo4#_hVPVB#BdXEJv9dTiVqVS^6uP8ujM#F}^syHFIgxz2hF=4dsen zzkesl>#<}PTS=|#$_e+69`|#yuV=W=;c7f>JMUJtmdVE-YFXS1N%fK{`<2hRH%LY> zt83TX8!w}+DwI-;o_yz-uJbC>J!5UNZL``-t-p4H3)j{%2kqMDqVNVhz`pMQM}Lmw zV#`&$TkBN!E&Yv?`L4RZi$A%4Ld%?OQ3?Bb z^MyR+SG{@iDc4v2{?3R$`kO-!+L_qIYP>o;+zmeV|F*y{^MtkXvtZnE}FE-B>H@_ZR_!~*QVWndRy@Ef(_7qDl6mKQdl#q z=+ksa&m{5g*FErCy38FD+tfaJJ2#E2t95($&%R8#x#E58<>yulX00kqY?x~|kv(wQ z&wcM?S{~htk#+AfSS&Q{q#FCl{x0iXi@*1kdOqZ9wJ6LD(b)W~BYs8VJF`3oft3?K zYbpH&4fp$oXWojM>T>GMoIeb2I3x9n-8<$A{9U%_utiX1%7ap^$D!}u_BuY_R#&{~ zgRFV*%%V2#h~Ik_#i?hx`^9k{|8wh;|MCaP|CemP{aCu(GPNEOV{8$%noY!9SBkRkiY-` zzuy)&b%i=xoTjSIJGRAWzItq5o#e z63eo%2Y0xS3cf3{Zx0fl7~pdG`q665MGqToy=E?SanzT8DSbJ0--Ccv$JnRbl)k*U zdHvemg{Pud=6O9;Eq6})JLlf#g^MP)YftC;D6&cKZRV-ftA6@yTb-sJ)S|?ADfG#* zZ9bhH_6kcSFLgG076ohHj6GP=;kBdms{6&>Wj<4;n>^~BzcnfJ_dAm9Zc#}6##;6D?bht6QI*|yr~6DXQ8s@4Vl`i9=8~Hpw@pti(OKdz&7$rf9=%NOY{XAB zr_xEKZ&E}`Lr&&9cNhgmPF?7K?97UW2LbpZRv?ly=&+d&x3yxc8osI5^9wP(+$_uT4=+2)o-|w}s%9%rin* z)QYa~#+b9LyS?Pq-vyv0NcwXaEY9lh;dEeJt86fF-Rx=lCs&u|a&v)a9v}l+5BLQb zuD|6!(7eXsfvfO=;)yj=OD#;oye>pkPVc@hKXcM;d1rIgiH#RQ(ZUC6PU*zw?Su%ffKV>TBSnt+k zVK+Fse$A`ErUiW)pWUgEah)>rcaG_&_eD}4qspD7_ixSGzxe*f?$SN)6wm%FoqD#* zXmO}Y4riS3yy$lE({qcYMR%pQC}bWpEGX2tVbwZA@sw+ah0daQ!?Q{5Cq6{KUME_p zr6oN(`?bgQ$hAv~8qfb(x%!)4_~Ye&DyOnqC>4}cJvI(!mIMuJMS#44(JxR&>lbV) zu=*>$@7$W1f7LW2Cw_Vx`tgWT+buQY#%*_;-R0WFwiR@(=Dt@K`cU&?Vc4vV|C&Aa z6udP#JO7|V=}W_hp8NS;UY#>}$EnK4-nX5j4;>D(esbdRUhi9nuf5r`+=p( z_U$fv`#(c;T21my=Bg{}KkWYYNSeW~J0J zrK;KQ&AT`LKe~FY#;<)m>(@t53JjVQ9};xQsE9ZPs*(!|3RbTM z_f6(Ke9w~l+CfQxf$6a?D3X|Zk-H{UET~s#o^apo68rt zjKh~67DRth6=a;c=D`Ht`X9qQWNXubH7dp*B+ zwa#Yis;5hw&3<3(TKn=oi^|;mC2x2xwO_Z1@6Rgwc7Dev!?(we#6+@0d38T|r4^X7 z|DXRBy@$L%wHm&By=wVxGuz(6B`Tf8*;&stwn^V&XI;2NShP9UrX}F3Lre39&cYoI zH$Y{~7nYFe9CN>DX=|+jjZY&c6*u}HE8xDn=hCHHF7F+G&RqYwD{5N3R(EUb-aVf# z$D1oppP}G>l<7eQm+*q~-@jeUPo35|t@8JY@cOm8Pq@idFFt(t!}*s!?;rHkK0h>R zUH*qJ$rctyJ{SAEr#E-rm<675+@RljNABwL`s(n0wQcSiOV=nLs#PmH30cGwW4l2i zYu}Ws4cqE|TYh|hNDaEoCuYx=leJqE^-rBWC=$895$M*RTKk5c^Ji-#?2Et>;tt4;wc;-MPYUZ+7yX^v|N}a!z$^_?`MVBd2+> zAMex^_O*;oo*UKK!y=^4mE79h?-`<=bK16Q9XszXai=FD-x_!81U0QY$dk?1=NjMX zWxc!ng~jbjOCR14IA)et=Hs$%oqMR-_D||sC7U&~Ki;YD@c?Q2hmS~pLB&pKzukDdH#M)tO^uSa^`co>u{_>M=} zJa!giRp~bcUzhEhB)`sIl9tw&W}UlkxA?DZ+|?=0Q~R!Pen0wd*Z+I6)0<|jH0z4> z2^9ze#it01$i4^at#;>EwDe7EUcJ0|YTlW~Lv9CecfUAsB59srWZO~ccU$)SmpX7i z;z)S%_twMgUbp9(skh9sPv%wl_gu}PrR(^_6(Z)zPdR4oIsPPbr9`D}OvhidpK7lT z9!~jYR(y6jKgR^Q+U#$Eiz}~PYL~IUZ@XLXNzFeg=P&EIv(1IShkAWDm#LAluJ83S zj!hg%Hs>;aU3jng^2LeMVV|F!l$dnPtN2m>evzYGeWic<_wUgAZgIKfLb~F&KP^i( zRV=SbUA@x7?5d?o)}OF@fv30q&gEyj^?u6c$mcq=MMXD;R*|9G*?ER;=t5>rhlEdp7jAI|XMTVB zX3wf=aVtXts$Z-9Gn?BSYm%9tdv$JK-Jf91b$>rD;xOdtyl-{zsql?_XS<2}j>U$i zpDXBym$=cuAZS13{?Yf&i|YO{%=h2%^F-BAsggo}v*ogJ*#WU4S|CW^3cxa z2UaIdsf-&h_do5td|Pn7`-ZaGmbI@RbWYeO`+E7ADSt$6YJXlXA~XHbt#?lw|K*sM zu`OS2q!jRM`^l@j?%&ay#Ib7AzU&E+E}?3wRmMRdh&b_ ze0ciX_rx<*E1pf13{9W0y`%F|WaON*#tGqtuSCk?>ZJt&qg%2MC7hh6{N!YH-(Bm2 z-(Hm5375Io(D8qRVY#sJrx4k7A)%in&n#(LAu)!*a9QVB_=csretTHk++VeWk!vQgI+4G-%G*A#_EYzZk%Zhl=A!Vx_@bg z?}rZs8-3)v_A)Y`pQqh#5$xe8B*4HlxuKzq{g4oBk}x)LM*M~Q`qR8#x~V;BIeuBv zSz*m`<5^ikM+~Ip3XB%K)-KWU;y|o=V|mD^Ys9j=h)v5gwKLG(b5?RX>$$xFG7t62 zFL7j^ygMP%e);zr4<0@3oFGLx$tz23Ln~W#HaWw)t+sc|roM4$3Q%#_)m3?Q+Dayu zwJM>mt0v6X+-+4N5*k>_wld&D#G+)MzE}L|fg3Y^TsfgExIcW!YDf0V7ksvED-So2 zT_ltj`!(=!tM-ed=c6{Rsx6m0&Axjr2UDWvghpqD1%i#8JS|J_uAA*4mGZoSd(3MExu;_kCc# zNx0cuSo_?PmfMZ5mvI_SU}WlIIZztB#PHqm2fKQ$lU5|;aCktviUn7Wu{{^jU}gX9 zq;K3-`*-%so{EpJzE^`GJAG;IMW0wMD{3@pcH zGVI8E%p=jo&h*&B0n`)hiMN|p`XJKm--~X~9^c%kwSR6XR5&i};jYw*{+Hn@d{uO1 zNxO-HK__UUQSIHn;%5#yK0ZEg63c4W=M)BBDKvh65UJ+xn_gfoJ9uz^_B;I6hZ1828ua^te=#0 zbFqB(sy{E5YRsK$@pS5{sr4^b?L93TG*{yEmQEG@r`N)!J}F+c>h-(0)xq!2t`6^9 z)Omc5b{|*xrJlw7k1y;})}QmxCu{2S?bl+pABBXNnO(m&@qgbHFFtXzeeR1FRR8Nz zUvk-Qf7OIwSw`KmyK?t-p4=R>SGVeOP>FSKt@E?pU$K$3y3hK5=D}{2w~5(h_ZCZetoH8b^#4`5 z;>xo*M?%j@$KR5>B_y})mZJOLPitOdv|{d-Lk$1*?UnDj)Ks zFA9mPGPf<8T72W^{JN9(0CZ>RLj*f@r9$B0>3=_FO{iaP!HL4bD8-+lYNka-rWnjSvnsl&$}yfGDfiSk4IEagvXP2LNzN_X`R>g9g-! z>}zn=X_MEjc^f4)rW{xO@Y=HTwWmVj#*5lY-LE*$dxcicxpDO5p{(SR8(mFaGv9ek zRiC!R=g7;l#@RDd3xB$-;MqF+L0l-~?gb68CO=L+<+*06be>yHf6w&d6%SK_)ws*s z=IvofX`i2QIYu?7J4^Wg!gU%sK5>FVJMCD^1D-5U?~!fUCEK6|1ng^kZDZT6a# zD#7|)tFPVl(Uiw8?YCZCkeQ;j|6i2RO-T{eP;2J>R@QSuXT;Q+{(C?F=>H=(8z(4A zzVHndn*Qtf?p~jV7r$S5(b8MtW0(?r>+Y>pkC((=bl18P+css}V=ql>T`|9I`?y8R z()-qF&6z6!id4adBf9BANqo;tcee;^+}oKuYlqtB2m6jNcm7VgWZ}EXBx${tWes0n z!+|I225;t{EHRDVW42u9*rTL8B&rQw6v=VwWzK#kkfZhF|{j+LXooSo-sJQp9aB zl~%U;nfGltvR9}m9mLXyORAba`;kCc#=F^tS(7iGopPxA#Q(oXci4qKl{|gFx8qf^ z{44H#^QPCm*}7ywanbwC4V#wl4c6%2rER90Y8&-2)vr|U_1fuP*;>~1(w8b!tU9@w1L23w5~v5(bOawQ*jS*Nb=W51K9^iJ&P zx2BV?r6V3V2*%IZTlO~Zv29d||DT$}=`VP0$X!+Y=Nub&zwEEs_ESc?7l->Y)x3Y7y&e6%)HD~HxBTbDD7R$YVeVFz9b)fILf0E&L%l^*jV2%>d z))bhV2%l}!pXQ@%YcI4nC_Mw(`_#T!>KGqC_px2}3#q_KM=FmmxIICtXWwGC<@V`^ zzlQYRno`i;`{MBAm2YD6_>5QT9}dh}{%Xrx*YqI1x&M-UA7=b_a=R{ZuFsfpk$3h- z@QNv<9_e>1JyNeDhYro|S|S$ByNa3d&SKv5TNYBcA3Sh%Hun)srHhkY5@O+)eo*Wv{%=QQPa z?bKynxOVy^<{3Xe6`j5O`V0U5eLIi4nQoZWw^Mf|Pv7GN$U@j7RgSqYGesi*l-t`R zS=j3?E;yGsyYk2b#i^f+pGW!gC*&Wox6im&edg>&S?2j?r?95UUdq419QxE+Kh<=> z+WU2Wf7Wm2{I3*hvig3-3-gGrYcfqUr6(UcS;8OwsJBbKRB0yX`ITo&zdPM8ON{r4 zH8n{#_KtQjpTf($P(8`yw%1hEK$*9!lhbonpPx~zQQEy;r!LyT?ew~zQmb3OhUX?7 zlYiY6W^rZaW9Dxf|trIxly@I;4Jc z=Fj{3dX37Pf3Ll2+bLGP$9+w)T7UP&g~i>o)Cbv?Fkn%K{+aY94p-^aYg0W)Sf zo4$C#!|vXud8_bck%91cCG$k!KFqNvmaiY_sMqJUQW!iofW|&LuphjE(j_4maOU5?7!7N5(4kPuRVSEe|Ry zChYus&i-*z()%xyikym8Bs{5LtUNW@@QZM3@`B<=lcmqbG$%h^Kkcp4&GcCu>jSio z9lXJ=d{%OX0N>3AW+Cf!8Ux(^wAf7J_WR_3_u$EW3D{mVfSxD+&8tks(pIFmgNC)O`+vV`*=_I9xn}Ud0t?nq55X`CpF?lBn&2t(f-X9zpJ2YYxbN1dSMgeP6ZfvlpYr$4 zlDv$^u9K#h-T(Xk|4-c?@7cAhwX|=4Hd}CKlhvB#&$LdSk-KRB(c#(Wa@R#`q&A8O zHcv_F^ys=9r*3p(;l`o|q4$!V4(09Ill=Nr^S`dD3X8NgXJbCkH1=6G`)1BryIFD> zx|f4C3ZDw*n_A3%UUR?p*0&O+(!RU4Tb1l^-6N(KQnFD)?{Hx5@o&9vwk-3R|D)$e zLcVnB?T43DlrXpa#IG#=V6P18*lyK^bZk2$nx{;fyn@p~RN;dN(;~)w2@BF2+FNYw z__8{gr##B*o&WVPunBt8(JCYZ|#&V`$p2l^ZM8K!XL#w?l(xyd!=yN^w7HH z6(Y7D`<1k3evN#SzDfM```vab$!)7{H3!EjR9X^Rgne24|0gEDQ%ifY(#q?k;Y+hwrTJPVE+w&#vKQ{pev#dnp|_`Z2hY`;dctlQDa%E# ziVK+6zT2l(yqEpxgIXcMfM5KEonNX}X<3+H#`?{~~R z^<+Zr3$DN&pR@j)%&vBN=x6S-auWaH+WXgzEZA_!f5KjN;r~8)H=}F5PVsjM?z3&zSymcyfq!OD~eX@QQ*JBmZ$+vOZmH8E0l)295=Kg%bq;AjfUpae!WUI02 zk^P$T?h~_3AN6`wM$g~##_#_EhnsWm-9gl{XnwfT zmZlZ>?Y!^ji^b)xiN%ZRxvr_8?dG!IIp;8B^x$jE?)NXwIoRy~>G+U&w-CBS9K-c`G%Zzu-)%tC8u6b*fy<(R97Sn(F-?CJWFSwm? zZSTj;LdxqOt-G{ktK*ML?j3)kBC2)N?XIvXT0KqmNVJ|PoG&tW+g73ewgpd4s0tMK zyO>Cp-;%A1(|IA@v9!uft@*PhOA>75;DqLvMK7jI+Egs?$@Lt^y)E+_JTw-)eEn#z z$i)}GyyEu+Dax(Ayi`-o3*Ke6d$A;uY0_@R&2@h7e->Qu7fN00UvRR2{(423g&qwh z?jgFTyWVTmAD%h)-lR<*BHtw(Zr0rSI$TvsJ?5-JUToDVv!KeL7^O##KiWH6z0Ir- z`RJe~d9Zkgkk`B^oi6jKWIka}Qol$?~jv3Fbt2RDay64^TV`^KD?`2x4clV0R zv44`GLCN1gm${lAeVCH;$Ft=NuZZ=$5RD3*i-u}xaUy2D*35GKkH2@7Og$Zm-i|hqP}X$g}FTJ_++$X%iKkmxwx)XAG=vwseCi~8!uDi29XneWgLb+?u!>! z`1R*4Y5&iqm0zN)Jk_LTGhgeHBD)_fEL-L=_|E^aaM8=vaf}tNJhLWgw?8e(wM%9H z@$;X+E#Wm24kmq9ovf(79J-xtk)UG#oJZ$#o;)so<@oZlNSD&lmfnlSO{vT+aleDa zZD!wZ^A_mrompL8sr8>}b+ChH<<1FuXCwCcOxP9ksbts56CaI0;j*K{s?4a%%F3-y zy6WPSQlGP&QpcVhelR~$)pXDN_1dd6dwi}fz4-Lp(+whVr;}5PA5E4jXRDD+JYTxQ z;;Vc8n%g$P-rq46 z<>_!L`>AyF%vHZzvs(rx~7c|5Z9`y3tS7 z!YgWDjFQ*r%xQUY+-YgxtdE+pg;VAfyxPf`aVazLim&q?Var!+>!g{k`yQ_21RZJD z!_N34Q-*(4fSSOJ1Sa8^yE5MjFB86_763g59lVxSjghh7u9~BA1DC^tmnz9-q#qUsP%0Ud6zuU|=w8R-ZIoDeAXM z=F|HkDbcV(=Ren0{q3teu6OO@uKBaVmu~Q!xnQQN5}&u&YLjhz>qX4UqQl?DuB-X_ zaJl%Y)j9_*rY*kw@v}T+vC6z&&|WveV7-a{pY zkvl3j&Ry!%BVTxV=A7FeSG1zf{=TWuXd+PYkmXCR@u#5sbJt&3Dwu`7T+}26vRu@; z%;dSsx}tkOE`7T&?Zbwve3q}mzQ|9S|A$>F+9i74iHBRBxLR@6Ne8cn%;Y*4>qiu% zR?FO)zUT1$GM~_fL!hY$A(l2V#tU}YYr|dtOuZ6S-szi}s4nNHFz;;@($a7Zo7bU` zErk1P{TJ1?H606{>mdI8P1Jv<^`-0gO25y@)Tox268`Dx%ldyIT@_#6^P6@|I9olR zT|?*GGN(1*8QAZ?t~dXi`{4QJooAk`iG5g>@%vYkl42R>PSwmc3%s_!U2khqvP${_Evf^CL zchf(;UcdD1jYE2eC!LYKSsyI!;a;$Q)srY`r^_8moxTQl6IqMhX18_DJ2P`r&Z%my z?hOq4=N0F$Yj5Ydxjx$ZdENC_`IBp9UR2!V_;WX5#hL6SGgEZWx~Bi%e?fU_MQj-V z@0Vrrs_MTV^i1j8p||_MS)Z_qx~<^`aX-SFbHS6YS8Q*scB~U%WO7JYC3N9Yp!uSc zNL^&XWtd&$!qfaSzn01W+}~&XB5UJjt<7xTg8LefW-XnC=b3aLJ*S_{fAC`6zS)}> zZ=R}iXo{5yYrS2oN`+?D8eu7l%vyp7$Q|-skDqn0Y;gwI{^u$orQS7Y@FDH)XGt zT*2<&F0<78bo~C!Jfsw)dTp_2{Iihf8}C)E+_G%b=j{vs=Q*=~`lEdI$VrT8SMMha zeWpxJ%#aspndBG3V>)S1MwfY@Kd%tCiNKN*+@7FyA*D=F?@qj!vFrD~X1zK4YggX6 z|1tN?UPH{)p4Y7Y9$l$ge6Mp}uhlQX|B2DxwLhPExc*(p`yWxM`}-dHNV_LXt1l_Y z7OUO2eS4kuW}hu*ZXbWQ@|p+Rt_hP@KgwB+G6Sih(O7({eVu(VWUr)o`%FZCP$lfb z+_1^p3^nJhIdWK3QC3?<;nc}vcW?H-Zh5xn<-P(b@!CrlHY}3vKeN+z)%pM5*2($y z9M%AB(A*K+GvQ*-S)E+Ly8(8u+75S|-)6MT_p(Xg+>NWmO5;vtIYjUOJLgAyy6`{O zRT*LXKTi0(D(Vb}vEZfo`xq83xiOhpTZcE@>h0a*Dhxqtr??kG`A(mD+y^XDS~Z`8lQj#+&I! z&6cV$t#n8T5}I)L%*v93LLVQWjQAp@`DW#g1?xJ5>;Ej(2rF3gy8h46(w)a=E^D^4 zu$$_Vl91{5OIXO}fQhWQcI}CepYLvd?R4(>dPA50yEc>=f1JU;(5pA1tHV)wBMbXo zA!T)2Pkz48ynN&9HNP4d-1TqH0&n~j3%KjjZ9A_^$o5loxf65_xNpgLq^=z-|o#FdW z@BKGp-?mD>32$rPQx{`zkIXM2~JN1hAU ztACNBBlW;rupZR;+vm_!!qdAnB<)h*VZZ;n3&XpVoqPkg3tQKEv-`J{tQ2ZjR!ck{ zZd0UJ7UB7*BkgtNhUFi2+`RQ^ca60gt9)wV4;Ii)ZV69^>{xSIsaLzER<5y`yrBcK zeeA;yCF8|y76+uyst1|vTGqUHmQvwm#1ReFKbYOP4)JmLq%j?8yHT0ANn(Mu%03EV%q-ie=poiG}b9y2byp=Gk3myc)8VoB7QXM-SdTeyMv-?cHnm;?A{vKe2s} z+wyNd7nAKr?k@CmgS!j&VZDIk&|U!eNQNKDs54yu)c+TSRi%LD_Z}2i{K>t`7WPNy zQ$bRhh?pX@YjHq%30HP`-OF})g$X9|TlmgQ)qJ{#Yk&JD?g%@rv^LP;5lIr@!y`n} z+*EZA7d~Y#(G*Hust8?yDYYY+jmPG%t#57fN$wVN(ArA|R>rq{Evm4su)7YO&2IWv zw=u-a+~{Jk#}b2D15Tzy-boGL?e!Twi{Gp{uv5HC`Oe14W;;CJwVnB8x%avA&ofUG zHoe-tV0!MFH*N!BuWi~obi@*bX4rNULan_db` zEqJ|(P4LCfNbRt#@6RRwOjs}OsGuVmaf6w0tr|n)29sPn+cyhlYW&Q#P?t+S+$r@d zch)tQA_s@noG)(GoZ|EN_}8)Ws$uut>0z0Vk}mq1e7?E!f1XW-k1BR-!3R&T`sH=EZr!7pwwU z1tjvBge_k!I~o7(<2LbA>`V>`OdKy}L}{Lx=I78FyoL)jgSBZ!9@E*6J_j5mI2af$ z8Fk|)iQf_gZR&vTV+!tM*pU~!a_hk`1%r3sw&+ggO`$K2Z8x%UJSkr*+qZFL{UaSI z>Dq-N3Jfg&-mq-BQ7T-1-?CW2OifMgo5AjV;s1g!qD)ssehyUocQab-4KtH|Qv-O8 zDo-|UW>})|wz+pj4w)oB3J=@*X|fPkP;>jA-E-Xbu-yHi_EM|Ee|6Q0DaZ2H-g^I{ z{7sVV`syi6t}^1b!G_b`9;1deua z@!Sh)(5LOydbEDwJh9DdXL{!dY!Cjo_a957Zb9UW7aKZWzRb#1N_UvKLQr0SiOIns zm~3w_fH{ulJ&@4+_`cWsO}@Yq90UP2Y)U zL?<5aUvjjq)#aVu!FbJ8Vujw9oX#jse%$Xa++3*`shaCt@`lOW`1GSstFKm1a$fZ0 z;HmBR5@z&xIY-LbftR$xADQpFV%U z%fZmNQ88g#MXq0D&(WiI(*9lGkOVK-v)I$H_-~DQx_i2IbD(@y{y)R*jJXl77ChOR z_;d=}M}b;T7Y9{siv z0acUkI-Xft6fARy>ujyDU#`)vnL!nTKlksK&|a7&h~>PDXFmm9VJq95j|q2PnZ05; zTPLd&M^Jiu2x!BiNn_xCcXfM7+2Hc~aM zM(4A=$M4A8HvDkYM~O-2UPkfVy%)B}-cXi)S$*o<hS<{&iQ$N2eUxSH)#(i zsr)b!(d4b|4cnuhyySjz#@~zQWY>Le6Wc9Xh(44a9;oH!k#C?huaWcN1l~NaQwg4P z^y-}EO#zRjx9m6h@hP20rDfHVJ{$K_j|~Jj@gLEg*tpd4WvQT3m*~UEKYpegc_qNs z0`TljytvSYi+$3+bFXq_6t5jPA&}-Ry5oSN00WbhFy_wM!wlyR#=p6A@75}7*}p%m zV`3niVjjseo^t7BY*Y|nV45X3;gQ6GrbfFr?qAElcd-3nQhcc5+4@JXPG0EiXZ9a8 zH|sUO9u@SHYxn;5P)aQ8^#Ap?zb6ZQD`vaw`gZz_K)#8Y%QyA?*A=u}yH$aG@0Vwb zmh4}8H}`4j)j02O_PyKoH?`m4FlDP^tMEASIQeUv%!%J;-zs%3(0aX_?aKB3=5%B84uGs&+uwMS*C(r8NzdPPER|#q*PxrIgHQj6TSDPEb zI~b=lBHz#r|EsV4AEz)ty~J-tHzy5Q@c;#gQ$2t zXYog|Kb!P?!e^~Na;NkXej40CS^y-N1>P>AIlp6>%;v>!y2YiY$#?7AiSgVKA0qa4 zMz!Iq09C6aQ9<>OF7|2IRBd}YnS0J3h9Zvu=t$`+owYu!t$P`n{k8pr`JEg^_!>c* z?Ugw)%6WpJ8%8u;7l?oP-n}$PW=5PLlWppv9@ZlUvKQ4KC<|01vZ$QhxS8pBoJL=P z{Fmb%p)Sl!v4;=d447F2A8jls3!Spn?x3oD-M+R}ptC+!ON7*E%-=HgbDOdCUe(lv zfB3d7H1@ZCu`a>NMfJ|ERgNrGb=SH=-|qe#VK;3@Ku6*)lT8J392ty^9f_+lm0w=$ z{nD1#AbG~c+$hM?c}i!qCFo@O#*>Z?*PjKKHOzm{ztHwzSGeKXfRB@XLP6U&+S=Bx z@_Xy0rR}OMCHM(^R8`@HzDq{6w@wJP_JW4?7PoLP*|}BeUhRR~(+{y8a!8oN30a|YIek}q{D%!|_qNXo zx(XV4tGwW-+>1W+CepxMyl}eYtmh(MK26wXDEG5D(A@V!6OX`*Cx|T@D*NReY{3mm z&`PSA4F8zTCa#-(%`VYu=52uzX7DLFpbh5@2Yv`JT+gl9;j|Le^UhVEzYRz`MbXsBkaTk~3~&aY-l%q;J| zpcC`|OcC3i_voEg zh_d4@HQjvIdE7xZn=v5`wYhhS>p$91upsD9*IMPUzqRXp!DDsX`Sh<^?~|VD`e)av zw4<)icl@-d(>C5d>(rCZ3!hm(i{&~){I3{ZEUWjcow>;XWjpo9%Bfje2YGbv^x_bI)pEw@)7i&!4YPQJZ;!4?T6K$C0DL3>S zbU!>(@kMEP(%d)8b7y(mtzD9ChgYQ>vKI^Ly#wW?XEP(M&~xJnKEt7 z-upVo;zF-ZjCl6zNziL(Z z?5<|JTXWJ*rB6R5Zn?2x!il@8KcrV8c2rEi)A(rGlGYinYRBdK)!06RmeX8u6uPro zD?wajLpNLe&N*I@p{p!4bRJy|6RC}F6PMA0Ztk8KnUe6V@!ZmrS^Z}ooyZQqDt!H7 zOo`c~fJu_z4dyPULGBrwEVSxgFZyQiJXAtq`7G_nW}KBtq0fIDeJ)z}?Cs;tiS7)$ zEPhOOlrT(Up6CC5zVd|34;QbbJ}+u@II{T3g^-|v^^bD?d|Z@$C-BswJ&&%$9$j_a zT5qP2;PTI}*DpOPuOC<)+PCP6#GFe>*Lyd_-6>L2e3lTm*}G%=pP7G9+iMeBSiXNy z$gRF;m$b{|VNvaSiG*gQ1_pr(VN4iX8ICWIalU{5K=Sd{_*wgP+qUL924#Gh{_||} zH%*>s#T3lV)$E4TPx%&dXq$XLYq9m@i!`r?u225|OWG5*0cjlZ)Bb5aPv5(_eBH?Z zl{NmnxBa)MpbM6z?`Cw|zx;7Q^Yy!$)ulEM%D%6ZR$sKi4|c?-~az__VUIEhhO_qU+#E_t*Jrb^lFF3tqGMI7j`LytQ3piux54af-Oh=H@0={ z;?<4K_$exWWVzVJYu~-XOEMF>`RlJ}tr5}HJSx6ng=p7=P!<+ZE|r5O!jqT(w-#pN zoT;FtFwt0E)wukf?e{zH_fEF7EPpnyf7&#@ho6@2eN+;2)T=ea-O4v9`sBje+x&GK zR#bG{DmDAK(O<%DTZ_8ZfdfhjFO5nb&Gufdb=Wrk*tOYf>qGu@^I0(cU3<#ey31?U z^L@_84jo#!bnUa89`2v5`_0XNFZq5=Lo4f=@KqTtb|!}hoPq@r^J1#{c-S8 z!4|E#`|YP>K27Sr&=wr2ed9;;k@Y8D>71tFGyNZ@Qwidv58kBU#%|m}Rhcz#iD30H!m zYuv^4>^lP5+th;RjXQSUW-!}ueAALf!RtJ|7gbtCmy zpd0hF_V@|yixVGROKNoyi-xE0R zx|(DEmPgMlvdmX7u{0c5ETr%wbN7FNDA?iKcyP4sw@5c{y8lF7w~*S5m%u@#~g#g4U25-Qq;b7 zP5JrzpV0n0D_5^cj`(uZvn3=W^@-Kt=5K1Qx0P}-1J^PANncPDWRbn;)VE73YA4J~ z(-(bPlCk$@)#~kUy;S?FuRN@pH-F=nml3YbuJg|w%1ik?U8AK#?cd6|4`&xBaGeup z_iO(>bK+IcW77VrVQksAUg=uqxA4j8^H$hZ)M!;IWp01)N>Yu&cl6sOyv8+ z?;KKpaJBdRj2%{&J;J;f?S7Q8E-94r?CPcZQ`Igu$++}eV%MRIIpNm($`tC{`|a+)~DQJ{#X8R z{PHd?M^$jI606YHvd7j_Jd}>#(==xLI<<21%H9vAYfk?!R~G837Uel#DKkY-?Cg&x zq08SVnVBw1(3GgLmfv>O6Z^hyj?UlpPn$Xd+`@I0OtQiif?XCb-(#p*Q+s9R zr5hUDS6&`H9a+D8wu4^Yo%f&FURHi{{`PC{yZ0Z9E;}t>UB9`{eBP8>liqKWx0<0` zGV6cpjP_ldns2e#$lKUWJ;BmGNomrmiQz{7e~UUZ$R64L|3hK-`{#U%%bMPGDThjw zh$;s&-+DdQOi)~1s_*>Vy`0DQS?{-eF!9Z`I-dSbi?=VE&B$CDbLMuaXYE7-r=6L7oX z3a{kqMcwz^-Zkd@kvs6K-@E>Xyj1nyj;DV2P73!Hmlt+DUhP>weT(5y(-wWZt1OHv0cdII|`s@Y1g}$G~^A>3(9AA1q(61+`{Z&1a z+24XXtIO;+v#Vw})wKNc@5N%@+DLQMX@K*tpE9V?Q*>^N7&QLmjE>X1!2| z))VYb}2-P)f()e!e9uzKQ7miL~1@=UJ`si+KsbPo-MVAJl!d+DTFMLvbaK zRcL!y(*z-&WamHOjS^dQWjFoU@pR<@3yC%pS@Rv12Z{{@ey9$)6(?PaQNl*0|xzwbyPBjgvO@Y}vELCuiQp2J?iO-`9#d z6$?!QP1{DWys@`Qz4!lX_-1>{&5LBt3M+_IEGe10`D1g0gfUzFNe@=eGC?o-=z>>` z>Bn#6DSy415m?XsA-7bb%&Y!eqbysgeVPP+-U|o5yVZ|pEN?726}|o4-}Hub`>us$ za>w%y7tK#8e7m}0MH`=$`Zrkc3_lhW8cpYEgeC+YOh9&C^Gz^rp z!u8CvcI0RE{WfcC0*y;H7P>q1@6Fr3KITPP#12EnIKFM)sx(C*5Kv8H{E)!Ye%*MBb%5RmX>^0_{}s8S~GPq;6C zgn71#Hfto<_)a&F@qXM%|J_QbKjc35^l151#q}3zpZr+!o=2Q{=ESL$_oLsQSt`F& z^Y_-DN6LFF83hiMEb1-FcrPJnU^e^TrS6<5m%8Jx)iAA2?g`XhC%4u|AINi$G*F$hQ$GFAOv z11pwix+^8N9NFi(x29mdmVWrp1=4;zPgSf|#;Hv;iG9~{^OB&voq_-dk5WR%{-7H= z74C@wViw>t0()c_|MIn{PVP`OY85;^XQk0a1If+^onVa_I>pLcUEWNbd~(9Xv`IqB zM+{_lK4h7sX2p22chiFB{?E4M&h~RHXm^MZu61zu-FToy(O?>+Jm_UpRy)1o{n<;6 z7Z0Xv+;ZtdB(rjbeIkR<8^*?o>IysO$eY*;AFX-hbTd~up3wvB4hF`SFSkpY; z68;DzRQ=t#C9!kn)R}GjtN*-Up9NlXGmncYVVAAwU5;J`rpJv9iiZ!a`hQj-NU=gH z(WZp^g~2qI2a1gwm)Iu0zI5B%M?I(C@i2I#2b^#@eHeVUbKd!Rp+v#Jki#Qyd$*kJ znpG|VwOjXw=a#A%eotL=V?^=2JxA@=9+4=UmPvs=iGOXkE;)Wv^+$}^y6)VW zLHB=46g}~kTrz=0$K}$^dsi;3+T`2WC+)jdm!B(jVOUJNkn?NJU8lrXl*`Me$TpR# z+P8Tvn)Yk6>Yr6vj={0EsVV$x_vrD;&AAs?zEyVGtU3er6Nax?zT7C;UHjB&`{6^q zoF6w|T$*#Qa_L*Ooa`5~e(~JCUViM%%sf6duR7EJ_d+#4dwY2HeS3ZCcHkA`S0M|T z6c||AR21^N|H?BwdX3wQvThU zKUc2k|I5U8HjBKvR$FRv*DUg{`+s?3xpEkr+w@6p-vUnY2g}~dImEsDP@L^QhHYC^ z6$LqZG(gchN9@QyU9A)Mj&=TRGS1q6`@8T5yP}$FGbfo2KWt zHk{d;e%9^9uh<=*+)8*F4HO)NCU9+#*C@*Uc6HaRyQe*m2OWAIY7u#*z^vOUCA#R- z=~)F{<*}hBuZwb+PJ23Ss;suAw(x`dvA*sb?rSexGvlvy8Na%rVlStclKxbEdBJzn=k)s#PJ8joYNq7$Z3lPj-b!bzt`z%URQcJChIs6uk6Dx0@2QxtDswM3ICIzX{`PB&JWnVn zXzEHVe6@t@P1f#Xzh$0#{+l1L$3bYV&)P>zeBRm}>fBN_X=inoS>bB?b1_S*6kWMD zg-kHjpS0OVDEnOG?5Tpj@1D$8{VHEL)nz(&(vG8%)9XEM@6mf({jZv1=B$bD?_JdL zKRtPyd8Y8ji0xB9zUlHku9rRI@r<~#TkniQ*&pU?U~Igo2C5A@-LBPW*cL_yPR>v9 zxF3}_Ic00*?I7cAX-m}7KCch{5z#ntA8(~(J6A>Y_PWC#;@>%Le{(ydneC^;15NdW zobA8vG#=PhYuK25LAsj%!=%5qYXZ}+-n#kvqO|3o-Os!Ib?zGd^$b-&b> z74F@*?_W{u-UZULUHkO)I-QjFU zZhnn3w z&#C-;I4x3bO3b_Y$FFEC$#|&G^JI}|b@%%D=kzNCgKwQxzpXMq<&)RB#>c!%EqBkD zEjBe#IgPX;zo#7|5Yri>jcf-=t7drFx=C0!TUL!d>W!t~NkNQ>*IKFJx z;(x25l{xP>Utg>0%VWh$dORnqJ#?+)Ow{KqX#-@yxV#`mOcu$iDqe(ogPAxV$m#@~)SE?>mI)or_x` z4jrG6_FWd`sVuzQzj)T3rtNJeys@wmh_%XJrXBwD|IhCa@lR`89QyLl--X*8 zOSUSP{8x*L6?y(Xv2jjZa-X9&OnVQwr&n;&}RoBir zWp*%q$=X)y{xZd>7ZqGl1|K$r^Gv<}_DG!KthFCi_*v`b2t4lRj%aszvP`b`oXvJC z4W8SRx8BS)N?xJVD51Wq@Qc8?nIG#k&RN>3|9`%6rq^eera8{{%(~;Gwp(OBkJ+4+ z^X1Yhp13Nf-4)eeznj#GB=|1Yn5y#rtwUU0%IeVBW-0Fe)=!?wJa~NnUF(}?>}O_N z>ARP==Sj%QyJwDvoScx@^e<)cqrMq^=bZl;$e$6u_)RT0DLz^9GE>vV>9RLUUa!BB z=J(@~>b1Dl%^w!D^K$g?HvZE;w{d0Ol5E3-${(zi7E)??x?&!2-_n$(?bYsHb)+tg zVeyOjy+62;z3QwkKM|cP^z^KgV!fA-_KN9e4q7HMGdUzI;nYacs5sWs7%g$J^{>yn zbC=hsefOFmSnPbzZ<@AQ@`km}Gi839KVU9kxmaVjf2PWGu9g0;&L_;Y2=tp_5fON- zS*ANcs*;)Y$~TU>Tkq_T6e~=~Pc^r`p1v&TTFxZ5pzpSi%?M&sJu#u9~-B=fE_Me_@@0(Q2`Ub8B5zEn6rubHSaaoZp@g)3Th)j^4~l z<#MrFo>Ju0m~x`K%gI7YD|da4|HsX5FZ=v;cCKWV^>2Amb$O22#(1N;Y3Dp*x3F59 z=$dc&Z}Ntr(NJN*cHw1R=Pt9lnx3`gYF+Z~5$m7YwDz@zuKuxSr&=fdkyT#}86a7y zFX7CVwew!n{s!y(2bxzjpJm;*N^X!?#lR%o)G%klm$I*A%7yJ7mz0$>Zl5ts&?{pw z%$?62DfugD!tdIH{m<)ODP^8`>J(DDJ=W#Rmhg{!&!=zE61ltUvYUN(&{{ zA9qw2zRi{N(01d5E$>8ZlN4u8HW7Sbw&<;h{<-GKd+qDL-#4CcJ*j$Wao@6U)v;SW zg4O;V3V6`wQPp~*Q}x{&r7BmUl}umF)LPf?fB&`U&F_tOo|qTDepe!V;zsZ9+I#zw ze^2@UY2SVEXD4lbKfE*bp-p|9-u~5AWltOKx}93+;JN#^gXP)i7QecX1NlcoyYfP0 zJ#u6A6q+qw&AafZ+`DZ&mB)9kH~vsQYeRVA8iZuU0ue`ggI zyOqZaT`ZVWBlq#}=9KJ2W~O8(hx)_kyZztajJmXa4}-Fb*~e6Vv7kFvQ?@ML#xJ8h zW%7=OPX{}t{qoQ11=d}!Xf3)I{H9s6x81tm`e$b7*UF?At!=gfpSb+)e+^vG?^=EH;fByB!Qb9B zzB$&FWwXEX%hmt;7O8IDtD>#b)n5EI_r~Yb_r>Z;gccr1`L|KDWL}ADb?oD}-@LQK zWbb}pE&pg#|Ju&|>VsS9cWfl&np4@HZ(qup)ch-@?(NJZao?3ILgZQVPu~3|)_FFnVqwB>{niO?<>#zdSsI3zq=AsW^+ADII%+Wa9_^j zM{D*LOFy=|b^4_3V*%U$i@%?nGw<%duN|vZR%zcB`O&y(_MPxtkK2D{&93C0`>D;u zrgEO~Cg%X;*!{I7fx1;Kv`Kou3{1Qu3WmTI-C2bJKMWpMSmn zrCT4@Oc$MrnmrNEe75R)bVB=DrySQy*>FYnM|X z2MtnYZM@AdIot4e&l0=8B0(o@cQ(!}@=MH^`!eN{`1OnKCXb%_Y6ge< zSqDlpr#zJZFh@2h%wZ*va2DR*Iy zX~nHo+4?6rx{IEcyYf_6sk1%#bzXV#`w-s*C|Kfg|v3cq``GX~k7aJ*FI(Dh# z@|*)R1S;6gh1P93=<+}Uv{25#q%qTZex29(TRUx+@;0Zvlw{mndpP90Me{CD=MX$z z!yq8R$ds_Fm%&8AD0}MKw|?894|~6 zZNKfhyRT^B?Zk)2T7KMo5oGp$Pm!fdVzl%1E9p1(?K4h0S5h3nmOb&~{yX8VX~)$I z{#^;0RJg)zy*1C2`3)>RXJTvbuC1OWz58E2(>A$TJdm*qDV8rcUO(HS@GUgPMmyjVeziN^DJ-nWaRx=nR@BY&AiDQJdYK9;Ny&!6nm9Ba~hwaJ+o7O(s^2Ch#isXo*2^r85ZhZ!?=Y>iN;yg9ow z;#Gkjqei`(&Z3t- zewEArf7+R_v-j$YrYg6-2A?Y{9qMOoK9Mg~yXN!6)toBe#di${cBn1b9%s(X_G-tB z?W>LYkDTV{tUcXzXJ`1->8ool@T#{J3C%sh>YVb&R=)PK%e-&#I}4|pui$QbK4;nG?aAUgz%5M`TPHxeG1a-WO4LZdMQw7orpGkKuFBnUrFq= z2$$OFJ04R#X6J^8GCy=kNZ~wD_3!uH*64lQP0L=rUB7lBE7K+L;hK-T7>*do=9Nnr zM!H2^p6~N#&VpqOw{m7hKH%W!iD%lh+rGAZrR>Ie8(DVe{`n@90lrmBLYb*RTSECl z0Ixtr3X@ydc{a9P(#E}Czg@iIo@XTj86j#s$a0{>x#_a-gI-q$mJ!wF3iFvY$hLdSc4l@K66D z18#d7ys3%r|GBz-=d0GBlWT?dtUo1fC3x6e(ezYXl>Cxq8UAsp(uXZA>fQ!vrJnJ0 zZhhR3JO=yg$7Mbf*i{P-&Y(e3^fB0gZGL67{;&FqW{RsT8d@60WG*d@vzQa!sr1+URis`=B_#OTa0sJjLp>t8;x$AKWUm%%CSm!Z{K3w18gh? zjLDl{>hC?_)^zV;Y`s7P>_AirL#8U5L@%QWrt-ITtqyCcNse27t!VO{9coUCCS5rq z)N;lt`LTG#gpI;=suxm_kk9dA?kZUov?!%7*J!n+ba2q3=3cK&{$+e6F85nrIWWCpWb`?3r~Z*McdYh{C+a$q|1#423N%RYlkjq z>lEZ7+kc!d*0P^!XtdIM_IA}7Wl3YFr2Cr|B~WrJ}BS+_uFlaOfP|!5UX92 z1B^N&l!7HTo|(DI^zMpn8b@rCQd$;YSiSsIRh3GV<;gb!9NAOY8sa*p-qGN$`j?V- zd)v!nOZGiB5ttUYfJGIY_=RUQI4Eq`x^=EmDp&JCiCmtl*QJXOfO4kE=J{+o#h;D_ zojrTvj?A6hSsrSCCO#>uyYRUQ4>IR>yt8CbqFG}O(`t74D{kvYyXBd%UA zHzFx5b=kXlvd4clWkE6+1IvS4ZwcmPr-V6vE=l%pt{7(8hcJPXE$Gg|7LFHhrI#sR zsS{v^3W1EaRbp5+Tdq`W1-K#rSGPVTOjUo@%wF@^>z+M#mNjSF-1n~y>%SU=+ip4(}9w}%{GxC%e>|M_fxEvDM6>-Q$@v(>!9wIV$wzg0_H9UCPBcNgsp zyzCxjb^^AH%wQqsi;dUcew)gDmyg?A?Z|nz>6Ouo)#eYMY2`~A|5_qv2NJ!=d7)C2z8EnFrw+qeFu ztC`o!qpyD*%-Zh1LU=(GBpp;}alY92((PM2qGq*9UG13{Bdi$cnU%!pl(ul=M{b*6 z;uXs8?5E0FL+?^fLt3Xq2w&~U&)X~Fwt(x(sWzwq_5 z$XYF+k!x<4R8etjbHu&R(+w}2&&>*6GTGzJs&L6;f#NnxS4qtB`RKG_(T0V^CCv+M zm;P7)o+tt}sa{}ayaNZ--=2^RUe;~ioUudE?ZvgFUQE851MNPkP4-Z^E5zjauGCw_ zs7h#p)h3pz{MzvDvTLEo+ivu&NdWB+0A&=11SR1Mx6|+PNUV6AbZ^}$n@!&(6gTEa z2Ht(~lk2#7u6tCHq}?ap{_P8e)=z(TE8Oqw+-GlBxQ1#f95+}*Yv1Q zVVWeJ>Ue(sncUlEbGzQy`7tNj7JXg-S|kk45vEK`jR&q>D?2qslZVY&w=$&c>$TTz z7Y&j&^-Kv~Bvrr@@$9euw5&M|%^MX_W<-*MHLt)kj*`HI{L8sYUnbaXoA~nU^Gj{2 zX<=zn=K^YTIA1`Uc@7D41Q{;#9*ntnqTln6#=|QUr*jEGd_V>fg!>t0 zYjSBD`i4F*7vU`|9h3Vu4;o<(QB6Xt3S2*9r@tv z(R)bnh3fV!u67o*JCLn^y#Bf>RA!Yu4#zDxiVno6(z| zIY*aY?V6B(=Jk}dYC8*kTU=CEcB*pBY&~{N|AT^fMY7iP%HTV{et9q-uJ4-_YR*_K z18YY+FmSvuWVD@Upt@2zf<-6xS!$c!+*NP5P5S?4BIT+ji{dqRyN6X4xC?)}yW>=F z|8DLOq;N4~tTn$IAy?;^Uvwxiy44|bcc4W>k~9c7esoXl)XJ3m zhE7TMgLYlEiGTQG*;@~9ox>~lJ^X0)!}(g(QqKAXlWL5*88A$Y8Yy&lCxq1XAr@Huc^4;QzI2G>2u6h`>N*`|1oQ8XLua`Z)<5&wy zui#>Ufy0K0@$a`?woc7kyE*>(FPO`r30k6Cz?8SYeD(vD1wTOz34f*srPA~NGDSfe z&tRPmZ45K=Oac@#RX99Yu7=;P{_S+Suf-v#?Mc~g4tAsJu5HJ&FRpN?>w4i73@+#W z6+zQRsI!5K)08~&=AO9Mby+yLqI^ZlT+8`~_+-s}Cz-kHbZM^HzkK0@Enh#}^4O*- z{r~j-KL@^kbqW8;Br|JUz3|p6IUjj$mu}j(`*UOJZ|>gLvb)4OU#*^fCHiii4)YDv?>Gb~nf0ncFv5TEQSz_|f z;`)!vlqI=quKjsS5NaRHr?A!$3K5?l~X-)P5tHT z8CE9_KMee;sXl3T{QXZiM0n>;-rZ$hu`s^$+Nl|{4?Z^+FWjS&RVfl)93=L`W&WRk z%ah-`t>Nj>Q}wO6HOJ~H-~W~mht_Qf@8>^%WBQ!Ra$&EtRr+^Qe|%B|--(#e!};Q4 zHWzqJ!bKxUSy2}9pw#JA-=|q`oPzI1F4&jGk$cXN&356c*AL|5Wa4D@JlPq3$wt;^ zs+oKF&E@R-fA5niHQs;ko`=Ho@cZ$JhAdO&&GNnTs{j1kfScu$Vl`Obyi zr~9XSZ1lVlH|=a}=-dDAinni**KvRMUbIF^@KJ+n*@w^OE$L>H4mI1`ef_>c^3a-A zOw?Nv$&)Glm2WiH9`@l$ieAmNs{YcJ6}#8H`m^*jcwX`Drak>Wcj9;ojUCjcHLg&o zE)V5fFY`L`OQ6eyO*3yz2n;^?@PFs8JyMF_9loE;%TG&fT@}yq_v-l`@7o1W;xF29 z2PA}qMLmg;k7i!!AingS)xUfDi@8lTJ@Z0jeSUs=;JL*rd*TMMvrAkqe=;#hOOo}u zY873wQ=u(-PU+8f1@}99SMSwn?m2TpU+L`}i^78ZAcM@=p0hhtcdYG6FHY`@l++^#sv#z}q?~QPB)nbJ^ru@}z;=z3z1d1v!X|n7 zO<@>6+VY1JI`**C2*KJ2|qlhb6v(x$nA^Y>RQ z+w$w(%Oj$BS3_;H&RO&7^7yP}PTFA+{m%N_o}Y=Eb%edv&Ac2GwB>_1ThYa?y+^P6 zKNsKAq51Y%xklc6-YUCyyZkHO&D<_=KTSl*rR-UNjj2ec^>^8*Np{^^ZhtryQ}@&3 zz?FY}*G_c$^S|?*<8s^QmP?SGne^T8wN5juSN%G^$Y|y}{fnX9DU%XYmT2=pZp+)K zXz=83aZX6ZoG2bpW71iD-_DX%Mt44^UaB%av~V5rlHst>J(X|g^atxtk)6b_jc1PS z**SYB+!78r^HNdqnC=^{BtMT8wBEdr ztNMD4%QvcKU4A0E$Mm1vwG&@M%W6)|y;pi|*^VzuZoM&`X}Cm2>_sSe)%}-r*wg+0ROiX4zN_pK9 zV5+tM_Ro7YR$kNRXaznv&T05>M?)#Vmejm@ z@2}s9pG;C_EU>@1Ld40(Jw59B0s z{-*eiG5u?y`2@yq;M(bNOT(?diE}c(1Y}8Uu=&$uBf~4aU5r~rzxuItgM{I{?_1J0 zzIm>nJmvXT&k0jMZCfz+^FpnrGyJ{|KR+xy#xVKuY<0sMYZnC<+r~tX=o7#?K=Yzt7*S`mZ{va8HlV zk^kALTrO3?km;+_9`{=JhGR_RWtcshZe2RHl&9OSlw;+EQzx$8%i7UtY?JZ)<%{T+ zB_i^F+?!>ReBZS@ngws=ZOZu;bkVQ<+U&L4t8T9g`Lx4bcHQ%zlHRlXLQNvROcg3q zp1t4YVP3|g`L`tZt&~xOtU-P#>Fp`Yt6KEvLe8W%y}RE%`tr0|d3vXw5^(-_MZn?N z{kWU+9;L6=S@|(sSv@yDsWoF(rr+!v`cn4Z=}Q!M{qM#lPC z0FOTP7&AH7&+au&y?QmUWS-ud4Kuzj+P?SV)^70+bC2|yT%4hIujf;nbkY;WT_K(e zGR-U|+AZIub3;CoiOci6ZAu0I?mI{3#=5MJNz6E8Viw@xDyyXEC;au%^2d^C%l>ZT z@O`^v;_>|B^;6o+%}j6keKgu`Ua)PChSkK*J!Us1-!pa6*`qF&G}FhmKcb`MQC!oD zEa!}k?YniI?*;xVWpk2l*~@j<@6uoOMLrfACpZN61mx~^JrL8nZ|V4RZEv1-XOfSYZB)c-9!J}b_#^v&lTSpac6hYrZ4-aaVt4V zR*3aq$XLcSQ%UN?r(;V#d<{(ZN?xoJuv}a}{qNj7rky(q_n((ua_}bq&DY;|?LU6n zmwWCyrJi>e12@gt&Y@Zxa$x>OtrHLL^{!%G+1tH;#@np>-II3weCR%HzroIL7wU5U zyM7Tm|LTF~mo5>HE4O=>+*Rt7vF1K|XPWDd;>TvSzwS)i5y`e!_kNvBVOH9^eOoVY zE!KKbHM#S}tW1yT8TaguZK&0k{^ibmST!R${A1qfqf^6O^Kxb-8gwYifUk3&C&IYb z6xLJpdbR8bc&O9~t)qBQ-m1t>^O1l3-b=?su4mL(t8Wi|$i7iN+56qLt&_jsY<*bU z@<=S_VEy90J5Q}%%hgU^Ub*1bEVGwf+wJD}d4BkJ$9`*k)aF+&+VsDP>3=@%zjyoe zH+{F`dbbtFXWaOFy1MX2;--IZh5sZgzSlk3^HJkisZL*a()BtyF-M*Ccl!A^7u7st zTiEQqpU?7f!-a$IU6y|?wh;U*Ue|Iy@&D~fSMO|DdF9=WKMOMjBR9U>eCNu89nZxl z{Ej>La`&OAe%U+i-wzwd=Xnc%G5xIZKigmG#CpkFid!=O9r8^{JksYqfAJiNrF>Wa zv*i4G_$RIH*y10TmN7p}v2E4}y=PzBa(%0jjm>1O{T8L^m%MED|NPacYks|DeTdp4 z6=g-?kTQrg+p3Uggo%i&5iIG-m`+iWPzVV|oY`DuAG~D&( z>l8UpPDGb`_XMXq%5H8t)1p@O%}H4+!0~$Gjs7CV%HUI1re5}&a*QoO*>@{^-m5OY z>(!A5{+|6Dpee31`wpg?_C0NZOq!M4o+$Ox{hNb(w@8r9`kWI6*CehTUO5xK`1!_V z%Q;GiPbsUb>}4@h+q?YlPf^hH*ujMNFP%TAfM&mzovC~H%KFw`PjJ2Imo9o+S?}*7 z{)JXNkz04U{QNAor8eRS@6ltnO%4%RDd3f<>;eKDEZeqi3tr}vXdqY7U)8XJecrYF z%WoUcO8c=H+--BteDitB^pqCYou76q{Yw8bVbAYZORLXsl4U#7zA-#ICA;QVl*y(V zH>aq-&nI3iHw($-WH65f~J zcAgR9H7T`uvolVfKdOQ67R!dSX^jiYw;Xghby#pi?TNrE=I;ONJw6nCb;zq#{!ndh zUK=d=g_TK#(KddPxE1n26vCaLv4xe}7p^_5s<3i*)mGO-@bTndW-9& zYb&pxy1dOJUdX-GCib!X_C*_|x=MCAO9?PA_4|S*l_H-{b&d`$II?=m`3l}w+g(ns z6}}mLG9W^8k9Ai0DQoeHPR;gNCsm^onVDuV1Wr1*E#+~&=5%&eb@f@y$w@`)9+$?n z-*cJ1-t1*XXH-b6YJmOK%W;!8SiF(Hf3>`ff0fT(uDe<*pG#HM?>NP;>-zZ34bAm| zx%Us|9=s~H=g9pRdC8t}7nN36h8?qyj*pKGUjOgv(wi=KwJw%??BI9xjdlB;!SPgn z?;}G=v;K8*Q&^b#L33f-Z-?uZSnJ%GAz&{Zd+OQT_r{k}u76+hPGfpyp^(sI;lsJV zkpNt*HESMnbFCm!<~A=FC%DOoID$S}(j^b$HsF z8UCNU*O&70Ok?}^@adBJKHGlboi>YEW(&@3TBWS6Es$kXw&hJk`=+woc@}fc1eaI09b*s6|Fuev{o#e3U$R zRBYJzqU2thjl`<%qzTe}J=Qf-3!=B|{$bd@Xq}+Zj>jAa+b2#uZ8>p=_Vnc`g~BK1 z{xwZ$|7J4x?*u8HX*uWqZT7WD{UN>gQ%ghl`mIymWI6gusapOjn7WSJG5qb8!))pQ zO1{5KwmNp~!_~Gq4i8QWT}Zy%%c7obH)YHLk10ExxZmb%G~u z>mnuPq_|V>lCSqHc1nL>_(J^Kt=&#>f7qArx$kr5&$G>*cRG%2TDI?1zdvfvdZnN`$51%~tY8zwzwzf|Z zziOQ)zwqaa(bKj4YG`b?tfyq&#g9w;L$Z#S^vCv0+P5lbeuLbS?OV3LzBbo-?%ndK z|MTuY~?bC zpKdk(tG((jSJ8L7@H4w#?|&Hbt80ldQvle+2qVE_j*2*-=5Q3sJQ>b_h)JIzuc2bZ9TG-{nVRjsy7x`C#meZd+TS< z>d^l-uYSDbypS?Sz#t{6ddJM2yC2V3zN**oCi}uA=f8E`;7gkpx7%#P#@lD^)E`Z& ze?Ong`riE==iG~JPO8eDxXb_i<^33^Nz#2f|LzO78fG85_~^^CEdjyY;_fX$#ha4S z9wfdlFT8a3xxK~r|EuPn{e5~x8INv^Mry$ie`Egq?G7$hoYkyPZwoGOlx};x|7Xe* zu`_?q+?^P6smZT0+kE#)!^rHWIcq0AUfno5C`$G9KZ^(bVWEqE2S@+h*7YZ9%R&n? zmhBglkFu+$1h+c7E}8o!`QWT2{42O_)IDLB_5XFmZmmRK-N6+Lm}lo{xu@Ol{Kuah z>@Cioa_WekPSNDM?q%D)G_LQNZ%}#Lcj-<)cK$U{pDmZZ>@xn7GCy&3OLs>3#>dHg zu5IfCjaEG7iMjh`!tUY|CI7|BpO{!T4MlEq1#4pAp-yoxJL&Ze?>``F3{Okt;EO zjQ`B8{lCZcd%>k0F9icqdN?oqs|w_s_%AqZ{hPZ#j|PQbIvf2z_Rp^=T1z9_7l%H~ z-7vfJ(*65kXHO`2m8D_Gqq^SHV_2a9U`j7n!2-oS2y#23AGq5AXEmCxn z_wJP@&Y#S?UR>Yzc?sKhcDJtzPcPQa?A)yS_0Bw*=OOdurrpU9x?);-VVi^I?3$U* z-jzRVWhzCq7u?}tQc7}`{T16Ib?UVB54&tTu88UaPEw0Yd=`4C^zZd zyRxut&z?=2JU6)fosHCihpBW6B!t;`zjyuD}sKK-7YY<_%iXMX&4mnV0*HJ{vFv1_lhis;tQ{qpzD=Z9*Q z%HLKGeVetp`p8+XxF1gEmjC>jIaBgPtzqB&KJzwNuTy8%<-OmhYwvxf3d7mc~rKP#p6uXOLHb^1Cky)*yY+*Sz{(EVETN96AFE6o|V zPIcb=56Wx8>Ns_m9*ILd0YO;*^_r_zP_gUKlhnh zK1b1oslPcVO~3ck(6re1T<9q#^{S8T%~fs5H?%I6eN5(aoh9gWyKwK_ie0<6xBt>r zRC&I*H{h}UwYuVuqKQ^tcRpRX(EHEb_xJyNJhN3#_2)xg1FNT^EuRjFlzok#Q9IZ2 zg;T-RSnJS)4;v<$$*RlmK4WElB;t~3j)E*lk35s}pFUZ8uS=Op2OMO@KbM6*o2V|S zxH13XOyxb5@G1K5wTB<)o-kon>uycC{ylB_gJvPQ`fu*uE2Gsb`L=a>J6xP1v&G2$ z=D!WBKaBNW|9BSZbgt>eR7i_w((N{_5Yme&2N8 z7sKTV!KP&`ii-lHf9jU0ALb8R+U`(*)_Pf9+>_5b?{&_;pl0sckMC+s z*%t;Ge%)Vk%DN@)PUZKXU$ui*_N=y;@8WBId11|oX%Ei0a(5RV3k?ix?4AF+z<2g$ zo6HKY5(l-_6JmZXlwo!2xubG@vhx0?kv2mA0@bv%l9TvP6S;EYy z%BblmVa)R}-ZE*1k%`;vIX)&PVg4Z|Yv*pg^w#0!@46?S(`#oxdbKCgep=Z6g_|aK z{GIdV=I={2AlqN5A=ZeE9-rhw2H}d^O+`i_U);LRJ)@6=i66v zKdGL@DPepfdW~Uo+7?M8iRSu)(iZhowjN49TmNX4@`hsXtvB<}8@@kZX=ZP^a+i$j zqxrmz&x@{Ae);)4q;jjhB#&v}l}slATXUzE3Nf1=Ht6?e-3q!A%yFn?ueRQcgJsf@ z9?n1QG}(BHzp78XlA8T)_AK6WATJAg@2aukc6}?OxSQ8D^AlT`mxI(EFWzS4iUsu_mYlWYk^4atZvOWk z7jNDw3h#;tUS<_#v*n@L9<5`pdNNx%BX9FT)qQ;Sr{tHV%$Io^Uz*+1W4Mq$N4P=yp2d5G0DcaJ#*OL*)0WM?w=dD^+g&D8 z@YoV~?A76cr!d3ix1Qe_uKaJ|^mw%{F882zSkJ$<^n#M(Qt}619bf0FyuzddvM{VM z5!62Sy;k}3!Zi_@k6KTSD4FRZa&YYmCq~8 zn=)H~rQ_Lw88ha*u6XIUwKwChO)Jku54X%E*UpDpFW;-ZYMs!EwU64auYC33?K!*K z7q{2U+T`G0?R)6ahWeWD`!{>Tn=Wh>RFyncFkf?e`-!Eiw;0Xc=33&K$GvV_#tV<> zo>Q+?ezoX(Bo)iCK6!P=0q~sK15UvU$(Jz}%iK{zpE=ybdT3kQx|QcQ)Yhh-ne+0Q zgRb`fmICLkkNX%7KRt7g`QkdM#gC4ye7kbe3M;$)4}W~zzk_EFr^o6)PY)e&jsLf% zu5bPJx^czSnl!j_g?cmVGR-*Q!EpR{@N{ghSR>`S5d zV*gii9XFaZxy+(E*XhZpHAZiKUd{_Vee+Fa&bjv8<&S5uPkVFXZ+dj7uIs#o9~-aE z-nWQJ@ryd&#?2+?blf*9X7U6|_(A5n4{(5@uvbL^cW=<~>D?KiJ=W7^Z8TLjHJn{v z+j5~%Vy}9_)2%;Z>K<+Rbg1oK9lvDqtm*tOXOt6g0^9hI89`(us!xaKyx{%YO(ZQTU%{|7bSn+u!o|Cu9XuC#HD zC+n8`eJa8+>AIcHPko&ZT_`&@o&A#kr;4>p+}G8fKJD&Chk;E~wms+Fyz1Qp*d zUow|52$DS$dN^L}e3^z=jJPSkiIe^4wpp7ERaLEStWf!#qTYJ(n!T2tW$o*0Yo!nG zmD;D7Dc9|O>G+EO3uYZxOgORSTfyg&^6=>gzi@K=d>ylG`t>w zSHT9|qRHNc2a5JcK00yV2;Aux)>_@63^#lQ!*oV(~mBRq<;4pSre- z3x0(x|7G{|`@1-eJeLzGpFSv^=GEeZoVBW8unBYd%Y&b~)}P!?mV8VT;59$OaThx8 z5(rseJ!6mb_1fx54%=RB6mg%X=5bk@iA!eD#&9JOMU^-2CV9E+Wy$<1^S6-FkKMDjp-p?AalTmer5$Z}rePGST_& zGgZZT{)gTrryjq~cJzwUWKWf`t-h8 zQpg5qRu)z>`11a(`kFfdSEb?0cGTQF-b9CmP+CXy~G2b8V4}5;E z*tUdU!rPkvO2lQKH6KFiZ@sn4R1f8m@KE!B>(~3iQMvIZhv~Xsd$#E6e))UZ zea-))zklsMHr?)-NY1K#{l%BJW^~^@`Jwsh3kCBXCFk${?>sDiXw?+qv%kXv3YV%( zuhVdE6g*r}eEi5o*-oCX-(EMdaDmq$J)b}uZww?^K3_5Fao z-Cl2=FFAj2`m@XNX)k1(Ubwa`<5~N#yEgOfpOuMwg8$U!oSJFAMWT1}-Oy>=kN0W( zN|cy**Y&ruxXE$RT)v_MLJ9)Y*xW1_KqnU}m`rQjV3Ma-#eTozq|u_Cv636ku>TgE zabv>e-Om~iJ)Ymt_}M*DyXM*-^>tQGwsyM=gR6IdTV?z2oqMLP9y)!o2cr|XRkp(V zZASFjgcYaNHw!eq*eU3>{^2BE_L{BQOQtTKR`Ih!tm~E~&u-r7hO@=DDov377hLpj zqi9~15oj_3v=H;ytcJSkyKXIF6?ffO9v$Idj*`x6;d${bX5?+Dr*|gc&a9-YFN<;9${U zs;JxSzBTMbhSJ0 z;fLZ?)0=7)KD+?c@smsAEVr1ly6^G&*>inCo&V%JRulJ5y7P}}3}n~GPc_ONFgi&fbr&byR%aN?iC@@c8HQ77sb@G{!4_fI%( zGwo0Lw^uLL=kp}%9)9?|#%C&<_;T6#TRNM)4{h8hjIAxzV{-GW?MmxYsc~~!jyyS1 zApJCoYfI;^d!-Bhw%?#r@jk`DbTNpIE=MR$_a~mzK&n z>v^BP1%A}ow)~68b>p2bcUQ=od~1BJprBlEV#~7y&!1alwka>0YW-)eecgCLt?&FlhP4e1VvL@tfr$x4b=R!k8P@$< z_hn|q)Crs0gLNz;_iS>~Q!k23IaIf=fv2sNImHm%B3co}t9qkwYQdUV#eChF$J5-? zWy9O%FISpeq@!$^*}nO@nv33ft;5p}BF!pjK3zC%^UcpU=J1!l?^BywIq~=TZCNX? zPrqaca)obo*`U)OJVlGWaK#zgm(NQkUuWTUu@T^V$~;gs0Sh|PiTuAjPP`Fr)R ztn1f=!>=5$-!ms<5_pcHnMcHX_t{P_@45HP>~k2|B7*L(%Xx0`q;u;0Z3=H6O@BR& zy>;L3Yg{3H@oLw$GM;De_m6#3vON0CvooR5(jnz;CU@rST^l<8{k_^H%W63yw}j7G zw>si?)$vK0!i81-mv8!)zqecVd6kTlriJM{4$!*qO;b$ez5MTlU3nrc>9n>_0klx{ zmRHcpmzTa==Joo{lKW`KYt8@;ju#3Cc+dyhLp}Z+imMJk(f$9yl<%`UXWy?e>y(}t zaczm#z4TH|{#cCmR>+T^-*mYbbL&i-=NWDN^V7bjqA$lj&8%3PpuPU+^H0Ldr;3}c zVESuyuIA}qjfeM|4{h%knfvR<&Lv;nr%s!{YF(p$X8!fH*5y{a-)sH9yX$gY^qSX> zinGN2-ntv~`LeIhyQtv5Pk-$?ZN7WzSpy@-t*w`~_siH%%$X|^e#tX*#ai{ar|;zN zoS*(|TG?Fty`>YQkNVq6iLhO9Y4dqKK{RI0Tc0VP=e^jl@=c5K*Sn7=sE6IWbMS2I z%8Z>+$2zrL0?##zf0ND-`B3xWhs*-gJGRF@-7q& zauL!|iI3pp>imJb{iEOcYI&-$g(cmqeoE}pqRo?Tjbs^I)|&)2-}PeF}Dy(i-T z?%jDa`Cjzm6APTTbpE=NccIovuz=Gu&tlV$dVi5)YdGDzFVDX0Oo zms_)$XPcCCT$@ub`_^IA*FH{@&r`2E%dBu_7M8Y-HkVn?Gj)6E{&bt#J0C;J9M&&5 zpsr?Ys%>ta@k=27+JVoFkAqDY%zv`{Gxx^A?(^2VJeT(Qv0qsPJ{GZ2>G18%^CkCb z-KctYN-u&t=6*O*D&5A!ro+Eqf#3b`k+nyePM*H^qfg1L=eh0MNS)t5 zPfI+l%oS?c|Kg=^yQ17ChQ>mN292A0XG&?X^iSIWp zbiQf^nY>t}HeXhGiv6Ldm-1HGwmn%dd2#)zZJH;Fzq8LX2!6-Qu~Xl;aN82O+R2aS zOrF}h<-Zqb{5c}sX6JdoNkUGuJ=f)=N4@Ud=BlMzsG7A*dR>N*cWQO!6*~|A&EenP zmF%qjd~EK$XTMJEm2{8wd(LXGq&HR6-uK<*ozWd{;`z<{QPWpH(*z?AXlv}&sKh5EowT?GNm$kyKqUPH}rCqP3-fx(5NA|1<`%I~`3(Mr! z@3{J<;fDGAL`y6FP}Y4Cnd>ZOt&UJlc@Px3^nw2@m(`LBe{XMH^|Ue8R?Xq^!Cx1p zT%W%@#MK?CUv*nLc6SA%qPg`Y;R7Wf)25i;5m4s82;Ne0apns7wJf@g3}&WzVIL;( znW^mko^-x^=84*7W6M>7hxrPPH_!iXaq3~*-{Xbs7hmoDv3yU6(j?`H9vv!9f$L=? zXU))DYwegl`%C2ES;GI|hPj89WFt6aZNcxd~F zVgH8R-dYn+^ZNKm7A^cSFF@yr`1BZ+cWT|j9XIp6dB5=QGt8N12tN04g44a;Rky8O z>Wy}nFWmFx`AP0;Y=%}+6GIl4u_h@=*^2h&A6?sjTDR8z3{z?KTiuv?ZT)fYjr?8vtt(dj-*+{?T(YQl_34Pb6}4&W)HeFhvNhf%zjU%s zxlHWTxN^fsg%a<}k9o}5>pko7jwJSbzt>sbYTwFVCp@+13dgs1%NA(d*stxsYOaqn zi|es{&yFphx?-2E*NxzXo!@wRxjvV^G7ef^bi>!tovE%}opDuM(CrIBf}4IG`F7-m zIrHB6%XrmOtIqto^?Wb?lCBRYCzW>YZawI)ocZOn_9b4ajhdFvi|gBeO;X-${{HAi zIVQ)@NJ+V(Tpx~Y)4VVL*ZMWz`r7()8$0g>y1kD(zmjvlcwcScuMJNYFSeHTKi_xE zbw}F#yZ7hp_;A;$g{81`C3EGQmq(S3+)%2St7Ro5y-R$0BR9{F)9JV4cGbRE>R<4Z zQCv?g>HChyW(1vId^%u9z5mm{hlKiF*p2zU1DDKlo?)}AP2K~C73s46mZ!5zHOiXRQ<8sQ^9F9X1DI&YDlo>*PXC;pT^9Oec8r)ySJb3Fy4Fr z`NW?8oDbN-o*()B_Jruu7{0OvwtX9BJK0aY_djLY9pA>i%cRc+FDd(KO=&#iD!q&#c>(KMHmww%tw&(v^^~1F$ zA9j7yUmn=~CGtaZ=zX8slzP53rstEhlN59%kJ(u6;_U5DVX%?!?C|@bQg&M)-F$EN z@2g36OP@5B+$o?zdICW9R3HR^HD?4qV>D#We5PQ%i|U2VSR@t(x{_SK~`I z=4EN`59o+-{GYoqqB5XVfq|vrzy-k#OI{xPq*~eT=NVuG>RvEFcK7J`Gx(UFHf~4S z?4)4ez@#&8^NLBa=YQC(_Hq;Io0qM0ujsPQ8qef_dv>b776#}zx1^u>w!u>-w6e@C z@v-e54$ZymnXW(Vf9viE6ve;`y)m))+hi2T^aU-C&b6MV+DL!)^Y6@_qS#9$= zy6Im{#(6DOr&M;2gfmyd&#Q9tzxm;K=WaEd2Ky#R51&C`g9M{k_1!sQE_DkYrkEbz zX|P>#{h@CA$*b)YCt0!O|G&)C?EkDn@wU(whu3~{)oW^B#QG{SF#0rXm}&c7)Lx`t z{ND0veil%eF$gd)9iGR~?Q1@3?W%Vl)=kl}{L~Y%xbl-${$CyUPkY{OtmL@K;_jwf zU>x({?Yo&ykq^Y4C$1M+v4EAc|6I}9R8q>ntqDNJ#(k9h0P4=pZ>tWhE_jf;AP#*`=kLo8;Q>I3L+t`1&BSYUr z2$Gs2{2I0v-?d=L+Bs`t&>TnY29BeTJ!hNl$C}8?1(+PjrYwN4er+6|J8bJ<0OZ4@8I7D zwugp>g@;|!W}i2I>Iu31m;Bjw{(lGajj|KBL63NSGButenSTA6a4|9w|~ zZ*TAa%^o>F797?tUHbOW$BiEs?Y{MV`XasRdL`M(Gs5a_CrpiVQxV`~k>EJ7KGaKh zb4Gr3aOIgtOaIsIbGx?e{p!8m>(BeksS7N*{z6#d%8WIiyE{DgSDsgR<;iz)j|!t+ z_8f(OQo)&jMSVRNXDS*-c%(;9j<~g8cj`%N-b>NG{kKjXQmB?!wc9iA)25)#g}-Jf z%;u`w;dA+mk6~IEd$8avi)CWGiQ8Xpo>v=J!6drf{OS{NQPEJZBa@`gdUsoj91po@ zJ?T`{p8JL@3I{wd-|C?>A7Js5oPE5`Vm9t3- zPwTxk!zzy+Io?{mHSNvGJo&5_0d~JR0(u(-qwD2r{HIyyXa2gxyZCymryXZ`bj6z8 z>t{`|GtD>~*5aYvb~I1G@a>(({KL!bzXg@LW*++KIrI9gC&z9n#`S8h(mr+X)v6ky z)4YXqCZ8_azFSFkkzV(r=j%9X)mO8LUy1u^{{4ce{#%RdnK4=KH_v;scm0cV@?qz* zk0*=Qe%FunI>HlKzw`NnM5F2;+dml#URCV45*I!*+GNVzW#O#93#}YPgHw+`Uarsk zf8(2D{PWk(+O75H{TE1JJiYc>bMy8mHjCC9rM6foB*Zc4n1Ks2foJxWlO`wh8E0i( z+s7R`U%*qgdHa9OlwT^<(fi6C3LMo>dLm|!FLb}`+Ua7!T{r)@^ecS+#GdKw-Y_M> z{=%OhTZ}v_ny7N+r*yjX zet0bZdvB7TS>UU-JwGk-i_Xc;nc|sN>v^lD@x$fX--j}{Uw+lB%4?A*?-)6!_Kv=u z@z1?4CcDnm?9}gjxwxdo&0k=_V*9LAF8*m{r}qR`rOZ)ybo$Jl`O$^4yPJ2sIAOFa z<6zChSE-(rwYC*ChlRGC&)|vKl`zM^a{V&T`S-gX^gis}EV){E`Om4IU5k1(AHJ|& zI#YsGk7Kf6=(Y^w60<34M>q`6v^@Sl<=Uda4q+9ah^7mzcf~)59lq}W?&!%$_FUJt zOmST1Sr)ZwWnY0xvhB+&pFXWvvT4fyy(ebb9c*MQIytf8PFCQ*j~NeN{al^QCw5Wm z*ufCB&G!U@wqJeIE8Z8a>tiu#n_=45O;2jxJTVSE{l{P(~hdUAHTrPe){FV12=N#xg33K8reOm$kkGu-)(=n!Qu>cC$r=i`R{#1 z+m$7Mt3SSbP@+?H2fO>vsc(NQJoe%%+xKJo-``rVeEq>fl10Jb1}Ga`%m^uM7f#-P zYFgDgzDqMQPet3G4otpRcJ@I=W5nyt4}P!xCX%iqdrs)>t*`uts%J_c4k~CqEBS=q zo~h+=`|*9TDxR@hvY5GS3$!fr_I+l#61J=4Xqw2ZxbmMxrBx@coz>o_lmBz=+I@eH z>F;2)_s(8-H6;G`QeOM(%lGd|5!RYgHX)2}-~HOz6;Uc#2iCLr7%kuT;S$4kC zJ=HqD&!p?;+^uOc`!s`DKjG;oZqL=vj=#75xw$mrgU=t4Bpuo3&-&a#kMF)`JFQqN z@6a{h${Rd~4&F=txb)18bguqx>(a+oOP=gs{Jl-a_IB0IgzHMvxy^5VHJhpCeqLVt zUdw`~7cFk?GUBmu;7hP<;(x8 zg%gbXLRL$r8l|USnz&BV?duh{uI~Qug{9nczRnjicK8s!0*q80w<&O}N7{(0;9 zcDMCiXQvyTO1Wm8b!(@A&1t!S7PxFgdRt+bL`Zv5g@{TF@b?zT<0 z?`*2AUi-b(X!@GP>~SYVO{@3Us}=sdRy^roz(;-2=YbB7wE3c*e!6$gQq06}{fm2Z z4{oV{RIb~$yV)>kHS4_WCrMkrwg(+P_&vUh@4ZclhLV!_v0}Nqp^B|DIWFjH=!AvIhuT>^}S{%KkVB5ZC|t*>))u72N}0sM(#fJ=3{i3^uFaCfs5T9cBi;6 z_nO>wbZy(J+3gJZt2Y0>vN0pQ>fo`NW*n8j6++@$Mr zcE9fj+tX_Q?;rme=xX@YZTWXW!tPwRQV!D9M)!8dc{@l9MVP~`9slCHCZ%>-H#dAI1KSv&}>ozI}O8(0F6go^^d$ zbuTA-|6hLQX4rJs|Jg^EeE0Kwc-=#zFRttV_L*}_OtSCIk6nK2p^ne185jPaTcH1C zBKtC3satuUcXcZlmGaGc82i3!&a+<}Yi3>8cFVi(=(4-dI74l?_8;__-%>r@tf#QR zEM$vb)c@PN>y?h}ZZ_N$&Gzt-Xv3zc4KJ7Jmwf78sLialXUC!YTeiR8Zes@58{c;o z{>Y2_m)*K>#m6QWYo1jOEwg{8*wu$Uc+K)FTv>MIomRTd2));&+U-fnyMA)5W0@y=aVx2$j6>XUxG=kM(Nb1c>uuX~)8-g7bA#`dGH zbnlhes_!CBds82!d=Fhb_jvEJrz7BiOcJ?H&;GBU|!ET)9?3+>~rq9efmq?t9NC6*8j74jnD7*Pg*za zjo- zwYYEv^L{18TLHyVxBpIfT=KunENot$%lUmjvRH)nNWOUdTJ}Qk#SpdNZ+4|F;b&I_ zm9&^uSig|pvSX&tgpJn(67S~D_}tspUVSp-sB?`GtxWJ-sBu?tHYp z>-ENzwuB`XrosP@JYMZn&YrwvAA`+wzsq8=Eq~8EXpUFS`BHez^?<&BLDyQ#Rsqy^8!9{FVLW-Ww$>K|OEWd8ox^l6w|4`cOl|Fwyyb8GUI-umi zm#m$Odi^}@FU?^3d73rwh10|7GiP${o;=}oQo1jDn%3VqZ(XBloze~u+e);oH{@Qs zcF1uF$tzdhs{en+gSYtMQ}y$+ zcYB)H|ICPuym|a!+%~KKO1kdMT-?{1s=_vKi01uXw}sJu;caQJ{db~w7rl*n-RIUK zcD|%+L)dnaIev$xCC#2R>(3kp*?zkSt+y(-yNvkf9n%l`enQVxeN}E&;A4LApyoFx ztoPr`&Yx<0YRYEixBD(T zBif|p?y}9i*SBwuP2N_fQIP+9(XDuOgVNdRAsee7Xz`c4*tt1%2-`||LdW(9AXYq@lb5E+aO|+f>IajPn;(7{uR7T_hm>#_RNDwXYmv>tY*h1#B6`F1$}PoYePj z%A4Z*H6HgLO`R`mz2l1H{IKWCf7VV~)%%?z;``6`*MF8LFn56mo3>BrE9V6bHiezp zuv*{JsQPo9%tJ+ikf~E2emwh0_5U}ciIMSBY^HtzvbY1;VHAnv(@4=vc>F}5g_~gzHV{g34vI`{L=eaDz7X6CzQUpn=D z|Ib&l^9@%#O*r#tt(24Y;X|`r7IBvtJLjdSwY@oKDzKqI)M|F;dDg<-m8bLN`agOv z`n)7Peoo=%^=d{ZC*8X_J${$Wa=ZLR%I#^#s*+Ah{mYe@vYSs$I0Zh&m$WM5}>%AEQIl9xA{SWdiG8`xFE$-`CVzI_ zqcYFBE35ps+`X6l@i+V8`(@i#roZ9|t~>$sTq8^R>_G z&vkyk-Dp2`hs+y?{qGLsaa9>9zdbPN_W8}%OBPqRdaVptrJ;9!+Val=8Nax|qj2-{ zCA?SO67}NiKmS}x_2|okC6^tV?b%o~HvN@LwVkzG+Tr!SC2Ai}%$sVOc%ju}lW=6O zVUMAJ@d4*mMgLCQ&(*D7etq$*g4~O!j&9ruIdLqn7I3AD_6U=bx{8<9goyHQ!#v$?UD2#lgZK z_8h2d-S@Rm{jq8R9o0umZTxORD|>I;yL>=`nWIc`_}N%Em(3QqmOy_Dp?=%?niBh zJwG$J%KCuZOhKV9jtll_WR`vTvTIYQ?L5Ea6RI-}6?b!g)Nyb5qqlVb z^K1OxE6W3ysMOrkTKhizuRCd>y(0ge)1QyR%Wus*`Os`amcu+pm4@w7&cZTPaSSuMm@fBrp6cjezMSi_ zLQ)EPdxir8#~(Y6h)X5OZ^f7G=MQz(hOEj058!>UU^!4yEfX~Xd`KH~fXLZv!TO!@ z&QUA>iLOH*#9QyYbWg3<7w3f$Z5-!kyiNSV_oZug-@a@G0&R}x-7u}nX9Fn+1UHaB+iPkT@ts-Z8y9DjR=T9%$v1fjU!p#QGg52fRyZkcN zug?8@z9H4Y4K!W@9+GNkWa!?T=f|yNe__jstiIyJJma`R@%n3_wN5IfJoo-BXJwmT zu`*hEVt&Ym%PQxdlsYc0K6fvq()YR1h6atzf*Ur?`*G$<;MVIeT#qwuy}6-D0cLb< z?$6_5Myqxm-W{~+$qD16-eY0G_kKn8J*m8%{Q1MPl7kZix$nHVc=3N~vtG=)s8>${ zLx1Vl++zLK!un-3Tl;KQ4QD|}02n;t*idm`$~DpB=hUB+@=J#lE{j-sRrcG*8^7~9 z`}z4FJX<<<+Qo@B_ctVjRF!1ExwiOd@7^-LYiUjUpQ$GteX9KG*U?GQXYbB3tQS-e zgpGNfP(JX8F*qtxX5Z}T`)`M=z7e}q=xO%m4bOcWJEq@J|NL_@bG$m2vDDNP^V)x0 z7FSWJ(!Mh1SFz^Hr|Z7-O%Y(5eIPids(i)ou5b4ff}b5sh$YdgQslz^-8oQMkcel2d!c8a;=Hp{3-Li^`}(o&tBdy?O3&~COEW6vUT3)*e73m zdY^J528sW~ac;Qw`j}$C>8m|c9`QsOy97L`s_yN&b6=oJ?Tu&0+2iT+76wj!;SqZA zU+(`2m)!4ZZ(B2mHM{wO2Ai!->wPXa!4JKM7BsgpLDF(Uir|mK&FuVaE03ypmX&61 zW0hILv>|XAWMbj;VsXZc?2sYAc=6lrMzvKI2KJ1hzxSVy-}!dufqJFv`+R5kSydp* zV-CEZ(x7U7DCv9g)YFfPCEM&RYoe8}N6DY8TYfiP!o>S(&EpzZ;Yaq?eRuz6ODt&7 zf(`l^s4?`1CCe40@iE2xe*X7Q%-YIpYvy`o@^L9J!=gz+fZ=kkz=Ea|%hy!cyokEM z5Ags4$Bg+5J6zA47lAqgoSG9Ra5TI$^GI;ifed|vEjr`haCC8$*3GXy?>DbXQF-`c zr`jW3^XNZQSFWAm3S&FU*nfR`^H=g{Z%eVm6}Q};pMgy-u=EVt zd2GfgR(GMesSl^kSg~`3l5fe(MS&}&wN-`FE4WyiX7;TO+Ss!=(!{0gsfU|k zl&osa%B>$(FMis5R^$onlrYd*qX`@vz{lKvV&)ZHZF#PB=UJ6|-i#lewy9=#UY%>@ z|KnH2wU?oBw#sGEg0G*Z*k{KEe4Mx0JT&fd;>sJ2uL2Yh<&T69XyhtG2Pvz4{FPUJ zUgQ+hc8lzbf87>s-1epPTuY|eiY?svt2md<7UTVcxbZ2%6*N?ClHNDh|HNxKvlWkg zHePDj4IUXkGb<-!K_*)W@1+BZNC6t*-tcyr^!>A^>(?5Hn8r!!)S3ko;Vt4pR`J7zW8E?{B&8Bd!LKnYH#{< zTQGELz1Yp)RphlYs_r-Su+KEiHta!6ocIq=$yA!7n7k|&&<8GN=ce8{&H zlK(*d0x68JNmzwe{cJuuf6A&;n~k}o-)HV~f1tGPu>AE_pGOK_f#n-teDZ&4Z!a(Q z_f|>Udnq;szD+Ya8}=+)Q#$KF&ljs!NFNr@-P>9|Rrb$?fB_e|_vN@I z#RUZh#%{ad{PXsMa857qIznh7UPlooTA{4f0I@QYF4#Uzzp;WhVWghj^g%b)3B;3u$oyGZxM zZtqE^%bN-hovG36%UrE@_V-67r>#HTKY#Xr_Vl^;hE!eKX*v?(ljHpZw|@$Iyl4Ki zEf1FX7|s54Ijmn;P5n)`WV?6d+?n?qgue;i`n2E2ZboEB-Of*sudi&sw(MC{Y3~x=>if&~ZBpS8y_ctI8C+XF&r8QfVb|?WfyqAYmH94tuLNrEZhRF~ zR&|Pdclf*)X8RQ4c;D_)PV{ zqn&vs9N?1a#T9$4b0Y1#_AlFhZ;HA1krT=#Mr#gc-@A9oKhuWYyqw+o%f*>Zp-ee? zmDP$@rj*P08-D&5TJveQm)^o6SBHtBF#P zH!Z4nb6kkMVBL;cwJfhUo>$&t{mZ`#VMm~h&3KLZ12tEY=&Nci*gH^+yH_t9uScuxTcqahzwvmPh}|KjEpBoCZE@~d zHp~37x-Q2ocqgLEdsD3Z)s5r&78Cy4ZME=9ov?4Y*({IQ;hXo*y!65Q@Y{38ULRfb zLO3`t?Z(%uN-b|#4syCT^Da3EuNXE9CcJIXRMkFlN^gDka*folSG75ITD*E=wnS*Y zxbotQK~sZP<^)gjs9f*6(xk>|cCRwWE5!wBQ|GRoo9l5=DSX@Mt;a5f%&)BQlRp2j zb%E%?^*?ssoBpTdrJMF#*R}5)QqTGpZQ8psq(sGdy`%PX@l55FVbjw8traWPu+q#~ zJoD6%wi$~a&s)^I?cItpSN6F<#*YKF5B<=;s+vEs{DI6Tznw9YdvbD*%%8YxrC7)~iuPfR2_4Gw|OBZeLeY4p$qRFCtp8fYs z&Ki;AH7pj)kj!W-@ZxE#L9+{Y=L3NiPqW;-3fW@i1Vwhny-yDIT7PoFah>Limu9C2 z2XUvC9O|(RJz-~Lc#XF$C{w0cD2nT{*m@h6?sGqr9A>UVNS5v)sB$h<-Xiyk5+6* zK6~-pJ4bolo3an5b)Of{=MoNi8!KhD?8T4n`m(6PnAzUJ{|y5Dw#=WZ>}1U({_esN zZZp+ie##ar`o$DO;@j@425c(e`%$q~;UTnYo-y%&yqrx%f?HwRB9BRLUcEBvG5oy| z)<;hNGGR%G){&=DuC_}uZg9L-EI3o+>3hmrGl{3)pe}X6t_}I;x;B^vM2fF;39~sY zVI00RTIL(KQnvKGugXg%$Eqaew*C+5Fjyt(+&#te^q=w_HHDUz9=GLgaJ&{QcnDry z(eRf=MX0m6`S6dAk2x2uKf3(PHIK*cD{dZ%@(=)3%|9Y6VhUD8dNB7#_J}4XpPtZ~ z+&eeo*uhx|0c#3{HqZH(Q?2&I)tYoH*$T&~ za3P=RjoIB_cYQoKSajSDBt#`o?Mq+Ge1;SnbZBesbK!jn~y3VuKM(*=g_h0 zS?fi1biDp>yi{?rg-7LXo7e4+XHB{H`kMaybLp>nil(ml^~axgo8P?Rw2ZK88!E~h zncz*A#)YZ}lGfjz`#SvAGMzg@!lvS(OFH$kr`d;^hk2=;`yj%>Vk{fIG)c1E?2^dx zZz&C5o?WpsbHR^W8r6F%kMZ0es zn8?a{!P=xBek&YEy4)MqfLH~RyywxiyT+}X4(OhXQvH}?+T9trz1~JmZBK1)aMt7v z&(}-Ict+P3Hzw-B@UvP}yj z%%fJhDp`Mho_jN?f5j1lzhTS!&u3LUsp#^4Z&MI|@t?GuNh@?{z=46IM+bYemk-wL zovSvL^>?|b*`kER4qxw|4-dPtna$JV?5=}%27UII6(j|oUa$&QgESma=G;)WPP*Me zH{3X=%lL(wkmJPHU*DO4n!yEILar9Xda0lCzB{$O{ta{3rSvtt{)ySuA_uR%*NNzs z)#8IBSBHcO0cbZ+4b%-R<(*WpHezbf!jQn2eY*W|EH3gIQ@ILvx&{8q&an^J`v3Qz zski5G|54v`?N!=tt_A;K&Z!cd;Gx3D$M^VnzdFaF>#CdQZ~Fc7{L_y+e-&PmGn0Au z{)*<(tbK+17IA)@FMB+1@7EPveeiVOcwC7=?LhKFsYgeUdVz~9jxa2&fW<_PI>R#Q z)h0iti1xEU|>p9J@DwF z`P4U6$G%5~8cizr5+nR^n)F^zSTFFIHY=nTctV9Q$tyFgO96T~IoMz^MJ%}|*hIfH zd1=Zc9{)xMgUcI3wWbxCXtx+F-NF&8!Gdaa66n136Z|GRYo1w%KQo)m@lilOCAw*v z|J{|Jf9>5cBWTuCB@SrS0`hc&E60W#C5wNqc*XbLYvm;6^BtzgUhlqZ8?3>7=h2uzah=QxIe5Xqz|w=7Lca+(PJI2glowPx^0<5d_FH+H5qzo| zXsb^HgFpg%qrFYVhlB}PUXxP7!>=oFUhfLk6!j84`t{P^g0f(g8fQFeC3-I`VbP0l+XkKASV$? literal 0 HcmV?d00001 diff --git a/sr/_static/img/typical-cake-request.png b/sr/_static/img/typical-cake-request.png new file mode 100644 index 0000000000000000000000000000000000000000..f951d3619642a46a8c4de2b9123e47039c285760 GIT binary patch literal 19786 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 OH}iD$b6Mw<&;$T&F2sBQ literal 0 HcmV?d00001 diff --git a/sr/appendices.rst b/sr/appendices.rst new file mode 100644 index 000000000..fa818df38 --- /dev/null +++ b/sr/appendices.rst @@ -0,0 +1,71 @@ +Appendices +########## + +Appendices contain information regarding the new features +introduced in 2.x, and the migration path from 1.3 to 2.0. + +2.4 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-4-migration-guide + +2.3 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-3-migration-guide + +2.2 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-2-migration-guide + +2.1 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-1-migration-guide + appendices/new-features-in-cakephp-2-1 + +2.0 Migration Guide +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/2-0-migration-guide + appendices/new-features-in-cakephp-2-0 + appendices/phpunit-migration-hints + +Migration from 1.2 to 1.3 +========================= + +.. toctree:: + :maxdepth: 1 + + appendices/migrating-from-cakephp-1-2-to-1-3 + appendices/new-features-in-cakephp-1-3 + +General Information +=================== + +.. toctree:: + :maxdepth: 1 + + appendices/cakephp-development-process + appendices/glossary + + +.. meta:: + :title lang=en: Appendices + :keywords lang=en: migration guide,migration path,new features,glossary diff --git a/sr/appendices/2-0-migration-guide.rst b/sr/appendices/2-0-migration-guide.rst new file mode 100644 index 000000000..4e079c23f --- /dev/null +++ b/sr/appendices/2-0-migration-guide.rst @@ -0,0 +1,1292 @@ +2.0 Migration Guide +################### + +This page summarizes the changes from CakePHP 1.3 that will assist in a project +migration to 2.0, as well as for a developer reference to get up to date with +the changes made to the core since the CakePHP 1.3 branch. Be sure to read the +other pages in this guide for all the new features and API changes. + +.. tip:: + + Be sure to checkout the :ref:`upgrade-shell` included in the 2.0 core to help you + migrate your 1.3 code to 2.0. + +PHP Version Support +=================== + +CakePHP 2.x supports PHP Version 5.2.8 and above. PHP4 support has been dropped. +For developers that are still working with production PHP4 environments, the +CakePHP 1.x versions continue to support PHP4 for the lifetime of their +development and support lifetime. + +The move to PHP 5 means all methods and properties have been updated with +visibility keywords. If your code is attempting access to private or protected +methods from a public scope, you will encounter errors. + +While this does not really constitute a large framework change, it means that +access to tighter visibility methods and variables is now not possible. + +File and Folder naming +====================== + +In CakePHP 2.0 we rethought the way we are structuring our files and folders. +Given that PHP 5.3 is supporting namespaces we decided to prepare our code base +for adopting in a near future this PHP version, so we adopted the +https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md. At first +we glanced at the internal structure of CakePHP 1.3 and realized that after all +these years there was no clear organization in the files, nor did the directory +structure really hint where each file should be located. With this change we +would be allowed to experiment a little with (almost) automatic class loading +for increasing the overall framework performance. + +Biggest roadblock for achieving this was maintaining some sort of backwards +compatibility in the way the classes are loaded right now, and we definitely did +not want to become a framework of huge class prefixes, having class names like +``My_Huge_Class_Name_In_Package``. We decided adopting a strategy of keeping simple +class names while offering a very intuitive way of declaring class locations and +clear migration path for future PHP 5.3 version of CakePHP. First let's +highlight the main changes in file naming standard we adopted: + +File names +---------- + +All files containing classes should be named after the class it contains. No +file should contain more than one class. So, no more lowercasing and +underscoring your file names. Here are some examples: + +* ``my_things_controller.php`` becomes ``MyThingsController.php`` +* ``form.php`` (a Helper) becomes ``FormHelper.php`` +* ``session.php`` (a Component) becomes ``SessionComponent.php`` + +This makes file naming a lot more clear and consistent across applications, +and also avoids a few edge cases where the file loader would get confused in the +past and load files it should not. + +Folder Names +------------ + +Most folders should be also CamelCased, especially when containing classes. +Think of namespaces, each folder represents a level in the namespacing +hierarchy, folders that do not contain classes, or do not constitute a +namespace on themselves, should be lowercased. + +CamelCased Folders: + +* Config +* Console +* Controller +* Controller/Component +* Lib +* Locale +* Model +* Model/Behavior +* Plugin +* Test +* Vendor +* View +* View/Helper + +lowercased Folders: + +* tmp +* webroot + +htaccess (URL Rewriting) +=============================================== +In your ``app/webroot/.htaccess`` replace line ``RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]`` with ``RewriteRule ^(.*)$ index.php [QSA,L]`` + +AppController / AppModel / AppHelper / AppShell +=============================================== + +The ``app/app_controller.php``, ``app/app_model.php``, ``app/app_helper.php`` are now located and +named as ``app/Controller/AppController.php``, ``app/Model/AppModel.php`` and ``app/View/Helper/AppHelper.php`` respectively. + +Also all shell/task now extend AppShell. You can have your custom AppShell.php at ``app/Console/Command/AppShell.php`` + +Internationalization / Localization +=================================== + +:php:func:`__()` (Double underscore shortcut function) always returns the translation +(not echo anymore). + +If you want to echo the result of the translation, use:: + + echo __('My Message'); + +This change includes all shortcut translation methods:: + + __() + __n() + __d() + __dn() + __dc() + __dcn() + __c() + +Alongside this, if you pass additional parameters, the translation will call +`sprintf `_ with these +parameters before returning. For example:: + + // Will return something like "Called: MyClass:myMethod" + echo __('Called: %s:%s', $className, $methodName); + +It is valid for all shortcut translation methods. + +More information about the specifiers, you can see in +`sprintf `_ function. + + +Class location and constants changed +==================================== + +The constants ``APP`` and ``CORE_PATH`` +have consistent values between the web and console environments. In previous +versions of CakePHP these values changed depending on your environment. + +Basics.php +========== + +- ``getMicrotime()`` has been removed. Use the native ``microtime(true)`` + instead. +- ``e()`` was removed. Use ``echo``. +- ``r()`` was removed. Use ``str_replace``. +- ``a()`` was removed. ``Use array()`` +- ``aa()`` was removed. Use ``array()`` +- ``up()`` was removed. Use ``strtoupper()`` +- ``low()`` was removed. Use ``strtolower()`` +- ``params()`` was removed. It was not used anywhere in CakePHP. +- ``ife()`` was removed. Use a ternary operator. +- ``uses()`` was removed. Use ``App::import()`` instead. +- Compatibility functions for PHP4 have been removed. +- PHP5 constant has been removed. +- Global var called ``$TIME_START`` was removed use the constant + ``TIME_START`` or ``$_SERVER['REQUEST_TIME']`` instead. + +Removed Constants +----------------- + +A number of constants were removed, as they were no longer accurate, or +duplicated. + +* APP_PATH +* BEHAVIORS +* COMPONENTS +* CONFIGS +* CONSOLE_LIBS +* CONTROLLERS +* CONTROLLER_TESTS +* ELEMENTS +* HELPERS +* HELPER_TESTS +* LAYOUTS +* LIB_TESTS +* LIBS +* MODELS +* MODEL_TESTS +* SCRIPTS +* VIEWS + +CakeRequest +=========== + +This new class encapsulates the parameters and functions related to an incoming +request. It replaces many features inside ``Dispatcher``, +``RequestHandlerComponent`` and Controller. It also replaces +``$this->params`` array in all places. ``CakeRequest`` implements +``ArrayAccess`` so many interactions with the old params array do not need to +change. See the CakeRequest new features for more information. + +Request handling, $_GET['url'] and .htaccess files +================================================== + +CakePHP no longer uses ``$_GET['url']`` for handling application request paths. +Instead it uses ``$_SERVER['PATH_INFO']``. This provides a more uniform way of +handling requests between servers with URL rewriting and those without. Because +of these changes, you'll need to update your .htaccess files and +``app/webroot/index.php``, as these files were changed to accommodate the +changes. Additionally ``$this->params['url']['url']`` no longer exists. Instead +you should be using $this->request->url to access the same value. +This attribute now contains the url without the leading slash ``/`` prepended. + +Note: For the homepage itself (``http://domain/``) $this->request->url now returns +boolean ``false`` instead of ``/``. Make sure you check on that accordingly:: + + if (!$this->request->url) {} // instead of $this->request->url === '/' + +Components +========== + +Component is now the required base class for all components. You should update +your components and their constructors, as both have changed:: + + class PrgComponent extends Component { + public function __construct(ComponentCollection $collection, + $settings = array()) { + parent::__construct($collection, $settings); + } + } + +As with helpers it is important to call ``parent::__construct()`` in components with +overridden constructors. Settings for a component are also passed into the +constructor now, and not the ``initialize()`` callback. This makes getting well +constructed objects easier, and allows the base class to handle setting the +properties up. + +Since settings have been moved to the component constructor, the +``initialize()`` callback no longer receives ``$settings`` as its 2nd parameter. +You should update your components to use the following method signature:: + + public function initialize(Controller $controller) { } + +Additionally, the initialize() method is only called on components that are +enabled. This usually means components that are directly attached to the +controller object. + +Deprecated callbacks removed +---------------------------- + +All the deprecated callbacks in Component have not been transferred to +ComponentCollection. Instead you should use the `trigger()` method to interact +with callbacks. If you need to trigger a callback you could do so by calling:: + + $this->Components->trigger('someCallback', array(&$this)); + +Changes in disabling components +------------------------------- + +In the past you were able to disable components via `$this->Auth->enabled = +false;` for example. In CakePHP 2.0 you should use the ComponentCollection's +disable method, `$this->Components->disable('Auth');`. Using the enabled +property will not work. + +AclComponent +------------ + +- ``AclComponent`` implementations are now required to implement + ``AclInterface``. +- ``AclComponent::adapter()`` has been added to allow runtime modification of + the ``ACL`` implementation the component uses. +- ``AclComponent::grant()`` has been deprecated, it will be removed in a future + version. Use ``AclComponent::allow()`` instead. +- ``AclComponent::revoke()`` has been deprecated, it will be removed in a + future version. Use AclComponent::deny() instead. + +RequestHandlerComponent +----------------------- + +Many of RequestHandlerComponent's methods are just proxies for ``CakeRequest`` +methods. The following methods have been deprecated and will be removed in +future versions: + +- ``isSsl()`` +- ``isAjax()`` +- ``isPost()`` +- ``isPut()`` +- ``isFlash()`` +- ``isDelete()`` +- ``getReferer()`` +- ``getClientIp()`` +- ``accepts()``, ``prefers()``, ``requestedWith()`` All deal in mapped content + types now. They no longer work with mime-types. You can use + ``RequestHandler::setContent()`` to create new content types. +- ``RequestHandler::setContent()`` no longer accepts an array as a single + argument, you must supply both arguments. + +SecurityComponent +----------------- + +SecurityComponent no longer handles Basic and Digest Authentication. These are +both handled by the new AuthComponent. The following methods have been removed +from SecurityComponent: + +- requireLogin() +- generateDigestResponseHash() +- loginCredentials() +- loginRequest() +- parseDigestAuthData() + +In addition the following properties were removed: + +- $loginUsers +- $requireLogin + +Moving these features to AuthComponent was done to provide a single place for +all types of authentication and to streamline the roles of each component. + +AuthComponent +------------- + +The AuthComponent was entirely re-factored for 2.0, this was done to help reduce +developer confusion and frustration. In addition, AuthComponent was made more +flexible and extensible. You can find out more in +the :doc:`/core-libraries/components/authentication` guide. + +EmailComponent +-------------- + +The EmailComponent has been deprecated and has created a new library class to +send e-mails. See :doc:`/core-utility-libraries/email` Email changes for more details. + +SessionComponent +---------------- + +Session component has lost the following methods. + +* activate() +* active() +* __start() + +cakeError removed +================= + +The ``cakeError()`` method has been removed. It's recommended that you switch all +uses of ``cakeError`` to use exceptions. ``cakeError`` was removed because it +was simulating exceptions. Instead of simulation, real exceptions are used in +CakePHP 2.0. + +Error handling +============== + +The error handling implementation has dramatically changed in 2.0. Exceptions +have been introduced throughout the framework, and error handling has been +updated to offer more control and flexibility. You can read more in the +:doc:`/development/exceptions` and :doc:`/development/errors` section. + +Lib classes +=========== + +App +--- + +The API for ``App::build()`` has changed to ``App::build($paths, $mode).`` It +now allows you to either append, prepend or reset/replace existing paths. The +$mode param can take any of the following 3 values: App::APPEND, +App::PREPEND, ``App::RESET``. The default behavior of the function remains the +same (ie. Prepending new paths to existing list). + +App::path() +~~~~~~~~~~~ + +* Now supports plugins, App::path('Controller', 'Users') will return the folder + location of the controllers in the Users plugin. +* Won't merge core paths anymore, it will + only return paths defined in App::build() or default ones in app (or + corresponding plugin). + +App::build() +~~~~~~~~~~~~ + +* Will not merge app path with core paths anymore. + +App::objects() +~~~~~~~~~~~~~~ + +* Now supports plugins, App::objects('Users.Model') will return the models in + plugin Users. +* Returns array() instead of false for empty results or invalid types. +* Does not return core objects anymore, App::objects('core') will return array(). +* Returns the complete class name. + +App class lost the following properties, use method App::path() to access their value + +* App::$models +* App::$behaviors +* App::$controllers +* App::$components +* App::$datasources +* App::$libs +* App::$views +* App::$helpers +* App::$plugins +* App::$vendors +* App::$locales +* App::$shells + +App::import() +~~~~~~~~~~~~~ + +* No longer looks for classes recursively, it strictly uses the values for the + paths defined in App::build(). +* Will not be able to load App::import('Component', 'Component') use + App::uses('Component', 'Controller'); +* Using App::import('Lib', 'CoreClass') to load core classes is no longer + possible. +* Importing a non-existent file, supplying a wrong type or package name, or null + values for $name and $file parameters will result in a false return value. +* App::import('Core', 'CoreClass') is no longer supported, use App::uses() + instead and let the class autoloading do the rest. +* Loading Vendor files does not look recursively in the vendors folder, it will + also no longer convert the file to underscored as it did in the past. + +App::core() +~~~~~~~~~~~ + +* First parameter is no longer optional, it will always return one path +* It can't be used anymore to get the vendors paths +* It will only accept new style package names + +Class loading with App::uses() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Although there has been a huge refactoring in how the classes are loaded, in very +few occasions you will need to change your application code to respect the way you were +used to doing it. The biggest change is the introduction of a new method:: + + App::uses('AuthComponent', 'Controller/Component'); + +We decided the function name should emulate PHP 5.3's ``use`` keyword, just as a way +of declaring where a class name should be located. The first parameter of +:php:meth:`App::uses()` is the complete name of the class you intend to load, +and the second one, the package name (or namespace) where it belongs to. The +main difference with CakePHP 1.3's :php:meth:`App::import()` is that the former +won't actually import the class, it will just setup the system so when the class +is used for the first time it will be located. + +Some examples on using :php:meth:`App::uses()` when migrating from +:php:meth:`App::import()`:: + + App::import('Controller', 'Pages'); + // becomes + App::uses('PagesController', 'Controller'); + + App::import('Component', 'Auth'); + // becomes + App::uses('AuthComponent', 'Controller/Component'); + + App::import('View', 'Media'); + // becomes + App::uses('MediaView', 'View'); + + App::import('Core', 'Xml'); + // becomes + App::uses('Xml', 'Utility'); + + App::import('Datasource', 'MongoDb.MongoDbSource'); + // becomes + App::uses('MongoDbSource', 'MongoDb.Model/Datasource'); + +All classes that were loaded in the past using ``App::import('Core', $class);`` +will need to be loaded using ``App::uses()`` referring to the correct package. +See the API to locate the classes in their new folders. Some examples:: + + App::import('Core', 'CakeRoute'); + // becomes + App::uses('CakeRoute', 'Routing/Route'); + + App::import('Core', 'Sanitize'); + // becomes + App::uses('Sanitize', 'Utility'); + + App::import('Core', 'HttpSocket'); + // becomes + App::uses('HttpSocket', 'Network/Http'); + +In contrast to how :php:meth:`App::import()` worked in the past, the new class +loader will not locate classes recursively. This led to an impressive +performance gain even on develop mode, at the cost of some seldom used features +that always caused side effects. To be clear again, the class loader will only +fetch the class in the exact package in which you told it to find it. + +App::build() and core paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:php:meth:`App::build()` will not merge app paths with core paths anymore. + +Examples:: + + App::build(array('controllers' => array('/full/path/to/controllers'))); + //becomes + App::build(array('Controller' => array('/full/path/to/Controller'))); + + App::build(array('helpers' => array('/full/path/to/controllers'))); + //becomes + App::build(array('View/Helper' => array('/full/path/to/View/Helper'))); + +CakeLog +------- + +- Log streams now need to implement :php:class:`CakeLogInterface`. Exceptions will be raised + if a configured logger does not. + +Cache +----- + +- :php:class:`Cache` is now a static class, it no longer has a getInstance() method. +- CacheEngine is now an abstract class. You cannot directly create instances of + it anymore. +- CacheEngine implementations must extend CacheEngine, exceptions will be + raised if a configured class does not. +- FileCache now requires trailing slashes to be added to the path setting when + you are modifying a cache configuration. +- Cache no longer retains the name of the last configured cache engine. This + means that operations you want to occur on a specific engine need to have the + $config parameter equal to the config name you want the operation to occur + on. + +:: + + Cache::config('something'); + Cache::write('key', $value); + + // would become + Cache::write('key', $value, 'something'); + +Router +------ + +- You can no longer modify named parameter settings with + ``Router::setRequestInfo()``. You should use ``Router::connectNamed()`` to + configure how named parameters are handled. +- Router no longer has a ``getInstance()`` method. It is a static class, call + its methods and properties statically. +- ``Router::getNamedExpressions()`` is deprecated. Use the new router + constants. ``Router::ACTION``, ``Router::YEAR``, ``Router::MONTH``, + ``Router::DAY``, ``Router::ID``, and ``Router::UUID`` instead. +- ``Router::defaults()`` has been removed. Delete the core routes file + inclusion from your applications routes.php file to disable default routing. + Conversely if you want default routing, you will have to add an include to + ``Cake/Config/routes.php`` in your routes file. +- When using Router::parseExtensions() the extension parameter is no longer + under ``$this->params['url']['ext']``. Instead it is available at + ``$this->request->params['ext']``. +- Default plugin routes have changed. Plugin short routes are no longer built + in for any actions other than index. Previously ``/users`` and ``/users/add`` + would map to the UsersController in the Users plugin. In 2.0, only the + ``index`` action is given a short route. If you wish to continue using short + routes, you can add a route like:: + + Router::connect( + '/users/:action', + array('controller' => 'users', 'plugin' => 'users') + ); + + To your routes file for each plugin you need short routes on. + +Your app/Config/routes.php file needs to be updated adding this line at the bottom of the file:: + + require CAKE . 'Config' . DS . 'routes.php'; + +This is needed in order to generate the default routes for your application. If you do not wish to have such routes, +or want to implement your own standard you can include your own file with custom router rules. + +Dispatcher +---------- + +- Dispatcher has been moved inside of cake/libs, you will have to update your + ``app/webroot/index.php`` file. +- ``Dispatcher::dispatch()`` now takes two parameters. The request and + response objects. These should be instances of ``CakeRequest`` & + ``CakeResponse`` or a subclass thereof. +- ``Dispatcher::parseParams()`` now only accepts a ``CakeRequest`` object. +- ``Dispatcher::baseUrl()`` has been removed. +- ``Dispatcher::getUrl()`` has been removed. +- ``Dispatcher::uri()`` has been removed. +- ``Dispatcher::$here`` has been removed. + +Configure +--------- + +- ``Configure::read()`` with no parameter no longer returns the value of + 'debug' instead it returns all values in Configure. Use + ``Configure::read('debug');`` if you want the value of debug. +- ``Configure::load()`` now requires a ConfigReader to be setup. Read + :ref:`loading-configuration-files` for more information. +- ``Configure::store()`` now writes values to a given Cache configuration. Read + :ref:`loading-configuration-files` for more information. + +Scaffold +-------- + +- Scaffold 'edit' views should be renamed to 'form'. This was done to make + scaffold and bake templates consistent. + + - ``views/scaffolds/edit.ctp`` -> ``View/Scaffolds/form.ctp`` + - ``views/posts/scaffold.edit.ctp`` -> ``View/Posts/scaffold.form.ctp`` + +Xml +--- + +- The class Xml was completely re-factored. Now this class does not manipulate + data anymore, and it is a wrapper to SimpleXMLElement. You can use the following + methods: + + - ``Xml::build()``: static method that you can pass an xml string, array, path + to file or url. The result will be a SimpleXMLElement instance or an + exception will be thrown in case of error. + - ``Xml::fromArray():`` static method that returns a SimpleXMLElement from an + array. + - ``Xml::toArray()``: static method that returns an array from + SimpleXMLElement. + +You should see the :php:class:`Xml` documentation for more information on the changes made to +the Xml class. + +Inflector +--------- + +- Inflector no longer has a ``getInstance()`` method. +- ``Inflector::slug()`` no longer supports the $map argument. Use + ``Inflector::rules()`` to define transliteration rules. + +CakeSession +----------- + +CakeSession is now a fully static class, both ``SessionHelper`` and +``SessionComponent`` are wrappers and sugar for it. It can now easily be used +in models or other contexts. All of its methods are called statically. + +Session configuration has also changed :doc:`see the session section for more +information ` + +HttpSocket +---------- + +- HttpSocket doesn't change the header keys. Following other places in core, + the HttpSocket does not change the headers. :rfc:`2616` says that headers are case + insensitive, and HttpSocket preserves the values the remote host sends. +- HttpSocket returns responses as objects now. Instead of arrays, HttpSocket + returns instances of HttpResponse. See the :php:class:`HttpSocket` + documentation for more information. +- Cookies are stored internally by host, not per instance. This means that, if + you make two requests to different servers, cookies from domain1 won't be sent + to domain2. This was done to avoid possible security problems. + + +Helpers +======= + +Constructor changed +------------------- + +In order to accommodate View being removed from the ClassRegistry, the signature +of Helper::__construct() was changed. You should update any subclasses to use +the following:: + + public function __construct(View $View, $settings = array()) + +When overriding the constructor you should always call `parent::__construct` as +well. `Helper::__construct` stores the view instance at `$this->_View` for +later reference. The settings are not handled by the parent constructor. + +HelperCollection added +---------------------- + +After examining the responsibilities of each class involved in the View layer, +it became clear that View was handling much more than a single task. The +responsibility of creating helpers is not central to what View does, and was +moved into HelperCollection. HelperCollection is responsible for loading and +constructing helpers, as well as triggering callbacks on helpers. By default, +View creates a HelperCollection in its constructor, and uses it for subsequent +operations. The HelperCollection for a view can be found at `$this->Helpers` + +The motivations for refactoring this functionality came from a few issues. + +* View being registered in ClassRegistry could cause registry poisoning issues + when requestAction or the EmailComponent were used. +* View being accessible as a global symbol invited abuse. +* Helpers were not self contained. After constructing a helper, you had to + manually construct several other objects in order to get a functioning object. + +You can read more about HelperCollection in the +:doc:`/core-libraries/collections` documentation. + +Deprecated properties +--------------------- + +The following properties on helpers are deprecated, you should use the request +object properties or Helper methods instead of directly accessing these +properties as they will be removed in a future release. + +- ``Helper::$webroot`` is deprecated, use the request object's webroot + property. +- ``Helper::$base`` is deprecated, use the request object's base property. +- ``Helper::$here`` is deprecated, use the request object's here property. +- ``Helper::$data`` is deprecated, use the request object's data property. +- ``Helper::$params`` is deprecated, use the ``$this->request`` instead. + +XmlHelper, AjaxHelper and JavascriptHelper removed +-------------------------------------------------- + +The AjaxHelper and JavascriptHelper have been removed as they were deprecated in +version 1.3. The XmlHelper was removed, as it was made obsolete and redundant +with the improvements to :php:class:`Xml`. The ``Xml`` class should be used to +replace previous usage of XmlHelper. + +The AjaxHelper, and JavascriptHelper are replaced with the JsHelper and HtmlHelper. + +JsHelper +-------- + +- ``JsBaseEngineHelper`` is now abstract, you will need to implement all the + methods that previously generated errors. + +PaginatorHelper +--------------- + +- ``PaginatorHelper::sort()`` now takes the title and key arguments in the + reverse order. $key will always be first now. This was done to prevent + needing to swap arguments when adding a second one. +- PaginatorHelper had a number of changes to the paging params used internally. + The default key has been removed. +- PaginatorHelper now supports generating links with paging parameters in the + querystring. + +There have been a few improvements to pagination in general. For more +information on that you should read the new pagination features page. + +FormHelper +---------- + +$selected parameter removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$selected`` parameter was removed from several methods in ``FormHelper``. +All methods now support a ``$attributes['value']`` key now which should be used +in place of ``$selected``. This change simplifies the ``FormHelper`` methods, +reducing the number of arguments, and reduces the duplication that ``$selected`` +created. The effected methods are: + +- FormHelper::select() +- FormHelper::dateTime() +- FormHelper::year() +- FormHelper::month() +- FormHelper::day() +- FormHelper::hour() +- FormHelper::minute() +- FormHelper::meridian() + +Default URLs on forms is the current action +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The default url for all forms, is now the current url including passed, named, +and querystring parameters. You can override this default by supplying +``$options['url']`` in the second parameter of ``$this->Form->create()``. + +FormHelper::hidden() +~~~~~~~~~~~~~~~~~~~~ + +Hidden fields no longer remove the class attribute. This means that if there are +validation errors on hidden fields, the ``error-field`` class name will be +applied. + +CacheHelper +----------- + +CacheHelper has been fully decoupled from View, and uses helper callbacks to +generate caches. You should remember to place CacheHelper after other helpers +that modify content in their ``afterRender`` and ``afterLayout`` callbacks. If +you don't some changes will not be part of the cached content. + +CacheHelper also no longer uses ```` to indicate un-cached +regions. Instead it uses special HTML/XML comments. ```` and +````. This helps CacheHelper generate valid markup and still +perform the same functions as before. You can read more CacheHelper and View +changes. + +Helper Attribute format more flexible +------------------------------------- + +The Helper class has more 3 protected attributes: + +* ``Helper::_minimizedAttributes``: array with minimized attributes (ie: + ``array('checked', 'selected', ...)``); +* ``Helper::_attributeFormat``: how attributes will be generated (ie: + ``%s="%s"``); +* ``Helper::_minimizedAttributeFormat``: how minimized attributes will be + generated: (ie ``%s="%s"``) + +By default the values used in CakePHP 1.3 were not changed. But now you can +use boolean attributes from HTML, like ````. To +this, just change ``$_minimizedAttributeFormat`` in your AppHelper to ``%s``. + +To use with Html/Form helpers and others, you can write:: + + $this->Form->checkbox('field', array('checked' => true, 'value' => 'some_value')); + +Other facility is that minimized attributes can be passed as item and not as +key. For example:: + + $this->Form->checkbox('field', array('checked', 'value' => 'some_value')); + +Note that ``checked`` have a numeric key. + +Controller +========== + +- Controller's constructor now takes two parameters. A CakeRequest, and + CakeResponse objects. These objects are used to populate several deprecated + properties and will be set to $request and $response inside the controller. +- ``Controller::$webroot`` is deprecated, use the request object's webroot + property. +- ``Controller::$base`` is deprecated, use the request object's base property. +- ``Controller::$here`` is deprecated, use the request object's here property. +- ``Controller::$data`` is deprecated, use the request object's data property. +- ``Controller::$params`` is deprecated, use the ``$this->request`` instead. +- ``Controller::$Component`` has been moved to ``Controller::$Components``. See + the :doc:`/core-libraries/collections` documentation for more information. +- ``Controller::$view`` has been renamed to ``Controller::$viewClass``. + ``Controller::$view`` is now used to change which view file is rendered. +- ``Controller::render()`` now returns a CakeResponse object. + +The deprecated properties on Controller will be accessible through a ``__get()`` +method. This method will be removed in future versions, so it's recommended that +you update your application. + +Controller now defines a maxLimit for pagination. This maximum limit is set to +100, but can be overridden in the $paginate options. + + +Pagination +---------- + +Pagination has traditionally been a single method in Controller, this created a +number of problems though. Pagination was hard to extend, replace, or modify. For +2.0 pagination has been extracted into a component. :php:meth:`Controller::paginate()` still +exists, and serves as a convenience method for loading and using the +:php:class:`PaginatorComponent`. + +For more information on the new features offered by pagination in 2.0, see the +:doc:`/core-libraries/components/pagination` documentation. + +View +==== + +View no longer registered in ClassRegistry +------------------------------------------ + +The view being registered ClassRegistry invited abuse and affectively created a +global symbol. In 2.0 each Helper receives the current `View` instance in its +constructor. This allows helpers access to the view in a similar fashion as in +the past, without creating global symbols. You can access the view instance at +`$this->_View` in any helper. + +Deprecated properties +--------------------- + +- ``View::$webroot`` is deprecated, use the request object's webroot property. +- ``View::$base`` is deprecated, use the request object's base property. +- ``View::$here`` is deprecated, use the request object's here property. +- ``View::$data`` is deprecated, use the request object's data property. +- ``View::$params`` is deprecated, use the ``$this->request`` instead. +- ``View::$loaded`` has been removed. Use the ``HelperCollection`` to access + loaded helpers. +- ``View::$model`` has been removed. This behavior is now on :php:class:`Helper` +- ``View::$modelId`` has been removed. This behavior is now on + :php:class:`Helper` +- ``View::$association`` has been removed. This behavior is now on + :php:class:`Helper` +- ``View::$fieldSuffix`` has been removed. This behavior is now on + :php:class:`Helper` +- ``View::entity()`` has been removed. This behavior is now on + :php:class:`Helper` +- ``View::_loadHelpers()`` has been removed, used ``View::loadHelpers()`` + instead. +- How ``View::element()`` uses caching has changed, see below for more + information. +- View callbacks have been shifted around, see below for more information +- API for ``View::element()`` has changed. Read here for more info. + +The deprecated properties on View will be accessible through a ``__get()`` +method. This method will be removed in future versions, so it's recommended that +you update your application. + +Removed methods +--------------- + +* ``View::_triggerHelpers()`` Use ``$this->Helpers->trigger()`` instead. +* ``View::_loadHelpers()`` Use ``$this->loadHelpers()`` instead. Helpers now lazy + load their own helpers. + +Added methods +------------- + +* ``View::loadHelper($name, $settings = array());`` Load a single helper. +* ``View::loadHelpers()`` Loads all the helpers indicated in ``View::$helpers``. + +View->Helpers +------------- + +By default View objects contain a :php:class:`HelperCollection` at ``$this->Helpers``. + +Themes +------ + +To use themes in your Controller you no longer set ``public $view = 'Theme';``. +Use ``public $viewClass = 'Theme';`` instead. + +Callback positioning changes +---------------------------- + +beforeLayout used to fire after scripts_for_layout and content_for_layout were +prepared. In 2.0, beforeLayout is fired before any of the special variables are +prepared, allowing you to manipulate them before they are passed to the layout. +The same was done for beforeRender. It is now fired well before any view +variables are manipulated. In addition to these changes, helper callbacks always +receive the name of the file about to be rendered. This combined with helpers +being able to access the view through ``$this->_View`` and the current view +content through ``$this->_View->output`` gives you more power than ever before. + +Helper callback signature changes +--------------------------------- + +Helper callbacks now always get one argument passed in. For beforeRender and +afterRender it is the view file being rendered. For beforeLayout and afterLayout +it is the layout file being rendered. Your helpers function signatures should +look like:: + + public function beforeRender($viewFile) { + + } + + public function afterRender($viewFile) { + + } + + public function beforeLayout($layoutFile) { + + } + + public function afterLayout($layoutFile) { + + } + + +Element caching, and view callbacks have been changed in 2.0 to help provide you +with more flexibility and consistency. :doc:`Read more about those +changes `. + +CacheHelper decoupled +--------------------- + +In previous versions there was a tight coupling between :php:class:`CacheHelper` +and :php:class:`View`. For 2.0 this coupling has been removed and CacheHelper +just uses callbacks like other helpers to generate full page caches. + + +CacheHelper ```` tags changed +------------------------------------------- + +In previous versions, CacheHelper used a special ```` tag as +markers for output that should not be part of the full page cache. These tags +were not part of any XML schema, and were not possible to validate in HTML or +XML documents. For 2.0, these tags have been replaced with HTML/XML comments:: + + becomes + becomes + +The internal code for full page view caches has also changed, so be sure to +clear out view cache files when updating. + +MediaView changes +----------------- + +:php:func:`MediaView::render()` now forces download of unknown file types +instead of just returning false. If you want you provide an alternate download +filename you now specify the full name including extension using key 'name' in +the array parameter passed to the function. + + +PHPUnit instead of SimpleTest +============================= + +All of the core test cases and supporting infrastructure have been ported to use +PHPUnit 3.5. Of course you can continue to use SimpleTest in your application by +replacing the related files. No further support will be given for SimpleTest and +it is recommended that you migrate to PHPUnit as well. For some additional +information on how to migrate your tests see PHPUnit migration hints. + +No more group tests +------------------- + +PHPUnit does not differentiate between group tests and single test cases in the +runner. Because of this, the group test options, and support for old style group +tests has been removed. It is recommended that GroupTests be ported to +``PHPUnit_Framework_Testsuite`` subclasses. You can find several examples of this +in CakePHP's test suite. Group test related methods on ``TestManager`` have also +been removed. + +Testsuite shell +--------------- + +The testsuite shell has had its invocation simplified and expanded. You no +longer need to differentiate between ``case`` and ``group``. It is assumed that +all tests are cases. In the past you would have done +``cake testsuite app case models/post`` you can now do ``cake testsuite app +Model/Post``. + + +The testsuite shell has been refactored to use the PHPUnit cli tool. It now +supports all the command line options supported by PHPUnit. +``cake testsuite help`` will show you a list of all possible modifiers. + +Models +====== + +Model relationships are now lazy loaded. You can run into a situation where +assigning a value to a nonexistent model property will throw errors:: + + $Post->inexistentProperty[] = 'value'; + +will throw the error "Notice: Indirect modification of overloaded property +$inexistentProperty has no effect". Assigning an initial value to the property +solves the issue:: + + $Post->nonexistentProperty = array(); + $Post->nonexistentProperty[] = 'value'; + +Or just declare the property in the model class:: + + class Post { + public $nonexistentProperty = array(); + } + +Either of these approaches will solve the notice errors. + +The notation of ``find()`` in CakePHP 1.2 is no longer supported. Finds should use +notation ``$model->find('type', array(PARAMS))`` in CakePHP 1.3. + +- ``Model::$_findMethods`` is now ``Model::$findMethods``. This property is now + public and can be modified by behaviors. + + + +Database objects +---------------- + +CakePHP 2.0 introduces some changes to Database objects that should not greatly +affect backwards compatibility. The biggest one is the adoption of PDO for +handling database connections. If you are using a vanilla installation of PHP 5 +you will already have installed the needed extensions, but you may need to +activate individual extensions for each driver you wish to use. + +Using PDO across all DBOs let us homogenize the code for each one and provide +more reliable and predictable behavior for all drivers. It also allowed us to +write more portable and accurate tests for database related code. + +The first thing users will probably miss is the "affected rows" and "total rows" +statistics, as they are not reported due to the more performant and lazy design +of PDO, there are ways to overcome this issue but very specific to each +database. Those statistics are not gone, though, but could be missing or even +inaccurate for some drivers. + +A nice feature added after the PDO adoption is the ability to use prepared +statements with query placeholders using the native driver if available. + +List of Changes +~~~~~~~~~~~~~~~ + +* DboMysqli was removed, we will support DboMysql only. +* API for DboSource::execute has changed, it will now take an array of query + values as second parameter:: + + public function execute($sql, $params = array(), $options = array()) + + became:: + + public function execute($sql, $options = array(), $params = array()) + + third parameter is meant to receive options for logging, currently it only + understands the "log" option. + +* DboSource::value() looses its third parameter, it was not used anyways +* DboSource::fetchAll() now accepts an array as second parameter, to pass values + to be bound to the query, third parameter was dropped. Example:: + + $db->fetchAll( + 'SELECT + * from users + WHERE + username = ? + AND + password = ?', + array('jhon', '12345') + ); + $db->fetchAll( + 'SELECT + * from users + WHERE + username = :username + AND + password = :password', + array('username' => 'jhon', 'password' => '12345') + ); + +The PDO driver will automatically escape those values for you. + +* Database statistics are collected only if the "fullDebug" property of the + corresponding DBO is set to true. +* New method DboSource::getConnection() will return the PDO object in case you + need to talk to the driver directly. +* Treatment of boolean values changed a bit to make it more cross-database + friendly, you may need to change your test cases. +* Postgresql support was immensely improved, it now correctly creates schemas, + truncate tables, and is easier to write tests using it. +* DboSource::insertMulti() will no longer accept sql string, just pass an array + of fields and a nested array of values to insert them all at once +* TranslateBehavior was refactored to use model virtualFields, this makes the + implementation more portable. +* All tests cases with Mysql related stuff were moved to the corresponding + driver test case. This left the DboSourceTest file a bit skinny. +* Transaction nesting support. Now it is possible to start a transaction several + times. It will only be committed if the commit method is called the same + amount of times. +* Sqlite support was greatly improved. The major difference with cake 1.3 is + that it will only support Sqlite 3.x . It is a great alternative for + development apps, and quick at running test cases. +* Boolean column values will be casted to php native boolean type automatically, + so make sure you update your test cases and code if you were expecting the + returned value to be a string or an integer: If you had a "published" column in + the past using mysql all values returned from a find would be numeric in the + past, now they are strict boolean values. + +Behaviors +========= + +BehaviorCollection +------------------ + +- ``BehaviorCollection`` no longer ``strtolower()'s`` mappedMethods. Behavior + mappedMethods are now case sensitive. + +AclBehavior and TreeBehavior +---------------------------- + +- No longer supports strings as configuration. Example:: + + public $actsAs = array( + 'Acl' => 'Controlled', + 'Tree' => 'nested' + ); + + became:: + + public $actsAs = array( + 'Acl' => array('type' => 'Controlled'), + 'Tree' => array('type' => 'nested') + ); + + +Plugins +======= + +Plugins no longer magically append their plugin prefix to components, helpers +and models used within them. You must be explicit with the components, models, +and helpers you wish to use. In the past:: + + public $components = array('Session', 'Comments'); + +Would look in the controller's plugin before checking app/core components. It +will now only look in the app/core components. If you wish to use objects from a +plugin you must put the plugin name:: + + public $components = array('Session', 'Comment.Comments'); + +This was done to reduce hard to debug issues caused by magic misfiring. It also +improves consistency in an application, as objects have one authoritative way to +reference them. + +Plugin App Controller and Plugin App Model +------------------------------------------ + +The plugin AppController and AppModel are no longer located directly in the +plugin folder. They are now placed into the plugin's Controller and Model +folders as such:: + + /app + /Plugin + /Comment + /Controller + CommentAppController.php + /Model + CommentAppModel.php + +Console +======= + +Much of the console framework was rebuilt for 2.0 to address many of the +following issues: + +- Tightly coupled. +- It was difficult to make help text for shells. +- Parameters for shells were tedious to validate. +- Plugin tasks were not reachable. +- Objects with too many responsibilities. + +Backwards incompatible Shell API changes +---------------------------------------- + +- ``Shell`` no longer has an ``AppModel`` instance. This ``AppModel`` instance + was not correctly built and was problematic. +- ``Shell::_loadDbConfig()`` has been removed. It was not generic enough to + stay in Shell. You can use the ``DbConfigTask`` if you need to ask the user + to create a db config. +- Shells no longer use ``$this->Dispatcher`` to access stdin, stdout, and + stderr. They have ``ConsoleOutput`` and ``ConsoleInput`` objects to handle + that now. +- Shells lazy load tasks, and use ``TaskCollection`` to provide an interface + similar to that used for Helpers, Components, and Behaviors for on the fly + loading of tasks. +- ``Shell::$shell`` has been removed. +- ``Shell::_checkArgs()`` has been removed. Configure a ``ConsoleOptionParser`` +- Shells no longer have direct access to ``ShellDispatcher``. You should use + the ``ConsoleInput``, and ``ConsoleOutput`` objects instead. If you need to + dispatch other shells, see the section on 'Invoking other shells from your + shell'. + +Backwards incompatible ShellDispatcher API changes +-------------------------------------------------- + +- ``ShellDispatcher`` no longer has stdout, stdin, stderr file handles. +- ``ShellDispatcher::$shell`` has been removed. +- ``ShellDispatcher::$shellClass`` has been removed. +- ``ShellDispatcher::$shellName`` has been removed. +- ``ShellDispatcher::$shellCommand`` has been removed. +- ``ShellDispatcher::$shellPaths`` has been removed, use + ``App::path('shells');`` instead. +- ``ShellDispatcher`` no longer uses 'help' as a magic method that has special + status. Instead use the ``--help/-h`` options, and an option parser. + +Backwards incompatible Shell Changes +------------------------------------ + +- Bake's ControllerTask no longer takes ``public`` and ``admin`` as passed + arguments. They are now options, indicated like ``--admin`` and ``--public``. + +It's recommended that you use the help on shells you use to see what if any +parameters have changed. It's also recommended that you read the console new +features for more information on new APIs that are available. + +Debugging +========= + +The ``debug()`` function now defaults to outputting HTML safe strings. This is +disabled if being used in the console. The ``$showHtml`` option for ``debug()`` +can be set to false to disable HTML-safe output from debug. + +ConnectionManager +================= + +``ConnectionManager::enumConnectionObjects()`` will now return the current +configuration for each connection created, instead of an array with filename, +class name and plugin, which wasn't really useful. + +When defining database connections you will need to make some changes to the way +configs were defined in the past. Basically in the database configuration class, +the key "driver" is not accepted anymore, only "datasource", in order to make it +more consistent. Also, as the datasources have been moved to packages you will +need to pass the package they are located in. Example:: + + public $default = array( + 'datasource' => 'Database/Mysql', + 'persistent' => false, + 'host' => 'localhost', + 'login' => 'root', + 'password' => 'root', + 'database' => 'cake', + ); + + +.. meta:: + :title lang=en: 2.0 Migration Guide + :description lang=en: This page summarizes the changes from CakePHP 1.3 that will assist in a project migration to 2.0, as well as for a developer reference to get up to date with the changes made to the core since the CakePHP 1.3 branch. + :keywords lang=en: cakephp upgrade,cakephp migration,migration guide,1.3 to 2.0,update cakephp,backwards compatibility,api changes,x versions,directory structure,new features diff --git a/sr/appendices/2-1-migration-guide.rst b/sr/appendices/2-1-migration-guide.rst new file mode 100644 index 000000000..759be4a36 --- /dev/null +++ b/sr/appendices/2-1-migration-guide.rst @@ -0,0 +1,363 @@ +2.1 Migration Guide +################### + +CakePHP 2.1 is a fully API compatible upgrade from 2.0. This page outlines the +changes and improvements made for 2.1. + +AppController, AppHelper, AppModel and AppShell +=============================================== + +These classes are now required to be part of the app directory, as they were +removed from the CakePHP core. If you do not already have these classes, you +can use the following while upgrading:: + + // app/View/Helper/AppHelper.php + App::uses('Helper', 'View'); + class AppHelper extends Helper { + } + + // app/Model/AppModel.php + App::uses('Model', 'Model'); + class AppModel extends Model { + } + + // app/Controller/AppController.php + App::uses('Controller', 'Controller'); + class AppController extends Controller { + } + + // app/Console/Command/AppShell.php + App::uses('Shell', 'Console'); + class AppShell extends Shell { + } + +If your application already has these files/classes you don't need to do +anything. +Additionally if you were using the core PagesController, you would need to copy +this to your app/Controller directory as well. + +.htaccess files +=============== + +The default ``.htaccess`` files have changed, you should remember to update them +or update your webservers URL re-writing scheme to match the changes done in +``.htaccess`` + + +Models +====== + +- The ``beforeDelete`` callback will be fired before behaviors beforeDelete callbacks. + This makes it consistent with the rest of the events triggered in the model layer. +- ``Model::find('threaded')`` now accepts ``$options['parent']`` if using other field + then ``parent_id``. Also if the model has TreeBehavior attached and set up with other + parent field, the threaded find will by default use that. +- Parameters for queries using prepared statements will now be part of the SQL + dump. +- Validation arrays can now be more specific with when a field is required. + The ``required`` key now accepts ``create`` and ``update``. These values will + make a field required when creating or updating. +- Model now has a ``schemaName`` property. If your application switches + datasources by modifying :php:attr:`Model::$useDbConfig` you should also + modify ``schemaName`` or use :php:meth:`Model::setDataSource()` method which + handles this for you. + +CakeSession +----------- + +.. versionchanged:: 2.1.1 + CakeSession no longer sets the P3P header, as this is the responsibility of your application. + More info see ticket `#2515 `_ in lighthouse + +Behaviors +========= + +TranslateBehavior +----------------- + +- :php:class:`I18nModel` has been moved into a separate file. + +Exceptions +========== + +The default exception rendering now includes more detailed stack traces +including file excerpts and argument dumps for all functions in the stack. + + +Utility +======= + +Debugger +-------- + +- :php:func:`Debugger::getType()` has been added. It can be used to get the type of + variables. +- :php:func:`Debugger::exportVar()` has been modified to create more readable + and useful output. + +debug() +------- + +`debug()` now uses :php:class:`Debugger` internally. This makes it consistent +with Debugger, and takes advantage of improvements made there. + +Set +--- + +- :php:func:`Set::nest()` has been added. It takes in a flat array and returns a nested array + +File +---- + +- :php:meth:`File::info()` includes filesize & mimetype information. +- :php:meth:`File::mime()` was added. + +Cache +----- + +- :php:class:`CacheEngine` has been moved into a separate file. + +Configure +--------- + +- :php:class:`ConfigReaderInterface` has been moved into a separate file. + +App +--- + +- :php:meth:`App::build()` now has the ability to register new packages using + ``App::REGISTER``. See :ref:`app-build-register` for more information. +- Classes that could not be found on configured paths will be searched inside + ``APP`` as a fallback path. This makes autoloading nested directories in + ``app/Vendor`` easier. + +Console +======= + +Test Shell +---------- + +A new TestShell has been added. It reduces the typing required to run unit +tests, and offers a file path based UI:: + + ./Console/cake test app Model/Post + ./Console/cake test app Controller/PostsController + ./Console/cake test Plugin View/Helper/MyHelper + +The old testsuite shell and its syntax are still available. + +General +------- + +- Generated files no longer contain timestamps with the generation datetime. + +Routing +======= + +Router +------ + +- Routes can now use a special ``/**`` syntax to include all trailing arguments + as a single passed argument. See the section on :ref:`connecting-routes` for + more information. +- :php:meth:`Router::resourceMap()` was added. +- :php:meth:`Router::defaultRouteClass()` was added. This method allows you to + set the default route class used for all future routes that are connected. + +Network +======= + +CakeRequest +----------- + +- Added ``is('requested')`` and ``isRequested()`` for detecting requestAction. + +CakeResponse +------------ + +- Added :php:meth:`CakeResponse::cookie()` for setting cookies. +- Added a number of methods for :ref:`cake-response-caching` + +Controller +========== + +Controller +---------- + +- :php:attr:`Controller::$uses` was modified the default value is now ``true`` + instead of false. Additionally different values are handled slightly + differently, but will behave the same in most cases. + + - ``true`` Will load the default model and merge with AppController. + - An array will load those models and merge with AppController. + - An empty array will not load any models other than those declared in the + base class. + - ``false`` will not load any models, and will not merge with the base class + either. + + +Components +========== + +AuthComponent +------------- + +- :php:meth:`AuthComponent::allow()` no longer accepts ``allow('*')`` as a wildcard + for all actions. Just use ``allow()``. This unifies the API between allow() + and deny(). +- ``recursive`` option was added to all authentication adapters. Allows you to + more easily control the associations stored in the session. + + +AclComponent +------------ + +- :php:class:`AclComponent` no longer lowercases and inflects the class name used for + ``Acl.classname``. Instead it uses the provided value as is. +- Acl backend implementations should now be put in ``Controller/Component/Acl``. +- Acl implementations should be moved into the Component/Acl directory from + Component. For example if your Acl class was called ``CustomAclComponent``, + and was in ``Controller/Component/CustomAclComponent.php``. + It should be moved into ``Controller/Component/Acl/CustomAcl.php``, and be + named ``CustomAcl``. +- :php:class:`DbAcl` has been moved into a separate file. +- :php:class:`IniAcl` has been moved into a separate file. +- :php:class:`AclInterface` has been moved into a separate file. + +Helpers +======= + +TextHelper +---------- + +- :php:meth:`TextHelper::autoLink()`, :php:meth:`TextHelper::autoLinkUrls()`, + :php:meth:`TextHelper::autoLinkEmails()` now HTML escape their input by + default. You can control this with the ``escape`` option. + +HtmlHelper +---------- + +- :php:meth:`HtmlHelper::script()` had a ``block`` option added. +- :php:meth:`HtmlHelper::scriptBlock()` had a ``block`` option added. +- :php:meth:`HtmlHelper::css()` had a ``block`` option added. +- :php:meth:`HtmlHelper::meta()` had a ``block`` option added. +- The ``$startText`` parameter of :php:meth:`HtmlHelper::getCrumbs()` can now be + an array. This gives more control and flexibility over the first crumb link. +- :php:meth:`HtmlHelper::docType()` now defaults to HTML5. +- :php:meth:`HtmlHelper::image()` now has a ``fullBase`` option. +- :php:meth:`HtmlHelper::media()` has been added. You can use this method to + create HTML5 audio/video elements. +- :term:`plugin syntax` support has been added for + :php:meth:`HtmlHelper::script()`, :php:meth:`HtmlHelper::css()`, :php:meth:`HtmlHelper::image()`. + You can now easily link to plugin assets using ``Plugin.asset``. +- :php:meth:`HtmlHelper::getCrumbList()` had the ``$startText`` parameter added. + + +View +==== + +- :php:attr:`View::$output` is deprecated. +- ``$content_for_layout`` is deprecated. Use ``$this->fetch('content');`` + instead. +- ``$scripts_for_layout`` is deprecated. Use the following instead:: + + echo $this->fetch('meta'); + echo $this->fetch('css'); + echo $this->fetch('script'); + + ``$scripts_for_layout`` is still available, but the :ref:`view blocks ` API + gives a more extensible & flexible replacement. +- The ``Plugin.view`` syntax is now available everywhere. You can use this + syntax anywhere you reference the name of a view, layout or element. +- The ``$options['plugin']`` option for :php:meth:`~View::element()` is + deprecated. You should use ``Plugin.element_name`` instead. + +Content type views +------------------ + +Two new view classes have been added to CakePHP. A new :php:class:`JsonView` +and :php:class:`XmlView` allow you to easily generate XML and JSON views. You +can learn more about these classes in the section on +:doc:`/views/json-and-xml-views` + +Extending views +--------------- + +:php:class:`View` has a new method allowing you to wrap or 'extend' a +view/element/layout with another file. See the section on +:ref:`extending-views` for more information on this feature. + +Themes +------ + +The ``ThemeView`` class is deprecated in favor of the ``View`` class. Simply +setting ``$this->theme = 'MyTheme'`` will enable theme support, and all custom +View classes which extend from ``ThemeView`` should extend ``View``. + +View blocks +----------- + +View blocks are a flexible way to create slots or blocks in your views. Blocks +replace ``$scripts_for_layout`` with a more robust and flexible API. See the +section on :ref:`view-blocks` for more information. + + +Helpers +======= + +New callbacks +------------- + +Two new callbacks have been added to Helpers. +:php:meth:`Helper::beforeRenderFile()` and :php:meth:`Helper::afterRenderFile()` +these new callbacks are fired before/after every view fragment is rendered. +This includes elements, layouts and views. + +CacheHelper +----------- + +- ```` tags now work inside elements correctly. + +FormHelper +---------- + +- FormHelper now omits disabled fields from the secured fields hash. This makes + working with :php:class:`SecurityComponent` and disabled inputs easier. +- The ``between`` option when used in conjunction with radio inputs, now behaves + differently. The ``between`` value is now placed between the legend and first + input elements. +- The ``hiddenField`` option with checkbox inputs can now be set to a specific + value such as 'N' rather than just 0. +- The ``for`` attribute for date + time inputs now reflects the first generated + input. This may result in the for attribute changing for generated datetime + inputs. +- The ``type`` attribute for :php:meth:`FormHelper::button()` can be removed now. It still + defaults to 'submit'. +- :php:meth:`FormHelper::radio()` now allows you to disable all options. + You can do this by setting either ``'disabled' => true`` or ``'disabled' => 'disabled'`` + in the ``$attributes`` array. + +PaginatorHelper +--------------- + +- :php:meth:`PaginatorHelper::numbers()` now has a ``currentClass`` option. + + +Testing +======= + +- Web test runner now displays the PHPUnit version number. +- Web test runner now defaults to displaying app tests. +- Fixtures can be created in different datasources other than $test. +- Models loaded using the ClassRegistry and using another datasource will get + their datasource name prepended with ``test_`` (e.g datasource `master` will + try to use `test_master` in the testsuite) +- Test cases are generated with class specific setup methods. + +Events +====== + +- A new generic events system has been built and it replaced the way callbacks + were dispatched. This should not represent any change to your code. +- You can dispatch your own events and attach callbacks to them at will, useful + for inter-plugin communication and easier decoupling of your classes. diff --git a/sr/appendices/2-2-migration-guide.rst b/sr/appendices/2-2-migration-guide.rst new file mode 100644 index 000000000..441eb6cfe --- /dev/null +++ b/sr/appendices/2-2-migration-guide.rst @@ -0,0 +1,327 @@ +2.2 Migration Guide +################### + +CakePHP 2.2 is a fully API compatible upgrade from 2.0/2.1. This page outlines the +changes and improvements made for 2.2. + +.. _required-steps-to-upgrade-2-2: + +Required steps to upgrade +========================= + +When upgrading to CakePHP 2.2 its important to add a few new configuration +values to ``app/Config/bootstrap.php``. Adding these will ensure consistent +behavior with 2.1.x:: + + // Enable the Dispatcher filters for plugin assets, and + // CacheHelper. + Configure::write('Dispatcher.filters', array( + 'AssetDispatcher', + 'CacheDispatcher' + )); + + // Add logging configuration. + CakeLog::config('debug', array( + 'engine' => 'FileLog', + 'types' => array('notice', 'info', 'debug'), + 'file' => 'debug', + )); + CakeLog::config('error', array( + 'engine' => 'FileLog', + 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'), + 'file' => 'error', + )); + +You will also need to modify ``app/Config/core.php``. Change the value of +:php:const:`LOG_ERROR` to :php:const:`LOG_ERR`:: + + define('LOG_ERROR', LOG_ERR); + +When using ``Model::validateAssociated()`` or ``Model::saveAssociated()`` and +primary model validation fails, the validation errors of associated models are no longer wiped out. +``Model::$validationErrors`` will now always show all the errors. +You might need to update your test cases to reflect this change. + +Console +======= + +I18N extract shell +------------------ + +- An option was added to overwrite existing POT files by default:: + + ./Console/cake i18n extract --overwrite + + +Models +====== + +- ``Model::find('count')`` will now call the custom find methods with + ``$state = 'before'`` and ``$queryData['operation'] = 'count'``. + In many cases custom finds already return correct counts for pagination, + but ``'operation'`` key allows more flexibility to build other queries, + or drop joins which are required for the custom finder itself. + As the pagination of custom find methods never worked quite well it required + workarounds for this in the model level, which are now no longer needed. +- ``Model::find('first')`` will now return an empty array when no records are found. + +Datasources +=========== + +- Dbo datasources now supports real nested transactions. If you need to use this + feature in your application, enable it using + ``ConnectionManager::getDataSource('default')->useNestedTransactions = true;`` + +Testing +======= + +- The webrunner now includes links to re-run a test with debug output. +- Generated test cases for Controller now subclass + :php:class:`ControllerTestCase`. + + +Error Handling +============== + +- When repeat exceptions, or exception are raised when rendering error pages, + the new ``error`` layout will be used. It's recommended to not use additional + helpers in this layout as its intended for development level errors only. This + fixes issues with fatal errors in rendering error pages due to helper usage in + the ``default`` layout. +- It is important to copy the ``app/View/Layouts/error.ctp`` into your app + directory. Failing to do so will make error page rendering fail. +- You can now configure application specific console error handling. By setting + ``Error.consoleHandler``, and ``Exception.consoleHandler`` you can define the + callback that will handle errors/exceptions raised in console applications. +- The handler configured in ``Error.handler`` and ``Error.consoleHandler`` will + receive fatal error codes (ie. ``E_ERROR``, ``E_PARSE``, ``E_USER_ERROR``). + +Exceptions +---------- + +- The :php:class:`NotImplementedException` was added. + + +Core +==== + +Configure +--------- + +- :php:meth:`Configure::dump()` was added. It is used to persist configuration + data in durable storage like files. Both :php:class:`PhpReader` and + :php:class:`IniReader` work with it. +- A new config parameter 'Config.timezone' is available in which you can set + users' timezone string. eg. You can do ``Configure::write('Config.timezone', + 'Europe/Paris')``. If a method of ``CakeTime`` class is called with + ``$timezone`` parameter as null and 'Config.timezone' is set, then the value + of 'Config.timezone' will be used. This feature allows you to set users' + timezone just once instead of passing it each time in function calls. + + +Controller +========== + +AuthComponent +------------- + +- The options for adapters defined in :php:attr:`AuthComponent::$authenticate` + now accepts a ``contain`` option. This is used to set containable options for + when user records are loaded. + +CookieComponent +--------------- + +- You can now encrypt cookie values with the rijndael cipher. This requires + the `mcrypt `_ extension to be installed. Using + rijndael gives cookie values actual encryption, and is recommended in place of + the XOR cipher available in previous releases. The XOR cipher is still the + default cipher scheme to maintain compatibility with previous releases. You + can read more in the :php:meth:`Security::rijndael()` documentation. + +Pagination +========== + +- Paginating custom finders will now return correct counts, see Model changes + for more info. + + +Network +======= + +CakeEmail +--------- + +- :php:meth:`CakeEmail::charset()` and :php:meth:`CakeEmail::headerCharset()` + were added. +- Legacy Japanese encodings are now handled correctly. ``ISO-2202-JP`` is used + when the encoding is ``ISO-2202-JP-MS`` which works around a number of issues + in mail clients when dealing with the CP932 and Shift_JIS encodings. +- :php:meth:`CakeEmail::theme()` was added. +- :php:meth:`CakeEmail::domain()` was added. You can use this method to set the + domain name used when sending email from a CLI script or if you want to + control the hostname used to send email. +- You can now define ``theme`` and ``helpers`` in your EmailConfig class. + +CakeRequest +----------- + +- CakeRequest will now automatically decode + ``application/x-www-form-urlencoded`` request bodies on ``PUT`` and ``DELETE`` + requests. This data will be available as ``$this->data`` just like POST data + is. + +Utility +======= + +Set +--- + +- The :php:class:`Set` class is now deprecated, and replaced by the :php:class:`Hash` class. + Set will not be removed until 3.0. +- :php:meth:`Set::expand()` was added. + +Hash +---- + +The :php:class:`Hash` class was added in 2.2. It replaced Set providing a more +consistent, reliable and performant API to doing many of the same tasks Set +does. See the :doc:`/core-utility-libraries/hash` page for more detail. + +CakeTime +-------- + +- The ``$userOffset`` parameter has been replaced with ``$timezone`` parameter + in all relevant functions. So instead of numeric offset you can now pass in a + timezone string or DateTimeZone object. Passing numeric offsets for + ``$timezone`` parameter is still possible for backwards compatibility. +- :php:meth:`CakeTime::timeAgoInWords()` had the ``accuracy`` option added. + This option allows you to specify how accurate formatted times should be. + +- New methods added: + + * :php:meth:`CakeTime::toServer()` + * :php:meth:`CakeTime::timezone()` + * :php:meth:`CakeTime::listTimezones()` + +- The ``$dateString`` parameter in all methods now accepts a DateTime object. + + +Helpers +======= + +FormHelper +---------- + +- FormHelper now better handles adding required classes to inputs. It now + honors the ``on`` key. +- :php:meth:`FormHelper::radio()` now supports an ``empty`` which works similar + to the empty option on ``select()``. +- Added :php:meth:`FormHelper::inputDefaults()` to set common properties for + each of the inputs generated by the helper + +TimeHelper +---------- + +- Since 2.1, TimeHelper uses the CakeTime class for all its relevant methods. + The ``$userOffset`` parameter has been replaced with ``$timezone`` parameter. +- :php:meth:`TimeHelper::timeAgoInWords()` has the ``element`` option added. + This allows you to specify an HTML element to wrap the formatted time. + +HtmlHelper +---------- + +- :php:meth:`HtmlHelper::tableHeaders()` now supports setting attributes per + table cell. + + +Routing +======= + +Dispatcher +---------- + +- Event listeners can now be attached to the dispatcher calls, those will have + the ability to change the request information or the response before it is + sent to the client. Check the full documentation for this new features in + :doc:`/development/dispatch-filters` +- With the addition of :doc:`/development/dispatch-filters` you'll need to + update ``app/Config/bootstrap.php``. See + :ref:`required-steps-to-upgrade-2-2`. + +Router +------ + +- :php:meth:`Router::setExtensions()` has been added. With the new method you can + now add more extensions to be parsed, for example within a plugin routes file. + +Cache +===== + +Redis Engine +------------ + +A new caching engine was added using the `phpredis extension +`_ it is configured similarly to the +Memcache engine. + +Cache groups +------------ + +It is now possible to tag or label cache keys under groups. This makes it +simpler to mass-delete cache entries associated to the same label. Groups are +declared at configuration time when creating the cache engine:: + + Cache::config(array( + 'engine' => 'Redis', + ... + 'groups' => array('post', 'comment', 'user') + )); + +You can have as many groups as you like, but keep in mind they cannot be +dynamically modified. + +The :php:meth:`Cache::clearGroup()` class method was added. It takes the group +name and deletes all entries labeled with the same string. + +Log +=== + +Changes in :php:class:`CakeLog` now require, some additional configuration in +your ``app/Config/bootstrap.php``. See :ref:`required-steps-to-upgrade-2-2`, +and :doc:`/core-libraries/logging`. + +- The :php:class:`CakeLog` class now accepts the same log levels as defined in + `RFC 5424 `_. Several convenience + methods have also been added: + + * :php:meth:`CakeLog::emergency($message, $scope = array())` + * :php:meth:`CakeLog::alert($message, $scope = array())` + * :php:meth:`CakeLog::critical($message, $scope = array())` + * :php:meth:`CakeLog::error($message, $scope = array())` + * :php:meth:`CakeLog::warning($message, $scope = array())` + * :php:meth:`CakeLog::notice($message, $scope = array())` + * :php:meth:`CakeLog::info($message, $scope = array())` + * :php:meth:`CakeLog::debug($message, $scope = array())` + +- A third argument ``$scope`` has been added to :php:meth:`CakeLog::write`. + See :ref:`logging-scopes`. +- A new log engine: :php:class:`ConsoleLog` has been added. + +Model Validation +================ + +- A new object ``ModelValidator`` was added to delegate the work of validating + model data, it should be transparent to the application and fully backwards + compatible. It also exposes a rich API to add, modify and remove validation + rules. Check docs for this object in :doc:`/models/data-validation`. + +- Custom validation functions in your models need to have "public" visibility + so that they are accessible by ``ModelValidator``. + +- New validation rules added: + + * :php:meth:`Validation::naturalNumber()` + * :php:meth:`Validation::mimeType()` + * :php:meth:`Validation::uploadError()` + diff --git a/sr/appendices/2-3-migration-guide.rst b/sr/appendices/2-3-migration-guide.rst new file mode 100644 index 000000000..2c47db0d9 --- /dev/null +++ b/sr/appendices/2-3-migration-guide.rst @@ -0,0 +1,326 @@ +2.3 Migration Guide +################### + +CakePHP 2.3 is a fully API compatible upgrade from 2.2. This page outlines +the changes and improvements made in 2.3. + +Constants +========= + +An application can now easily define :php:const:`CACHE` and :php:const:`LOGS`, +as they are conditionally defined by CakePHP now. + +Caching +======= + +- FileEngine is always the default cache engine. In the past a number of people + had difficulty setting up and deploying APC correctly both in cli + web. + Using files should make setting up CakePHP simpler for new developers. + +- `Configure::write('Cache.viewPrefix', 'YOURPREFIX');` has been added to `core.php` + to allow multiple domains/languages per setup. + +Component +========= + +AuthComponent +------------- +- A new property ``AuthComponent::$unauthorizedRedirect`` has been added. + + - For default ``true`` value user is redirected to referrer URL upon authorization failure. + - If set to a string or array user is redirected to that URL. + - If set to false a ForbiddenException exception is thrown instead of redirecting. + +- A new authenticate adapter has been added to support blowfish/bcrypt hashed + passwords. You can now use ``Blowfish`` in your ``$authenticate`` array to + allow bcrypt passwords to be used. + +- :php:meth:`AuthComponent::redirect()` has been deprecated. + Use :php:meth:`AuthComponent::redirectUrl()` instead. + +PaginatorComponent +------------------ + +- PaginatorComponent now supports the ``findType`` option. This can be used to + specify what find method you want used for pagination. This is a bit easier + to manage and set than the 0'th index. + +- PaginatorComponent now throws a `NotFoundException` when trying to access a page + which is out of range (i.e. requested page is greater than total page count). + +SecurityComponent +----------------- + +- SecurityComponent now supports the ``unlockedActions`` option. This can be used to + disable all security checks for any actions listed in this option. + +RequestHandlerComponent +----------------------- + +- :php:meth:`RequestHandlerComponent::viewClassMap()` has been added, which is used to map a type + to view class name. You can add ``$settings['viewClassMap']`` for automatically setting + the correct viewClass based on extension/content type. + +CookieComponent +--------------- + +- :php:meth:`CookieComponent::check()` was added. This method works the same as + :php:meth:`CakeSession::check()` does. + +Console +======= + +- The ``server`` shell was added. You can use this to start the PHP5.4 + webserver for your CakePHP application. +- Baking a new project now sets the application's cache prefix to the name of + the application. + +I18n +==== + +L10n +---- + +- ``nld`` is now the default locale for Dutch as specified by ISO 639-3 and ``dut`` its alias. + The locale folders have to be adjusted accordingly (from `/Locale/dut/` to `/Locale/nld/`). +- Albanian is now ``sqi``, Basque is now ``eus``, Chinese is now ``zho``, Tibetan is now ``bod``, + Czech is now ``ces``, Farsi is now ``fas``, French is now ``fra``, Icelandic is now ``isl``, + Macedonian is now ``mkd``, Malaysian is now ``msa``, Romanian is now ``ron``, Serbian is now ``srp`` + and Slovak is now ``slk``. The corresponding locale folders have to be adjusted, as well. + +Core +==== + +CakePlugin +---------- + +- :php:meth:`CakePlugin::load()` can now take a new ``ignoreMissing`` option. Setting it to true will + prevent file include errors when you try to load routes or bootstrap but they don't exist for a plugin. + So essentially you can now use the following statement which will load all plugins and their routes and + bootstrap for whatever plugin it can find:: + ``CakePlugin::loadAll(array(array('routes' => true, 'bootstrap' => true, 'ignoreMissing' => true)))`` + + +Configure +--------- + +- :php:meth:`Configure::check()` was added. This method works the same as + :php:meth:`CakeSession::check()` does. + +- :php:meth:`ConfigReaderInterface::dump()` was added. Please ensure any custom readers you have now + implement a ``dump()`` method. + +- The ``$key`` parameter of :php:meth:`IniReader::dump()` now supports keys like `PluginName.keyname` + similar to ``PhpReader::dump()``. + +Error +===== + +Exceptions +---------- + +- CakeBaseException was added, which all core Exceptions now extend. The base exception + class also introduces the ``responseHeader()`` method which can be called on created Exception instances + to add headers for the response, as Exceptions don't reuse any response instance. + +Model +===== + +- Support for the biginteger type was added to all core datasources, and + fixtures. +- Support for ``FULLTEXT`` indexes was added for the MySQL driver. + + +Models +------ + +- ``Model::find('list')`` now sets the ``recursive`` based on the max + containment depth or recursive value. When list is used with + ContainableBehavior. +- ``Model::find('first')`` will now return an empty array when no records are found. + +Validation +---------- + +- Missing validation methods will **always** trigger errors now instead of + only in development mode. + +Network +======= + +SmtpTransport +------------- + +- TLS/SSL support was added for SMTP connections. + +CakeRequest +----------- + +- :php:meth:`CakeRequest::onlyAllow()` was added. +- :php:meth:`CakeRequest::query()` was added. + +CakeResponse +------------ + +- :php:meth:`CakeResponse::file()` was added. +- The content types `application/javascript`, `application/xml`, + `application/rss+xml` now also send the application charset. + +CakeEmail +--------- + +- The ``contentDisposition`` option was added to + :php:meth:`CakeEmail::attachments()`. This allows you to disable the + Content-Disposition header added to attached files. + +HttpSocket +---------- + +- :php:class:`HttpSocket` now verifies SSL certificates by default. If you are + using self-signed certificates or connecting through proxies you may need to + use some of the new options to augment this behavior. See + :ref:`http-socket-ssl-options` for more information. +- ``HttpResponse`` was renamed to ``HttpSocketResponse``. This + avoids a common issue with the HTTP PECL extension. There is an + ``HttpResponse`` class provided as well for compatibility reasons. + +Routing +======= + +Router +------ + +- Support for ``tel:``, ``sms:`` were added to :php:meth:`Router::url()`. + +View +==== + +- MediaView is deprecated, and you can use new features in + :php:class:`CakeResponse` to achieve the same results. +- Serialization in Json and Xml views has been moved to ``_serialize()`` +- beforeRender and afterRender callbacks are now being called in Json and Xml + views when using view templates. +- :php:meth:`View::fetch()` now has a ``$default`` argument. This argument can + be used to provide a default value should a block be empty. +- :php:meth:`View::prepend()` has been added to allow prepending content to + existing block. +- :php:class:`XmlView` now uses the ``_rootNode`` view variable to customize the + top level XML node. +- :php:meth:`View::elementExists()` was added. You can use this method to check + if elements exist before using them. +- :php:meth:`View::element()` had the ``ignoreMissing`` option added. You can + use this to suppress the errors triggered by missing view elements. +- :php:meth:`View::startIfEmpty()` was added. + +Layout +------ + +- The doctype for layout files in the app folder and the bake templates in the + cake package has been changed from XHTML to HTML5. + +Helpers +======= + +- New property ``Helper::$settings`` has been added for your helper setting. The + ``$settings`` parameter of ``Helper::__construct()`` is merged with + ``Helper::$settings``. + +FormHelper +---------- + +- :php:meth:`FormHelper::select()` now accepts a list of values in the disabled + attribute. Combined with ``'multiple' => 'checkbox'``, this allows you to + provide a list of values you want disabled. +- :php:meth:`FormHelper::postLink()` now accepts a ``method`` key. This allows + you to create link forms using HTTP methods other than POST. +- When creating inputs with :php:meth:`FormHelper::input()` you can now set the + ``errorMessage`` option to false. This will disable the error message display, + but leave the error class names intact. +- The FormHelper now also adds the HTML5 ``required`` attribute to your input + elements based on validation rules for a field. If you have a "Cancel" button + in your form which submits the form then you should add ``'formnovalidate' => true`` + to your button options to prevent the triggering of validation in HTML. You + can also prevent the validation triggering for the whole form by adding + ``'novalidate' => true`` in your FormHelper::create() options. +- :php:meth:`FormHelper::input()` now generates input elements of type ``tel`` + and ``email`` based on field names if ``type`` option is not specified. + +HtmlHelper +---------- + +- :php:meth:`HtmlHelper::getCrumbList()` now has the ``separator``, + ``firstClass`` and ``lastClass`` options. These allow you to better control + the HTML this method generates. + +TextHelper +---------- + +- :php:meth:`TextHelper::tail()` was added to truncate text starting from the end. +- `ending` in :php:meth:`TextHelper::truncate()` is deprecated in favor of `ellipsis` + +PaginatorHelper +--------------- + +- :php:meth:`PaginatorHelper::numbers()` now has a new option ``currentTag`` to + allow specifying extra tag for wrapping current page number. +- For methods: :php:meth:`PaginatorHelper::prev()` and :php:meth:`PaginatorHelper::next()` it + is now possible to set the ``tag`` option to ``false`` to disable the wrapper. + Also a new option `disabledTag` has been added for these two methods. + + +Testing +======= + +- A core fixture for the default ``cake_sessions`` table was added. You can use + it by adding ``core.cake_sessions`` to your fixture list. +- :php:meth:`CakeTestCase::getMockForModel()` was added. This simplifies getting + mock objects for models. + +Utility +======= + +CakeNumber +---------- + +- :php:meth:`CakeNumber::fromReadableSize()` was added. +- :php:meth:`CakeNumber::formatDelta()` was added. +- :php:meth:`CakeNumber::defaultCurrency()` was added. + +Folder +------ + +- :php:meth:`Folder::copy()` and :php:meth:`Folder::move()` now support the + ability to merge the target and source directories in addition to + skip/overwrite. + + +String +------ + +- :php:meth:`String::tail()` was added to truncate text starting from the end. +- `ending` in :php:meth:`String::truncate()` is deprecated in favor of `ellipsis` + +Debugger +-------- + +- :php:meth:`Debugger::exportVar()` now outputs private and protected properties + in PHP >= 5.3.0. + +Security +-------- + +- Support for `bcrypt `_ + was added. See the :php:class:`Security::hash()` documentation for more + information on how to use bcrypt. + +Validation +---------- + +- :php:meth:`Validation::fileSize()` was added. + +ObjectCollection +---------------- + +- :php:meth:`ObjectCollection::attached()` was deprecated in favor of the new + method :php:meth:`ObjectCollection::loaded()`. This unifies the access to the + ObjectCollection as load()/unload() already replaced attach()/detach(). diff --git a/sr/appendices/2-4-migration-guide.rst b/sr/appendices/2-4-migration-guide.rst new file mode 100644 index 000000000..73094f212 --- /dev/null +++ b/sr/appendices/2-4-migration-guide.rst @@ -0,0 +1,294 @@ +2.4 Migration Guide +################### + +CakePHP 2.4 is a fully API compatible upgrade from 2.3. This page outlines +the changes and improvements made in 2.4. + +Console +======= + +- Logged notice messages will now be colourized in terminals that support + colours. +- ConsoleShell is now deprecated. + +SchemaShell +----------- + +- ``cake schema generate`` now supports the ``--exclude`` parameter. +- The constant ``CAKEPHP_SHELL`` is now deprecated and will be removed in CakePHP 3.0. + +BakeShell +--------- + +- ``cake bake model`` now supports baking ``$behaviors``. Finding `lft`, `rght` and `parent_id` fields + in your table it will add the Tree behavior, for example. You can also extend the ModelTask to support your own + behaviors to be recognized. +- ``cake bake`` for views, models, controllers, tests and fixtures now supports a ``-f`` or ``--force`` parameter to + force overwriting of files. +- Tasks in core can now be aliased in the same way you would Helpers, Components and Behaviors + +FixtureTask +----------- + +- ``cake bake fixture`` now supports a ``--schema`` parameter to allow baking all fixtures with noninteractive "all" + while using schema import. + +Core +==== + +Constants +--------- + +- Constants ``IMAGES_URL``, ``JS_URL``, ``CSS_URL`` have been deprecated and + replaced with config variables ``App.imageBaseUrl``, ``App.jsBaseUrl``, + ``App.cssBaseUrl`` respectively. + +- Constants ``IMAGES``, ``JS``, ``CSS`` have been deprecated. + +Object +------ + +- :php:meth:`Object::log()` had the ``$scope`` parameter added. + + +Components +========== + +AuthComponent +------------- +- AuthComponent now supports proper stateless mode when using 'Basic' or 'Digest' + authenticators. Starting of session can be prevented by setting :php:attr:`AuthComponent::$sessionKey` + to false. Also now when using only 'Basic' or 'Digest' you are no longer + redirected to login page. For more info check the :php:class:`AuthComponent` page. +- Property :php:attr:`AuthComponent::$authError` can be set to boolean ``false`` to suppress flash message from being displayed. + +PasswordHasher +-------------- +- Authenticating objects now use new password hasher objects for password hash + generation and checking. See :ref:`hashing-passwords` for more info. + +DbAcl +----- + +- DbAcl now uses ``INNER`` joins instead of ``LEFT`` joins. This improves + performance for some database vendors. + +Model +===== + +Models +------ + +- :php:meth:`Model::save()`, :php:meth:`Model::saveField()`, :php:meth:`Model::saveAll()`, + :php:meth:`Model::saveAssociated()`, :php:meth:`Model::saveMany()` + now take a new ``counterCache`` option. You can set it to false to avoid + updating counter cache values for the particular save operation. +- :php:meth:`Model::clear()` was added. + +Datasource +---------- + +- Mysql, Postgres, and SQLserver now support a 'settings' array in the + connection definition. This key => value pair will be issued as ``SET`` commands when the + connection is created. +- Mysql driver now supports SSL options. + + +View +==== + +JsonView +-------- + +- JSONP support has been added to :php:class:`JsonView`. +- The ``_serialize`` key now supports renaming serialized variables. +- When debug > 0 JSON will be pretty printed. + +XmlView +------- + +- The ``_serialize`` key now supports renaming serialized variables. +- When debug > 0 XML will be pretty printed. + +HtmlHelper +---------- + +- The API for :php:meth:`HtmlHelper::css()` has been been simplified. You can + now provide an array of options as the second argument. When you do, the + ``rel`` attribute defaults to 'stylesheet'. +- New option ``escapeTitle`` added to :php:meth:`HtmlHelper::link()` to control + escaping of only link title and not attributes. + +TextHelper +---------- + +- :php:meth:`TextHelper::autoParagraph()` has been added. It allows to + automatically convert text into HTML paragraphs. + +PaginatorHelper +--------------- + +- :php:meth:`PaginatorHelper::param()` has been added. +- The first page no longer contains ``/page:1`` or ``?page=1`` in the URL. This helps prevent + duplicate content issues where you would need to use canonical or noindex otherwise. + +FormHelper +---------- + +- The ``round`` option was added to :php:meth:`FormHelper::dateTime()`. Can be set to ``up`` or ``down`` + to force rounding in either direction. Defaults to null which rounds half up according to ``interval``. + +Network +======= + +CakeRequest +----------- + +- :php:meth:`CakeRequest::param()` has been added. +- :php:meth:`CakeRequest::is()` has been modified to support an array of types and will return true if the request matches any type. +- :php:meth:`CakeRequest::isAll()` has been added to check that a request matches all the given types. + +CakeResponse +------------ + +- :php:meth:`CakeResponse::location()` has been added to get or set the redirect location header. + +CakeEmail +--------- + +- Logged email messages now have the scope of ``email`` by default. If you are + not seeing email contents in your logs, be sure to add the ``email`` scope to + your logging configuration. +- :php:meth:`CakeEmail::emailPattern()` was added. This method can be used to + relax email validation rules. This is useful when dealing with certain + Japanese hosts that allow non-compliant addresses to be used. +- :php:meth:`CakeEmail::attachments()` now allows you to provide the file + contents directly using the ``data`` key. +- Configuration data is now correctly merged with transport classes. + +HttpSocket +---------- + +- :php:meth:`HttpSocket::patch()` has been added. + + +I18n +==== + +L10n +---- + +- ``ell`` is now the default locale for Greek as specified by ISO 639-3 and ``gre`` its alias. + The locale folders have to be adjusted accordingly (from `/Locale/gre/` to `/Locale/ell/`). +- ``fas`` is now the default locale for Farsi as specified by ISO 639-3 and ``per`` its alias. + The locale folders have to be adjusted accordingly (from `/Locale/per/` to `/Locale/fas/`). +- ``sme`` is now the default locale for Sami as specified by ISO 639-3 and ``smi`` its alias. + The locale folders have to be adjusted accordingly (from `/Locale/smi/` to `/Locale/sme/`). +- ``mkd`` replaces ``mk`` as default locale for Macedonian as specified by ISO 639-3. + The corresponding locale folders have to be adjusted, as well. +- Catalog code ``in`` has been dropped in favor of ``id`` (Indonesian), + ``e`` has been dropped in favor of ``el`` (Greek), + ``n`` has been dropped in favor of ``nl`` (Dutch), + ``p`` has been dropped in favor of ``pl`` (Polish), + ``sz`` has been dropped in favor of ``se`` (Sami). +- Kazakh has been added with ``kaz`` as locale and ``kk`` as catalog code. +- Kalaallisut has been added with ``kal`` as locale and ``kl`` as catalog code. +- The constant ``DEFAULT_LANGUAGE`` has been deprecated in favor of Configure value ``Config.language``. + +Logging +======= + +- Log engines do not need the suffix ``Log`` anymore in their setup configuration. So for the + FileLog engine it suffices to define ``'engine' => 'File'`` now. This unifies the way engines + are named in configuration (see Cache engines for example). + Note: If you have a Log engine like ``DatabaseLogger`` that does not follow the convention to + use a suffix ``Log`` for your class name you have to adjust your class name to ``DatabaseLog``. + You should also avoid class names like ``SomeLogLog`` which include the suffix twice at the end. + +FileLog +------- + +- Two new config options ``size`` and ``rotate`` have been added for :ref:`FileLog ` engine. +- In debug mode missing directories will now be automatically created to avoid unnecessary errors thrown. + +SyslogLog +--------- + +- The new logging engine :ref:`SyslogLog ` was added to stream messages to syslog. + +Cache +===== + +FileEngine +---------- + +- In debug mode missing directories will now be automatically created to avoid unnecessary errors thrown. + +Utility +======= + +General +------- + +- :php:func:`pr()` no longer outputs HTML when running in cli mode. + +Sanitize +-------- + +- ``Sanitize`` class has been deprecated. + +Validation +---------- + +- :php:meth:`Validation::date()` now supports the ``y`` and ``ym`` formats. +- The country code of :php:meth:`Validation::phone()` for Canada has been changed from ``can`` to + ``ca`` to unify the country codes for validation methods according to ISO 3166 (two letter codes). + +CakeNumber +---------- + +- The currencies ``AUD``, ``CAD`` and ``JPY`` have been added. +- The symbols for ``GBP`` and ``EUR`` are now UTF-8. If you upgrade a non-UTF-8 application, + make sure that you update the static ``$_currencies`` attribute with the appropriate + HTML entity symbols (``£`` and ``€``) before you use those currencies. +- The ``fractionExponent`` option was added to + :php:meth:`CakeNumber::currency()`. + +CakeTime +-------- + +- :php:meth:`CakeTime::isPast()` and :php:meth:`CakeTime::isFuture()` were + added. +- :php:meth:`CakeTime::timeAgoInWords()` has two new options to customize the output strings: + ``relativeString`` (defaults to ``%s ago``) and ``absoluteString`` (defaults to ``on %s``). +- :php:meth:`CakeTime::timeAgoInWords()` uses fuzzy terms when time is below thresholds. + + +Xml +--- + +- New option ``pretty`` has been added to :php:meth:`Xml::fromArray()` to return nicely formatted Xml + + +Error +===== + +ErrorHandler +------------ + +- New configuration option ``skipLog`` has been added, to allow skipping certain + Exception types to be logged. ``Configure::write('Exception.skipLog', array('NotFoundException', 'ForbiddenException'));`` + will avoid these exceptions and the ones extending them to be be logged when + ``'Exception.log'`` config is ``true`` + +Routing +======= + +Router +------ + +- :php:meth:`Router::fullBaseUrl()` was added together with ``App.fullBaseUrl`` Configure value. They replace + :php:const:`FULL_BASE_URL` which is now deprecated. +- :php:meth:`Router::parse()` now parses query string arguments. + + diff --git a/sr/appendices/cakephp-development-process.rst b/sr/appendices/cakephp-development-process.rst new file mode 100644 index 000000000..a2fc2f09b --- /dev/null +++ b/sr/appendices/cakephp-development-process.rst @@ -0,0 +1,56 @@ +CakePHP Development Process +########################### + +Here we attempt to explain the process we use when developing the +CakePHP framework. We rely heavily on community interaction through +tickets and IRC chat. IRC is the best place to find members of the +`development team `_ and discuss +ideas, the latest code, and make general comments. If something more +formal needs to be proposed or there is a problem with a release, the +ticket system is the best place to share your thoughts. + +We currently maintain 4 versions of CakePHP. + +- **stable** : Tagged releases intended for production where stability + is more important than features. Issues filed against these releases + will be fixed in the related branch, and be part of the next release. +- **maintenance branch** : Development branches become maintenance + branches once a stable release point has been reached. Maintenance + branches are where all bugfixes are committed before making their way + into a stable release. Maintenance branches have the same name as the + major version they are for example *1.2*. If you are using a stable + release and need fixes that haven't made their way into a stable + release check here. +- **development branches** : Development branches contain leading edge + fixes and features. They are named after the version number they are + for example *1.3*. Once development branches have reached a stable + release point they become maintenance branches, and no further new + features are introduced unless absolutely necessary. +- **feature branches** : Feature branches contain unfinished or + possibly unstable features and are recommended only for power users + interested in the most advanced feature set and willing to contribute + back to the community. Feature branches are named with the following + convention *version-feature*. An example would be *1.3-router* Which + would contain new features for the Router for 1.3. + +Hopefully this will help you understand what version is right for you. +Once you pick your version you may feel compelled to contribute a bug +report or make general comments on the code. + +- If you are using a stable version or maintenance branch, please submit + tickets or discuss with us on IRC. +- If you are using the development branch or feature branch, the first + place to go is IRC. If you have a comment and cannot reach us in IRC + after a day or two, please submit a ticket. + +If you find an issue, the best answer is to write a test. The best +advice we can offer in writing tests is to look at the ones included in +the core. + +As always, if you have any questions or comments, visit us at #cakephp +on irc.freenode.net. + + +.. meta:: + :title lang=en: CakePHP Development Process + :keywords lang=en: maintenance branch,community interaction,community feature,necessary feature,stable release,ticket system,advanced feature,power users,feature set,chat irc,leading edge,router,new features,members,attempt,development branches,branch development diff --git a/sr/appendices/glossary.rst b/sr/appendices/glossary.rst new file mode 100644 index 000000000..80ff5cefc --- /dev/null +++ b/sr/appendices/glossary.rst @@ -0,0 +1,70 @@ +Glossary +######## + +.. glossary:: + + routing array + An array of attributes that are passed to :php:meth:`Router::url()`. + They typically look like:: + + array('controller' => 'posts', 'action' => 'view', 5) + + HTML attributes + An array of key => values that are composed into HTML attributes. For example:: + + // Given + array('class' => 'my-class', 'target' => '_blank') + + // Would generate + class="my-class" target="_blank" + + If an option can be minimized or accepts it's name as the value, then ``true`` + can be used:: + + // Given + array('checked' => true) + + // Would generate + checked="checked" + + plugin syntax + Plugin syntax refers to the dot separated class name indicating classes + are part of a plugin. E.g. ``DebugKit.Toolbar`` The plugin is DebugKit, + and the class name is Toolbar. + + dot notation + Dot notation defines an array path, by separating nested levels with ``.`` + For example:: + + Asset.filter.css + + Would point to the following value:: + + array( + 'Asset' => array( + 'filter' => array( + 'css' => 'got me' + ) + ) + ) + + CSRF + Cross Site Request Forgery. Prevents replay attacks, double + submissions and forged requests from other domains. + + routes.php + A file in APP/Config that contains routing configuration. + This file is included before each request is processed. + It should connect all the routes your application needs so + requests can be routed to the correct controller + action. + + DRY + Don't repeat yourself. Is a principle of software development aimed at + reducing repetition of information of all kinds. In CakePHP DRY is used + to allow you to code things once and re-use them across your + application. + + +.. meta:: + :title lang=en: Glossary + :keywords lang=en: html attributes,array class,array controller,glossary glossary,target blank,dot notation,routing configuration,forgery,replay,router,syntax,config,submissions diff --git a/sr/appendices/migrating-from-cakephp-1-2-to-1-3.rst b/sr/appendices/migrating-from-cakephp-1-2-to-1-3.rst new file mode 100644 index 000000000..5c49c43bd --- /dev/null +++ b/sr/appendices/migrating-from-cakephp-1-2-to-1-3.rst @@ -0,0 +1,778 @@ +Migrating from CakePHP 1.2 to 1.3 +################################# + +This guide summarizes many of the changes necessary when migrating +from a 1.2 to 1.3 CakePHP core. Each section contains relevant +information for the modifications made to existing methods as well +as any methods that have been removed/renamed. + +**App File Replacements (important)** + + +- webroot/index.php: Must be replaced due to changes in + bootstrapping process. +- config/core.php: Additional settings have been put in place + which are required for PHP 5.3. +- webroot/test.php: Replace if you want to run unit tests. + +Removed Constants +~~~~~~~~~~~~~~~~~ + +The following constants have been removed from CakePHP. If your +application depends on them you must define them in +``app/config/bootstrap.php`` + + +- ``CIPHER_SEED`` - It has been replaced with Configure class var + ``Security.cipherSeed`` which should be changed in + ``app/config/core.php`` +- ``PEAR`` +- ``INFLECTIONS`` +- ``VALID_NOT_EMPTY`` +- ``VALID_EMAIL`` +- ``VALID_NUMBER`` +- ``VALID_YEAR`` + +Configuration and application bootstrapping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Bootstrapping Additional Paths.** + +In your app/config/bootstrap.php you may have variables like +``$pluginPaths`` or ``$controllerPaths``. +There is a new way to add those paths. As of 1.3 RC1 the +``$pluginPaths`` variables will no longer work. You must use +``App::build()`` to modify paths. + +:: + + App::build(array( + 'plugins' => array( + '/full/path/to/plugins/', + '/next/full/path/to/plugins/' + ), + 'models' => array( + '/full/path/to/models/', + '/next/full/path/to/models/' + ), + 'views' => array( + '/full/path/to/views/', + '/next/full/path/to/views/' + ), + 'controllers' => array( + '/full/path/to/controllers/', + '/next/full/path/to/controllers/' + ), + 'datasources' => array( + '/full/path/to/datasources/', + '/next/full/path/to/datasources/' + ), + 'behaviors' => array( + '/full/path/to/behaviors/', + '/next/full/path/to/behaviors/' + ), + 'components' => array( + '/full/path/to/components/', + '/next/full/path/to/components/' + ), + 'helpers' => array( + '/full/path/to/helpers/', + '/next/full/path/to/helpers/' + ), + 'vendors' => array( + '/full/path/to/vendors/', + '/next/full/path/to/vendors/' + ), + 'shells' => array( + '/full/path/to/shells/', + '/next/full/path/to/shells/' + ), + 'locales' => array( + '/full/path/to/locale/', + '/next/full/path/to/locale/' + ), + 'libs' => array( + '/full/path/to/libs/', + '/next/full/path/to/libs/' + ) + )); + +Also changed is the order in which bootstrapping occurs. In the +past ``app/config/core.php`` was loaded **after** +``app/config/bootstrap.php``. This caused any ``App::import()`` in +an application bootstrap to be un-cached and considerably slower +than a cached include. In 1.3 core.php is loaded and the core cache +configs are created **before** bootstrap.php is loaded. + +**Loading custom inflections** + +``inflections.php`` has been removed, it was an unnecessary file +hit, and the related features have been refactored into a method to +increase their flexibility. You now use ``Inflector::rules()`` to +load custom inflections:: + + Inflector::rules('singular', array( + 'rules' => array( + '/^(bil)er$/i' => '\1', + '/^(inflec|contribu)tors$/i' => '\1ta' + ), + 'uninflected' => array('singulars'), + 'irregular' => array('spins' => 'spinor') + )); + +Will merge the supplied rules into the infection sets, with the +added rules taking precedence over the core rules. + +File renames and internal changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Library Renames** + +Core libraries of libs/session.php, libs/socket.php, +libs/model/schema.php and libs/model/behavior.php have been renamed +so that there is a better mapping between filenames and main +classes contained within (as well as dealing with some name-spacing +issues): + + +- session.php -> cake\_session.php + + + - App::import('Core', 'Session') -> App::import('Core', + 'CakeSession') + +- socket.php -> cake\_socket.php + + + - App::import('Core', 'Socket') -> App::import('Core', + 'CakeSocket') + +- schema.php -> cake\_schema.php + + + - App::import('Model', 'Schema') -> App::import('Model', + 'CakeSchema') + +- behavior.php -> model\_behavior.php + + + - App::import('Core', 'Behavior') -> App::import('Core', + 'ModelBehavior') + + +In most cases, the above renaming will not affect userland code. + +**Inheritance from Object** + +The following classes no longer extend Object: + + +- Router +- Set +- Inflector +- Cache +- CacheEngine + +If you were using Object methods from these classes, you will need +to not use those methods. + +Controller & Components +~~~~~~~~~~~~~~~~~~~~~~~ + +**Controller** + + +- ``Controller::set()`` no longer changes variables from + ``$var_name`` to ``$varName``. Variables always appear in the view + exactly as you set them. + +- ``Controller::set('title', $var)`` no longer sets + ``$title_for_layout`` when rendering the layout. + ``$title_for_layout`` is still populated by default. But if you + want to customize it, use + ``$this->set('title_for_layout', $var)``. + +- ``Controller::$pageTitle`` has been removed. Use + ``$this->set('title_for_layout', $var);`` instead. + +- Controller has two new methods ``startupProcess`` and + ``shutdownProcess``. These methods are responsible for handling the + controller startup and shutdown processes. + +**Component** + + +- ``Component::triggerCallback`` has been added. It is a generic + hook into the component callback process. It supplants + ``Component::startup()``, ``Component::shutdown()`` and + ``Component::beforeRender()`` as the preferred way to trigger + callbacks. + +**CookieComponent** + + +- ``del`` is deprecated use ``delete`` + +**AclComponent + DbAcl** + +Node reference checks done with paths are now less greedy and will +no longer consume intermediary nodes when doing searches. In the +past given the structure: + +:: + + ROOT/ + Users/ + Users/ + edit + +The path ``ROOT/Users`` would match the last Users node instead of +the first. In 1.3, if you were expecting to get the last node you +would need to use the path ``ROOT/Users/Users`` + +**RequestHandlerComponent** + + +- ``getReferrer`` is deprecated use ``getReferer`` + +**SessionComponent & SessionHelper** + + +- ``del`` is deprecated use ``delete`` + +``SessionComponent::setFlash()`` second param used to be used for +setting the layout and accordingly rendered a layout file. This has +been modified to use an element. If you specified custom session +flash layouts in your applications you will need to make the +following changes. + + +#. Move the required layout files into app/views/elements +#. Rename the $content\_for\_layout variable to $message +#. Make sure you have ``echo $session->flash();`` in your layout + +``SessionComponent`` and ``SessionHelper`` are not automatically +loaded. +Both ``SessionComponent`` and ``SessionHelper`` are no longer +automatically included without you asking for them. SessionHelper +and SessionComponent now act like every other component and must be +declared like any other helper/component. You should update +``AppController::$components`` and ``AppController::$helpers`` to +include these classes to retain existing behavior:: + + var $components = array('Session', 'Auth', ...); + var $helpers = array('Session', 'Html', 'Form' ...); + +These change were done to make CakePHP more explicit and +declarative in what classes you the application developer want to +use. In the past there was no way to avoid loading the Session +classes without modifying core files. Which is something we want +you to be able to avoid. In addition Session classes were the only +magical component and helper. This change helps unify and normalize +behavior amongst all classes. + +Library Classes +~~~~~~~~~~~~~~~ + +**CakeSession** + + +- ``del`` is deprecated use ``delete`` + +**SessionComponent** + + +- ``SessionComponent::setFlash()`` now uses an *element* instead + of a *layout* as its second parameter. Be sure to move any flash + layouts from app/views/layouts to app/views/elements and change + instances of $content\_for\_layout to $message. + +**Folder** + + +- ``mkdir`` is deprecated use ``create`` +- ``mv`` is deprecated use ``move`` +- ``ls`` is deprecated use ``read`` +- ``cp`` is deprecated use ``copy`` +- ``rm`` is deprecated use ``delete`` + +**Set** + + +- ``isEqual`` is deprecated. Use == or ===. + +**String** + + +- ``getInstance`` is deprecated, call String methods statically. + +**Router** + +``Routing.admin`` is deprecated. It provided an inconsistent +behavior with other prefix style routes in that it was treated +differently. Instead you should use ``Routing.prefixes``. Prefix +routes in 1.3 do not require additional routes to be declared +manually. All prefix routes will be generated automatically. To +update simply change your core.php:: + + //from: + Configure::write('Routing.admin', 'admin'); + + //to: + Configure::write('Routing.prefixes', array('admin')); + +See the New features guide for more information on using prefix +routes. A small change has also been done to routing params. Routed +params should now only consist of alphanumeric chars, - and \_ or +``/[A-Z0-9-_+]+/``:: + + Router::connect('/:$%@#param/:action/*', array(...)); // BAD + Router::connect('/:can/:anybody/:see/:m-3/*', array(...)); //Acceptable + +For 1.3 the internals of the Router were heavily refactored to +increase performance and reduce code clutter. The side effect of +this is two seldom used features were removed, as they were +problematic and buggy even with the existing code base. First path +segments using full regular expressions was removed. You can no +longer create routes like:: + + Router::connect( + '/([0-9]+)-p-(.*)/', + array('controller' => 'products', 'action' => 'show') + ); + +These routes complicated route compilation and impossible to +reverse route. If you need routes like this, it is recommended that +you use route parameters with capture patterns. Next mid-route +greedy star support has been removed. It was previously possible to +use a greedy star in the middle of a route:: + + Router::connect( + '/pages/*/:event', + array('controller' => 'pages', 'action' => 'display'), + array('event' => '[a-z0-9_-]+') + ); + +This is no longer supported as mid-route greedy stars behaved +erratically, and complicated route compiling. Outside of these two +edge-case features and the above changes the router behaves exactly +as it did in 1.2 + +Also, people using the 'id' key in array-form URLs will notice that +Router::url() now treats this as a named parameter. If you +previously used this approach for passing the ID parameter to +actions, you will need to rewrite all your $html->link() and +$this->redirect() calls to reflect this change. + +:: + + // old format: + $url = array('controller' => 'posts', 'action' => 'view', 'id' => $id); + // use cases: + Router::url($url); + $html->link($url); + $this->redirect($url); + // 1.2 result: + /posts/view/123 + // 1.3 result: + /posts/view/id:123 + // correct format: + $url = array('controller' => 'posts', 'action' => 'view', $id); + +**Dispatcher** + +``Dispatcher`` is no longer capable of setting a controller's +layout/viewPath with request parameters. Control of these +properties should be handled by the Controller, not the Dispatcher. +This feature was also undocumented, and untested. + +**Debugger** + + +- ``Debugger::checkSessionKey()`` has been renamed to + ``Debugger::checkSecurityKeys()`` +- Calling ``Debugger::output("text")`` no longer works. Use + ``Debugger::output("txt")``. + +**Object** + + +- ``Object::$_log`` has been removed. ``CakeLog::write`` is now + called statically. See :doc:`/core-libraries/logging` + for more information on changes made to logging. + +**Sanitize** + + +- ``Sanitize::html()`` now actually always returns escaped + strings. In the past using the ``$remove`` parameter would skip + entity encoding, returning possibly dangerous content. +- ``Sanitize::clean()`` now has a ``remove_html`` option. This + will trigger the ``strip_tags`` feature of ``Sanitize::html()``, + and must be used in conjunction with the ``encode`` parameter. + +**Configure and App** + + +- Configure::listObjects() replaced by App::objects() +- Configure::corePaths() replaced by App::core() +- Configure::buildPaths() replaced by App::build() +- Configure no longer manages paths. +- Configure::write('modelPaths', array...) replaced by + App::build(array('models' => array...)) +- Configure::read('modelPaths') replaced by App::path('models') +- There is no longer a debug = 3. The controller dumps generated + by this setting often caused memory consumption issues making it an + impractical and unusable setting. The ``$cakeDebug`` variable has + also been removed from ``View::renderLayout`` You should remove + this variable reference to avoid errors. +- ``Configure::load()`` can now load configuration files from + plugins. Use ``Configure::load('plugin.file');`` to load + configuration files from plugins. Any configuration files in your + application that use ``.`` in the name should be updated to use + ``_`` + +**Cache** + +In addition to being able to load CacheEngines from app/libs or +plugins, Cache underwent some refactoring for CakePHP1.3. These +refactorings focused around reducing the number and frequency of +method calls. The end result was a significant performance +improvement with only a few minor API changes which are detailed +below. + +The changes in Cache removed the singletons used for each Engine +type, and instead an engine instance is made for each unique key +created with ``Cache::config()``. Since engines are not singletons +anymore, ``Cache::engine()`` was not needed and was removed. In +addition ``Cache::isInitialized()`` now checks cache +*configuration names*, not cache *engine names*. You can still use +``Cache::set()`` or ``Cache::engine()`` to modify cache +configurations. Also checkout the +:doc:`/appendices/new-features-in-cakephp-1-3` for +more information on the additional methods added to ``Cache``. + +It should be noted that using an app/libs or plugin cache engine +for the default cache config can cause performance issues as the +import that loads these classes will always be uncached. It is +recommended that you either use one of the core cache engines for +your ``default`` configuration, or manually include the cache +engine class before configuring it. Furthermore any non-core cache +engine configurations should be done in +``app/config/bootstrap.php`` for the same reasons detailed above. + +Model Databases and Datasources +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Model** + + +- ``Model::del()`` and ``Model::remove()`` have been removed in + favor of ``Model::delete()``, which is now the canonical delete + method. +- ``Model::findAll``, findCount, findNeighbours, removed. +- Dynamic calling of setTablePrefix() has been removed. + tableprefix should be with the ``$tablePrefix`` property, and any + other custom construction behavior should be done in an overridden + ``Model::__construct()``. +- ``DboSource::query()`` now throws warnings for un-handled model + methods, instead of trying to run them as queries. This means, + people starting transactions improperly via the + ``$this->Model->begin()`` syntax will need to update their code so + that it accesses the model's DataSource object directly. +- Missing validation methods will now trigger errors in + development mode. +- Missing behaviors will now trigger a cakeError. +- ``Model::find(first)`` will no longer use the id property for + default conditions if no conditions are supplied and id is not + empty. Instead no conditions will be used +- For Model::saveAll() the default value for option 'validate' is + now 'first' instead of true + +**Datasources** + + +- DataSource::exists() has been refactored to be more consistent + with non-database backed datasources. Previously, if you set + ``var $useTable = false; var $useDbConfig = 'custom';``, it was + impossible for ``Model::exists()`` to return anything but false. + This prevented custom datasources from using ``create()`` or + ``update()`` correctly without some ugly hacks. If you have custom + datasources that implement ``create()``, ``update()``, and + ``read()`` (since ``Model::exists()`` will make a call to + ``Model::find('count')``, which is passed to + ``DataSource::read()``), make sure to re-run your unit tests on + 1.3. + +**Databases** + +Most database configurations no longer support the 'connect' key +(which has been deprecated since pre-1.2). Instead, set +``'persistent' => true`` or false to determine whether or not a +persistent database connection should be used + +**SQL log dumping** + +A commonly asked question is how can one disable or remove the SQL +log dump at the bottom of the page?. In previous versions the HTML +SQL log generation was buried inside DboSource. For 1.3 there is a +new core element called ``sql_dump``. ``DboSource`` no longer +automatically outputs SQL logs. If you want to output SQL logs in +1.3, do the following: + +:: + + echo $this->element('sql_dump'); + +You can place this element anywhere in your layout or view. The +``sql_dump`` element will only generate output when +``Configure::read('debug')`` is equal to 2. You can of course +customize or override this element in your app by creating +``app/views/elements/sql_dump.ctp``. + +View and Helpers +~~~~~~~~~~~~~~~~ + +**View** + + +- ``View::renderElement`` removed. Use ``View::element()`` + instead. +- Automagic support for ``.thtml`` view file extension has been + removed either declare ``$this->ext = 'thtml';`` in your + controllers, or rename your views to use ``.ctp`` +- ``View::set('title', $var)`` no longer sets + ``$title_for_layout`` when rendering the layout. + ``$title_for_layout`` is still populated by default. But if you + want to customize it, use ``$this->set('title_for_layout', $var)``. +- ``View::$pageTitle`` has been removed. Use + ``$this->set('title_for_layout', $var);`` instead. +- The ``$cakeDebug`` layout variable associated with debug = 3 has + been removed. Remove it from your layouts as it will cause errors. + Also see the notes related to SQL log dumping and Configure for + more information. + +All core helpers no longer use ``Helper::output()``. The method was +inconsistently used and caused output issues with many of +FormHelper's methods. If you previously overrode +``AppHelper::output()`` to force helpers to auto-echo you will need +to update your view files to manually echo helper output. + +**TextHelper** + + +- ``TextHelper::trim()`` is deprecated, used ``truncate()`` + instead. +- ``TextHelper::highlight()`` no longer has: +- an ``$highlighter`` parameter. Use ``$options['format']`` + instead. +- an ``$considerHtml``parameter. Use ``$options['html']`` instead. +- ``TextHelper::truncate()`` no longer has: +- an ``$ending`` parameter. Use ``$options['ending']`` instead. +- an ``$exact`` parameter. Use ``$options['exact']`` instead. +- an ``$considerHtml``parameter. Use ``$options['html']`` + instead. + +**PaginatorHelper** + +PaginatorHelper has had a number of enhancements applied to make +styling easier. +``prev()``, ``next()``, ``first()`` and ``last()`` + +The disabled state of these methods now defaults to ```` tags +instead of ``
`` tags. + +passedArgs are now auto merged with URL options in paginator. + +``sort()``, ``prev()``, ``next()`` now add additional class names +to the generated html. ``prev()`` adds a class of prev. ``next()`` +adds a class of next. ``sort()`` will add the direction currently +being sorted, either asc or desc. + +**FormHelper** + + +- ``FormHelper::dateTime()`` no longer has a ``$showEmpty`` + parameter. Use ``$attributes['empty']`` instead. +- ``FormHelper::year()`` no longer has a ``$showEmpty`` parameter. + Use ``$attributes['empty']`` instead. +- ``FormHelper::month()`` no longer has a ``$showEmpty`` + parameter. Use ``$attributes['empty']`` instead. +- ``FormHelper::day()`` no longer has a ``$showEmpty`` parameter. + Use ``$attributes['empty']`` instead. +- ``FormHelper::minute()`` no longer has a ``$showEmpty`` + parameter. Use ``$attributes['empty']`` instead. +- ``FormHelper::meridian()`` no longer has a ``$showEmpty`` + parameter. Use ``$attributes['empty']`` instead. +- ``FormHelper::select()`` no longer has a ``$showEmpty`` + parameter. Use ``$attributes['empty']`` instead. +- Default URLs generated by form helper no longer contain 'id' + parameter. This makes default URLs more consistent with documented + userland routes. Also enables reverse routing to work in a more + intuitive fashion with default FormHelper URLs. +- ``FormHelper::submit()`` Can now create other types of inputs + other than type=submit. Use the type option to control the type of + input generated. +- ``FormHelper::button()`` Now creates `` + + + + + + The ``button`` input type supports the ``escape`` option, which accepts a + bool and determines whether to HTML entity encode the $title of the button. + Defaults to false:: + + echo $this->Form->button('Submit Form', array( + 'type' => 'submit', + 'escape' => true + )); + +.. php:method:: postButton(string $title, mixed $url, array $options = array ()) + + Create a ``