Migrating to Version 2.1

There are new features and some incompatibilities that should be considered, and code should be tested before switching to new Nette Framework version.

New Features

Application & Presenter

  • Presenter: new method sendJson()
  • PresenterFactory: configurable mapping Presenter name → Class name
  • Route: new pseudo-variables %basePath%, %tld% and %domain%

Caching

  • added SQLite storage (Nette/Caching/Storages/SQLiteStorage)

Database (NDB)

  • complete refactoring, a ton of bug fixes
  • Connection:
    • lazy connection
    • all queries are logged (error queries, transactions, …)
    • added onConnect event
    • DSN in connection panel
  • much better (dibi-like) SQL preprocessor
  • Selection, ActiveRow: insert() & update() methods return row instances with refetched data
  • Selection: added placeholder support select(), group(), having(), order() methods
  • SqlLiteral: added placeholder support
  • Selection:
    • added: WHERE conditions consider NOT for IN operator
    • insert() method returns IRow
  • drivers:
    • new driver for Sqlsrv
    • Sqlite supports multi-inserts
    • fixes for PostgreSQL

Debugger

  • Dumper: colored and clickable dumps in HTML or terminal
  • Debugger: full stack trace on fatal errors (requires Xdebug)
  • Debugger: method barDump() accepts options
  • BlueScreen: new property $collapsePaths which allows you to configure which paths are collapses in stack trace
  • Bar: you can see bar after redirect
  • Bar: new method getPanel()
  • Dumper: possibility to include JS & CSS separately

Dependency Injection (DI)

  • annotation @inject
  • auto-generated factories and accessors via interface
  • adding compiler extensions via config file
  • auto-detection of sections in config file
  • configurable presenters via config file
  • Container: new methods findByType() and callInjects()

Forms

  • new macro n:name for <form> <input> <select> <textarea>
  • partially rendered radiolists using {input name:$key} and {label name:$key}
  • setOmitted: excludes value from $form->getValues() result
  • removed dependency on Environment
  • improved toggles
  • improved netteForms.js
  • validation scopes
  • data-nette-rules attribute is JSON
  • getOwnErrors() returns only errors attached to form
  • Radiolist::getLabel(…, $key) returns label for single item

HTTP

  • added new SessionPanel
  • Helpers: new method ipMatch()
  • RequestFactory: new method setProxy()
  • Url: new methods getQueryParameter() and setQueryParameter()

Latte

  • new modifier |noescape which is preferred over exclamation mark
  • new macro n:ifcontent
  • {include block} can be written without hash
  • template allows helpers overriding
  • native support for empty macros {macro /}
  • a lot of small improvements
  • PhpWriter supports indexed arguments like %1.raw

Utils

  • Arrays: new method isList()
  • Arrays: method flatten() supports key preserving
  • Strings: new methods findPrefix() and normalizeNewLines()
  • Json: supports pretty output
  • Neon: is superset of JSON
  • Validators: new method isType()
  • new utility class FileSystem
  • new utility class Callback

Mailing

  • SmtpMailer: persistent connection
  • SmtpMailer: some methods protected and can be overloaded

Others

  • ObjectMixin: new methods getMagicMethods, getExtensionMethod, setExtensionMethod and checkType
  • ObjectMixin: magic methods setProperty(), getProperty(), isProperty() and addProperty() by @method
  • both RobotLoader and NetteLoader can be registered before existing autoloaders instead of after
  • SafeStream: supports ftruncate (requires PHP 5.4+)

Backward Incompatible Changes

Database (NDB)

  • Nette\Database\Connection is not a descendant of PDO
  • rename methods exec()query(), fetchColumn()fetchField() and lastInsertId() → getInsertId()
  • Nette\Database\Statement rename to Nette\Database\ResultSet, which is not a descendant of PDOStatement
  • rename methods rowCount()getRowCount() and columnCount() → getColumnCount()
  • MySQL: removed timezone setting. Use onConnect[] event instead. (commit)

Are you using Nette Database Table (NDBT), a great part of the NDB to which is accessed via $database->table(...)?

  • method table() was moved from Connection to new class Nette\Database\Context. It contains all of the important methods for working with databases, so feel free to change the Connection for Context and you're done.
  • properties of ActiveRow are now read-only, for updating use $row->update(['field' => 'value']). The old behavior had so many difficulties, sorry.
  • backjoin syntax was changed from book_tag:tag.name to :book_tag.tag.name (see semicolons)
  • instead of second argument $having in method group() use method having()
  • Selection: removed support for INNER join in where statement (commit)

Dependency Injection (DI)

  • class Nette\Config\ConfiguratorNette\Configurator
  • definitions of factories and services in configuration file were merged into a single services section. Append key autowired: false to the factories when moving them to services section.
  • introduced “bullet” syntax for anonymous services:
services:
	Namespace\Class: self  # old way

	- Namespace\Class  # new way

Working directly with the DI container is usually not a good idea, but if you do so:

  • factory method call as $container->createService('name') instead of $container->createName()
  • all default factories are deprecated: createLatte(), createCache(), createMail()createBasicForm()
  • access to services via $container->getService() or getByType() instead of $container->serviceName
  • Container: removed property $classes, removed parameter $meta in method addService()
  • ServiceDefinition: removed property $internal and method setInternal()
  • ContainerBuilder: method generateClass() is deprecated, use generateClasses()[0] instead
  • ContainerBuilder operates on expanded parameters, removed Helpers: escape()
  • Configurator: deprecated parameter productionMode, use debugMode instead
  • Configurator: methods setProductionMode, isProductionMode and detectProductionMode are deprecated, use *Debug* variants instead
  • Container: removed deprecated property $params, use $parameters instead

