Přechod na verzi 2.1
Nová verze přináší nové vlastnosti a některé nekompatibility, které je třeba projít a kód otestovat před nasazením nové verze.
Nové vlastnosti
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 $collapsePathswhich 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()andcallInjects()
- bullet syntax for anonymous services
Forms
- setOmitted: excludes value from $form->getValues() result
- implemented full validation scopes
- data-nette-rules attribute is JSON
- Form::getOwnErrors() returns only errors attached to form
- Radiolist::getLabel(…, $key) returns label for single item
- added ChoiceControl, MultiChoiceControl and CheckboxList
- SelectBox and CheckboxList: allowes to disable single items
- UploadControl allowes multiple files upload
- validators Form::INTEGER,NUMERICandFLOATconverts values to integer or float
- validator Form::URLprependshttp://to value
- Form::getHttpData($htmlName)returns data for single field
- supports Twitter Bootstrap 2 & 3 (see examples)
- removed dependency on Environment
- improved toggles
- improved netteForms.js
Latte
- supports <tag attr=$val>without quotes
- new macro n:namefor<form> <input> <select> <textarea>
- partially rendered radiolists using {input name:$key}and{label name:$key}
- new modifier |safeurlwhich allowes only http(s), ftp and mailto protocols
- safeurl is automatically used for href,src,actionandformactionattributes (can be bypassed by|nosafeurlmodifier)
- new modifier |noescapewhich is preferred over exclamation mark
- {foreach ...|nointerator}bypasses creating variable- $iterator
- 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
Http
- added new SessionPanel
- Helpers: new method ipMatch()
- RequestFactory: new method setProxy()
- Url: new methods getQueryParameter()andsetQueryParameter()
Utils
- Arrays: new method isList()
- Arrays: method flatten()supports key preserving
- Strings: new methods findPrefix()andnormalizeNewLines()
- 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
- minified version is PHAR file
- ObjectMixin: new methods getMagicMethods,getExtensionMethod,setExtensionMethodandcheckType
- ObjectMixin: magic methods setProperty(), getProperty(), isProperty() and addProperty() by @method
- both RobotLoaderandNetteLoadercan be registered before existing autoloaders instead of after
- SafeStream: supports ftruncate(requires PHP 5.4+)
Nekompatibility
Database (NDB)
- Nette\Database\Connectionjiž není potomkem- PDO
- přejmenujte metody exec()→query(),fetchColumn()→fetchField()alastInsertId()→getInsertId()
- Nette\Database\Statementje nyní- Nette\Database\ResultSeta též už není potomkem- PDOStatement
- přejmenujte metody rowCount()→getRowCount()acolumnCount()→getColumnCount()
- MySQL: removed timezone setting. Use onConnect[] event instead. (commit)
Používáte Nette Database Table (NDBT), tedy skvělou část NDB, ke které se přistupuje přes
$database->table(...)?
- metoda table()byl přesunuta zConnectiondo nové třídyNette\Database\Context. Ta obsahuje všechny důležité metody pro práci s databází, takže klidně změňteConnectionzaContexta máte hotovo.
- proměnné řádku ActiveRowjsou nyní read-only, pro změnu slouží metoda$row->update(['field' => 'value']). Věřte, že dřívější chování mělo tolik úskalí, že jiná cesta nebyla.
- změnila se tzv. backjoin syntaxe z book_tag:tag.namena:book_tag.tag.name(dvojtečka na začátku)
- místo druhého parametru $havingv metoděgroup()použijte metoduhaving()
- Selection: removed support for INNER join in where statement (commit)
(Pokud jste používali SelectionFactory v dev-verzi, změňte ji také na Context.)
Dependency Injection (DI)
- třída Nette\Config\Configurator→Nette\Configurator
- v konfiguračním souboru se sloučily definice factoriesaservicesdo společnéhoservices. Jen těm, co byly původně factories, přidejte klíčautowired: false.
- a zavedl se „odrážkový“ zápis anonymních služeb:
services:
	Jmeno\Tridy: self  # dříve, ukázalo se jako matoucí
	- Jmeno\Tridy  # nyní
Pracovat přímo s DI kontejnerem není obvykle dobrý nápad, ale pokud už tak činíte:
- tovární metody volejte jako $container->createService('nazevsluzby')namísto$container->createNazevSluzby()
- zavrženy jsou všechny výchozí továrny jako createLatte(),createCache(),createMail()acreateBasicForm()
- a ke službám přistupujte raději přes $container->getService()čigetByType()namísto$container->nazevSluzby
- Container: removed property $classes, removed parameter$metain methodaddService()
- ServiceDefinition: removed property $internaland methodsetInternal()
- ContainerBuilder: method generateClass()is deprecated, usegenerateClasses()[0]instead
- ContainerBuilder operates on expanded parameters, removed Helpers: escape()
- Configurator: deprecated parameter productionMode, usedebugModeinstead
- Configurator: methods setProductionMode,isProductionModeanddetectProductionModeare deprecated, use*Debug*variants instead
- Container: removed deprecated property $params, use$parametersinstead
Pokud píšete vlastní rozšíření, vězte, že došlo k přejmenování jmenných prostorů Nette\Config →
Nette\DI a Nette\Utils\PhpGenerator → Nette\PhpGenerator.
Oproti dev-verzi jsou anotace @inject a metody inject() automaticky zpracovány jen na presenterech.
Na jiných službách je zapnete uvedením klíče inject: true v definici.
Používáte-li ještě stařičký Environment, bude po vás vyžadovat nastavenou konstantu
TEMP_DIR, kvůli výkonu.
Application & Presenter
- Presenter nyní zabraňuje, aby vám někdo podstrčil do persistentního parametru pole. Pokud ale pole chcete, uveďte ho jako výchozí hodnotu,
- zavržené jsou metody getService()(použijtegetContext()->getService()), dálegetHttpContext()agetApplication()
- magické getParameter(null)→getParameters()
- místo divného invalidateControl()lze používatredrawControl()
- Application: methods storeRequest()andrestoreRequest()are deprecated, call them onUI\Presenterinstead
- Application\Routers\Route: foo-parameters are not optional when pattern is missing
Latte
- výchozím režimem je HTML (namísto XHTML), což lze přepnout v konfiguraci
- automaticky ouvozovkuje atributy v
	<a title={$title}>, což by nemělo způsobit žádnou komplikaci, ale raději to zmiňuji
