Smooth Upgrade to Nette 3.1 in Diffs

Nette 3.1 was released almost a month ago. Packages using it had enough time to give support to small BC breaks and now it's ready to run on your project. Let's look at what has changed and how to upgrade today.

Contributed by
lulco in #5195

If you're not on Nette 3.1, hurry up. Why? There is a security issue in 3.0.x version:


But that's not the only reason to upgrade. Nette is rising to more active half of PHP frameworks and is right behind Laravel. Give Nette core developers your appreciation by upgrading to the new version as soon as possible.


What has Changed in Nette 3.1?

1. Minimal PHP Version Bumped to PHP 7.2

 {
     "require": {
-        "php": "^7.1"
+        "php": "^7.2"
     }
 }


2. All Interfaces lost their I Prefix

This is the most significant change of Nette 3.1. Removing visual clues makes it harder to separate classes from interfaces, and it affects over 30 class names:

-use Nette\Application\UI\ITemplate;
+use Nette\Application\UI\Template;

-final class SomeTemplate implements ITemplate
+final class SomeTemplate implements Template
 {
    // ...
 }
 foreach ($rows as $row) {
-    /** @var \Nette\Database\IRow $row */
+    /** @var \Nette\Database\Row $row */
     $row->...()
 }
-use Nette\Localization\ITranslator;
+use Nette\Localization\Translator;


Watch Out For Name Conflicts

This will create a naming conflict with already existing class short names, so be careful about "found & replace" upgrades:

-use Nette\Forms\IControl;
+use Nette\Forms\Control;
 use Nette\Applicatdion\UI\Control;
-use Nette\Application\UI\ITemplate;
+use Nette\Application\UI\Template;
 use Nette\Bridges\ApplicationLatte\Template;


Don't forget about configs:

 services:
     nette.mailer:
-        class: Nette\Mail\IMailer
+        class: Nette\Mail\Mailer


3. From Magical RouteList to addRoute() Method

 $routeList = new RouteList();
-$routeList[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
+$routeList->addRoute('<presenter>/<action>[/<id>]', 'Homepage:default');

 return $routeList;


4. Form addImage() to addImageButton()

 $form = new Form;
-$input = $form->addImage('image');
+$input = $form->addImageButton('image');


5. New addStaticParameters() Method

Now its more clear what is a static parameter and what dynamic one:

 // bootstrap.php
 $configurator = new Nette\Configurator();

-$configurator->addParameters([
+$configurator->addStaticParameters([
    // ...
]);

 $configurator->addDynamicParameters([
     // ...
 ]);


6. Renamed DefaultTemplate class

The interface rename sometimes took already existing class names. That's why some classes had to be renamed too:

-use Nette\Bridges\ApplicationLatte\Template;
+use Nette\Bridges\ApplicationLatte\DefaultTemplate;


7. New Param in sendTemplate() Method

 use Nette\Application\UI\Template;

 final class SomePresenter extends Presenter
 {
-    public function sendTemplate(): void
+    public function sendTemplate(?Template $template = null): void
     {
         // ...
     }
 }


8. Cache save() with Callable is Deprecated

After this change you have to resolve data first, then pass it to cache save() method:

-$result = $this->cache->save($key, function () {
-    return $this->getSomeHeavyResult();
-});
+$result = $this->getSomeHeavyResult();
+$this->cache->save($key, $result);


 session:
     autoStart: false
-    cookieSamesite: Lax
 $this->response->setCookie(
     $key,
     $data,
     $expire,
     null,
     null,
     $this->request->isSecured(),
-    true,
-    'Lax',
);


You can read more detailed post about changes on the Czech forum.


2 Steps to Make your Project Nette 3.1

Eager to try it on your project? This time try it without any composer.json modification - Rector will handle it too.

  1. Add NETTE_31 set your rector.php
use Rector\Nette\Set\NetteSetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->import(NetteSetList::NETTE_31);
 };
  1. Run Rector:
vendor/bin/rector process

That's it!


Have we missed something? Create an issue so we can complete the set for other developers.


Happy coding!