Saturday, April 19, 2014

Making the switch from Yii 1.1 to Yii 2.0 - Part 2: Getting Started

Probably my biggest hurdle in getting started with Yii 2.0 (aside from getting my hosting company to upgrade my server from PHP5.2 to 5.4) has been understanding the changes to the application structure and the vast difference between the basic application and the advanced application. Since my personal site runs on a subdomain, this greatly complicated the issue for me. I needed something more than the basic application, but the advanced application was way too much overkill. I finally went with the advanced application, but now that I understand how the composer works to distribute the skeleton files, I'm looking forward to creating something that's between the two.

There is way too much to cover in a single blog, so this is just a look at the basic structure and front end changes that you need to know to get up and running in 2.0.

If you're past all of this and looking to dive into the nitty-gritty detail changes, I suggest you read the official documentation on upgrading.


To begin, lets look at the high level structure in Yii 1.1.*:

index.php
index-test.php
assets/
css/
images/
themes/
protected/
  commands/
  components/
  config/
  controllers/
  data/
  extensions/ 
  messages/
  models/
  runtime/
  tests/
  views/
framework/  <-- may be located elsewhere outside the web root

With Yii 2.0 the top level structure changes. The basic application is the most similar to the 1.1 version, but the entirety of the protected folder has been moved up several levels out of the web root (it's actually easier to understand with the advanced application, since it collapses everything).

Basic Yii 2.0 Application Structure (Installation Instructions)

assets/   // This is *NOT* the web accessible assets folder
commands/
config/
controllers/
mail/
models/
runtime/
tests/
vendor/
  yiisoft/  <-- This is the equivalent of the "framework" folder
  ezyang
  twbs
  ... <-- Composer installed dependencies (extensions)
views/
web/       <-- The web root for your application
  index.php
  index-test.php
  assets/  <-- THIS is your published assets folder for the web
  css/

If you're on a shared hosting account, you can now have your moment of panic that your launch file is not at the top level -- but don't worry, you can set up .htaccess rules to handle that, or you can change up your application structure to suit. The important thing is to keep that vendor directory where it is and ensure that everything points to it properly (i.e., update vendor include paths in the various files if you move them around). You'll also need to set up .htaccess deny from all rules for anything that you cannot move outside the web root.

Advanced Yii 2.0 Application Structure (Installion Instructions)

backend/  <-- Site 1
  config/
  controllers/
  models/
  runtime/
  tests/
  views/
  web/       <-- The web root for your backend application
    index.php
    index-test.php
    assets/ 
    css/
common/
  config/
  mail/
  models/
  tests/
console/
environments/ 
frontend/
  config/
  controllers/
  models/
  runtime/
  tests/
  views/
  web/       <-- The web root for your frontend application
    index.php
    index-test.php
    assets/  
    css/
vendor/
  yiisoft/

Skipping over the details for using the advanced app for now (like the fantastic init script for toggling between production and development, and the ability to share common configuration options between applications), you'll notice that this structure contains two web applications ("frontend" and "backend") and a console application ("console") within it. These applications share common files and all pull from the shared vendor folder for the framework.

Note that the commands folder is now under console, rather than listed with either of the specialized web applications.

There are a lot of nice features in the advanced application, but that's a whole other blog. ;)

If you're like me, and run a few subdomains off a single yii installation, the advanced application is going to be the way to go, even if it contains a lot of functionality you'll never use. (Side note: This is why I want to create my own mid-level application configuration -- the *one* page in the new documentation that still says TBD -- oh I lost sleep over that one, but I think I've got it figured out now -- again, a topic for another blog...)

The top front-end changes you need to know to get a basic page converted

Ah, CHtml how you've grown. The CHtml class is now Html. Many of the old methods still work, but one of the most commonly used ones ("link") has been changed.

Old New
CHtml::link()
Html::a()
$this->widget('zii.widgets.CMenu', [
  'items'=>[
    [
      'label'=>'Home',
      'url'=>['site/index']
    ],
    [
      'label'=>'Home',
      'url'=>['site/index']
    ]
  ]
]);
echo Nav::widget(
  'items'=>[
    [
      'label'=>'Home',
      'url'=>['site/index']
    ],
    [
      'label'=>'Home',
      'url'=>['site/index']
    ]
  ]
);
CHtml::img(
  '/path/to/file',
  'alt-text', 
  ['class'=>'img-responsive']
);
Html::img(
  '/path/to/img',
  [
    'alt'=>'alt-text',
    'class'=>'img-responsive'
  ]
)
$this->breadcrumbs = [
  'Label'=>['site/labelAction'],
  'Current Page Title',
];
$this->params['breadcrumbs'] =[
  [
    'label'=>'Label',
    'url'=>['site/labelAction']
  ],
  'Current Page Title'
]; 

CActiveForm -- Just consider this a heads up. The form syntax is too altered to cover at a high level here, but I highly recommend the Class Reference for that one.