- atribut n:inputse mění nan:name, aby šel použít nejen na<input>, ale i label, select, form a textarea
- zavržená jsou makra {attr}(nahrazujen:attr) a{assign}→{var}
- doporučujeme místo vykřičníkového zápisu {!$var}přejít na{$var|noescape}, je to zřejmější
- pokud jste v dev-verzi používali zkrácený zápis bloků {#block}, tak do 2.1 se nedostal, nebyl srozumitelný
- native support for empty macros, use for example {label foo /}instead of{label foo}
V Latte je novinka, která v <a href={$url}> automaticky kontroluje, zda proměnná $url
neobsahuje něco jako javascript:hackniWeb(). Povolené jsou pouze protokoly http, https, ftp, mailto a pochopitelně
relativní cesty a kontroluje i atributy src, action, formaction a také <object data=...>. Pokud někde
potřebujete vypsat URL bez kontroly, použijte modifikátor |nosafeurl.
A nakonec: drobná změna souvisí s ručním vykreslování checkboxů, ale o tom níže.
Formuláře
Checkboxy a RadioListy se nyní vykreslují v praktičtějším tvaru <label><input>...</label>
namísto <label>...</label><input>. Jako důsledek u Checkbox metoda getLabel() či
{label} nevrací nic a getControl() či {input} HTML v onom novém tvaru. Pokud ale
potřebujete staré chování, přepněte se do tzv. partial renderingu přidáním dvojtečky: {label nazevprvku:} a
{input nazevprvku:}. Easy.
Makro {control form} nyní vždy vypisuje chybové zprávy u jednotlivých prvků a nad formulářem jsou jen ty
nepřiřazené. Doporučujeme to tak dělat i při manuálním vykreslování, třeba
takto.
- setValue()u prvků kontroluje hodnotu a v případě chyby vyhodí výjimku namísto dřívějšího mlčení
- validační pravidla jako Form::INTEGER,NUMERICaFLOATpřevádí hodnotu na integer resp. float
- TextArea: zrušeny výchozí hodnoty atributů colsarows(existovaly jen proto, že to HTML4 vyžadovalo)
- prvky označené setDisabled()se neobjeví ve$form->getValues()(prohlížeč je totiž vůbec neposílá)
- zavrženo SelectBox::setPrompt(true), místo true použijte řetězec
- přejmenováno MultiSelectBox::getSelectedItem()→getSelectedItems()
- v HTML atributech data-nette-rulesse používá JSON, takže nezapomeňte nasadit aktuálnínetteForms.js
- Form: removed deprecated event $onInvalidSubmit, use$onErrorinstead
- RadioList: calling getValue(true)is deprecated, usegetRawValue()instead
Debugger
- Nette\Diagnostics\Debugger::$blueScreen→- Debugger::getBlueScreen()
- a adekvátně $bar→getBar(),$logger→getLogger()a$fireLogger→getFireLogger()
- zavrženo Nette\Diagnostics\Debugger::tryError(),catchError()a takétoStringException(), místo kterého použijte obyčejnýtrigger_error()
- zavrženy interní Nette\Diagnostics\Helpers::clickableDump()ahtmlDump(), které nahrazuje nová třídaDumper
- Zavržená metoda Nette\Mail\Message::send(), použijte mailer
- Mail\Message: methods setHtmlBody()andsetBody()render template immediately
- MimePart: removed method generateMessage(), usegetEncodedMessage()instead
ostatní
- Nette Framework opouští PHP 5.2, s přechodem na jmenné prostory vám pomůže
	nástroj migration-53.php
- minimalizovaná verze se nyní generuje ve formátu PHAR, takže
	v distribuci místo nette.min.phpnajdete soubornette.phar, se kterým se však pracuje úplně stejně
- Nette\Utils\Finder::find($mask)filtruje podle masky nejen soubory, ale i adresáře
- do Nette\Security\Userse v konstruktoru předává autentikátor, pozor na kruhové závislosti
- v loaderu se už nenastavuje iconv_set_encoding()amb_internal_encoding()
- zavrženy konstanty NETTE, NETTE_DIR a NETTE_VERSION_ID
- a třída Nette\Loaders\AutoLoader
- a proměnná Nette\Framework::$iAmUsingBadHost
- doporučujeme přestat používat callback()a tříduNette\Callback, neboť globální funkce mohou způsobit komplikace
- přejmenoval se jmenný prostor Nette\Utils\PhpGenerator→Nette\PhpGenerator
- Nette varuje hláškou „Possible problem: you are sending a cookie while already having some data in output buffer,“ pokud se snažíte odeslat HTTP hlavičku nebo cookie a byl již odeslán nějaký výstup – byť do bufferu. Buffer totiž může přetéct a proto to varování.
- InstanceFilter: removed entirely
- ResursiveFilter: removed method accept()and parameter$childrenCallbackin constructor
- RequestFactory: removed method setEncoding(), only UTF-8 and binary (viasetBinary()) is now supported
- ObjectMixin: removed method callProperty()
- ObjectMixin: removes support for non-registered extension methods (*_prototype_*functions)