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í potomkemPDO- přejmenujte metody
exec()→query(),fetchColumn()→fetchField()alastInsertId()→getInsertId() Nette\Database\Statementje nyníNette\Database\ResultSeta též už není potomkemPDOStatement- 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)