If you write your own extensions, you should know that these namespaces was renamed: Nette\ConfigNette\DI and Nette\Utils\PhpGeneratorNette\PhpGenerator.

Compared to the dev-version the annotation @inject a methods inject() are processed automatically only for presenters. They can be enabled using key inject: true in the definition.

If you are using old Environment, it will require to set constant TEMP_DIR.

Application & Presenter

  • Presenter doesn't accept array in persistent parameters anymore. If you really do want to use arrays, assign empty array as default value.
  • deprecated all of the following methods: getService() (use getContext()->getService()), getHttpContext() and getApplication()
  • magical getParameter(null)getParameters()
  • you can use redrawControl() instead of invalidateControl()
  • Application: methods storeRequest() and restoreRequest() are deprecated, call them on UI\Presenter instead
  • Application\Routers\Route: foo-parameters are not optional when pattern is missing

Latte

  • default mode is HTML (instead of XHTML); if you need to use XHTML, please see configuration
  • automatic quoting of attributes in <a title={$title}>; this should not cause any trouble, but it's better to mention it just in case
  • renamed n:input to n:name; it can be used on tags other than <input>, like label, select, form and textarea
  • deprecated {attr} (replaced by n:attr) and {assign} → {var}
  • it's now best practice to use {$var|noescape} instead of old “exclamation mark” notation {!$var}, it's more clearer
  • shorter macro for blocks {#block} (present in development version) was not included in version 2.1 due to comprehension reasons
  • native support for empty macros, use for example {label foo /} instead of {label foo}

Latte contains a new feature which automatically checks if variable $url in <a href={$url}> contains malicious code (like javascript:siteHack()). It only allows http, https, ftp, mailto protocols and relative paths. It also checks in attributes src, action, formaction and <object data=...>. Should you need to print URL without checking, use |nosafeurl modifier.

There also was a small change with manual rendering of checkboxes, which is described later in the article.

Forms

Checkboxes and RadioLists are now rendered in more practical way (<label><input>...</label> instead of <label>...</label><input>). Therefore, Checkbox's method getLabel() or {label} return nothing and getControl() or {input} return HTML in the new form. Should you need previous behavior, you can achieve it by so-called partial rendering by adding colon ({label elementName:} and {input elementName:}). Easy.

Macro {control form} always prints error messages next to controls; only unassigned errors are shown in the beginning of the form. It is recommended to do it like this when rendering form manually, as can be seen in the example.

  • setValue() checks value and throws exception if something is wrong (instead of ignoring any errors)
  • validation rules Form::INTEGER, NUMERIC and FLOAT cast the value to integer or float
  • TextArea: removed default values of attributes cols and rows (they were included only because HTML4 required them)
  • controls marked setDisabled() are not present in $form->getValues() (they are not sent by the browser)
  • deprecated SelectBox::setPrompt(true); use string instead of true
  • renamed MultiSelectBox::getSelectedItem()getSelectedItems()
  • HTML attributes as data-nette-rules contains JSON, don't forget to update netteForms.js to latest version
  • Form: removed deprecated event $onInvalidSubmit, use $onError instead
  • RadioList: calling getValue(true) is deprecated, use getRawValue() instead

Debugger

  • Nette\Diagnostics\Debugger::$blueScreenDebugger::getBlueScreen()
  • and similarly $bargetBar(), $loggergetLogger() a $fireLogger → getFireLogger()
  • deprecated Nette\Diagnostics\Debugger::tryError(), catchError() and also toStringException(), use standard trigger_error() instead
  • deprecated internal Nette\Diagnostics\Helpers::clickableDump() and htmlDump(), which were replaced by Dumper

Mail

  • Deprecated method Nette\Mail\Message::send(), use mailer
  • Mail\Message: methods setHtmlBody() and setBody() render template immediately
  • MimePart: removed method generateMessage(), use getEncodedMessage() instead

Miscellaneous

  • Nette Framework dropped support for PHP 5.2; to ease migration to namespaces, migration-53.php utility is available
  • minimized version is generated in PHAR format, therefore there's nette.phar instead of nette.min.php in the distribution. Usage is the same.
  • Nette\Utils\Finder::find($mask) filters both directories and files by mask
  • Nette\Security\User accepts authenticator in constructor, beware of circular dependencies
  • loader doesn't set iconv_set_encoding() and mb_internal_encoding() anymore
  • deprecated constants NETTE, NETTE_DIR and NETTE_VERSION_ID
  • deprecated class Nette\Loaders\AutoLoader
  • deprecated variable Nette\Framework::$iAmUsingBadHost
  • we recommend you to stop using callback() and class Nette\Callback, because global functions can cause troubles
  • renamed namespace Nette\Utils\PhpGeneratorNette\PhpGenerator
  • Nette shows warning „Possible problem: you are sending a cookie while already having some data in output buffer,“ if you are trying to send HTTP headers or cookies and previous output was sent to buffer. The error is shown because buffer may overflow.
  • InstanceFilter: removed entirely
  • RecursiveFilter: removed method accept() and parameter $childrenCallback in constructor
  • RequestFactory: removed method setEncoding(), only UTF-8 and binary (via setBinary()) is now supported
  • ObjectMixin: removed method callProperty()
  • ObjectMixin: removes support for non-registered extension methods (*_prototype_* functions)