Difference between #144 and #168 of
Yii v2 snippet guide

Changes

Title unchanged

Yii v2 snippet guide

Category unchanged

Tutorials

Yii version unchanged

2.0

Tags unchanged

tutorial,beginner,yii2

Content changed

[...]
```
variables:
HOST: "ftp url"
USERNAME: "user"
PASSWORD: "password"
TARGETFOLDER: "relative path if needed, or just ./" deploy: script: - apt-get update -qq && apt-get install -y -qq lftp - lftp -c "set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST; mirror -Rnev ./ $TARGETFOLDER --ignore-time --parallel=10 --exclude-glob .git* --exclude .git/ --exclude vendor --exclude web/assets --exclude web/index.php --exclude web/index-test.php"
only:
- master
[...]
- exclude vendor = huge folder with 3rd party SW which is not in GIT
- exclude web/assets = also some cache
- exclude web/index.php = in GIT is your devel index wit
nh DEBUG mode enabled. You dont wanna have this file in productive environment
- exclude web/index-test.php = tests are only on your computer and in GIT
[...]
**How to redirect web to subfolder /web**
---
... to be added on Friday ...
 
 
**Auto redirection from login to desired URL **
 
---
 
... to be added on Friday ...
 
 
**What to change when exporting to the Internet**
 
---
 
- Delete file web/index-test.php
 
- In file web/index.php comment you 2 first lines containing YII_DEBUG + YII_ENV
 
- Delete the text from view site/login which says "You may login with admin/admin or demo/demo."
 
 
**Saving contact inqueries into DB**
 
---
 
```sql
 
DROP TABLE IF EXISTS `contact` ;
 
 
CREATE TABLE IF NOT EXISTS `contact` (
 
  `id` INT NOT NULL AUTO_INCREMENT,
 
  `name` VARCHAR(45) NOT NULL,
 
  `email` VARCHAR(45) NOT NULL,
 
  `subject` VARCHAR(100) NOT NULL,
 
  `body` TEXT NOT NULL,
 
  PRIMARY KEY (`id`))
 
ENGINE = InnoDB;
 
```
 
 
- Create the DB table
 
- Generate Model + CRUD using GII
 
- In Site controller replace ContactForm with Contact (in section "use" and in actionContact) and in the action change the IF condition:
 
```php
 
use app\models\Contact;
 
// ... 
 
public function actionContact() {
 
    $model = new Contact();
 
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
 
    // ...
 
```
 
- Open the new contact model and add one attribute and 2 rules:
 
 
```php
 
public $verifyCode;
 
// ...
 
  ['verifyCode', 'captcha'],
 
  ['email', 'email'],
 
 
// and translation for Captcha
 
'verifyCode' => Yii::t('app', 'Verification'),
 
```
 
 
- You can also delete one paragraph from view/site/contact
 
```php
 
<p>
 
Note that if you turn on the Yii debugger ...
 
```
 
 
Then some security - filtering users in the new ContactController:
 
 
```php
 
public function beforeAction($action) {
 
 
  if (!parent::beforeAction($action)) {
 
    return false;
 
  }
 
 
  $guestAllowedActions = [];
 
 
  if (Yii::$app->user->isGuest) {
 
    if (!in_array($action->actionMethod, $guestAllowedActions)) {
 
      return $this->redirect(['site/index']);
 
    }
 
  }
 
  
 
  return true;
 
}
 
```
 
 
**Tests - unit + opa**
 
---
 
... text ...
 
 
 
 
**Adding a google-like calendar**
 
---
 
 
I needed to show user a list of his events in a large calendar so I used library [fullcalendar](https://fullcalendar.io/).
 
 
Great demo which you can just copy and paste:
 
- https://fullcalendar.io/js/fullcalendar-3.0.0/demos/list-views.html
 
- ... just "view source" of the web and copy the js + html code, css and js files. 
 
 
```css
 
/*I added this style to hide vertical scroll-bars*/
 
.fc-scroller.fc-day-grid-container{
 
  overflow: hidden !important;
 
}
 
```
 
- Don't forget to use these files for example in your view like this:
 
 
```php
 
$this->registerCssFile('@web/css/fullcalendar/fullcalendar.css');
 
$this->registerCssFile('@web/css/fullcalendar/fullcalendar.print.css', ['media' => 'print']); 
 
 
$this->registerJsFile('@web/js/fullcalendar/moment.min.js', ['depends' => ['yii\web\JqueryAsset']]);
 
$this->registerJsFile('@web/js/fullcalendar/fullcalendar.min.js', ['depends' => ['yii\web\JqueryAsset']]);
 
 
// details here:
 
// https://www.yiiframework.com/doc/api/2.0/yii-web-view
 
```
 
 
... if you want to go pro, use NPM. The NPM way is described [here](https://fullcalendar.io/docs/getting-started).
 
 
API is  here:
 
https://fullcalendar.io/docs
 
... you can then enhace the calendar config from the example above
 
 
In order to make things work I had to force jQuery to be loaded before calendar scripts using file config/web.php like this
 
 
```php
 
   'components' => [
 
        
 
// ...
 

 
       'assetManager' => [
 
            'bundles' => [
 
                'yii\web\JqueryAsset' => [
 
                    'jsOptions' => [ 'position' => \yii\web\View::POS_HEAD ],
 
                ],
 
            ],
 
        ],
 
```
 
 
You can customize the calendar in many ways. For example different event-color is shown [here](https://fullcalendar.io/docs/event-colors-demo). Check the source code.
 
 
**Scenarios - UNKNOWN SCENARIO EXCEPTION**
 
---
 
I have been using scenarios a lot but today I spent 1 hour on a problem - I had 2 scenarios and one of them was just assigned to the model ...
 
 
```php
 
$model->scenario = "abc";
 
```
 
 
... but had no **rule** defined yet. I wanted to implement the rule later, but I didnt know that when you set a scenario to your model it **must** be used in method rules() or defined in method scenarios(). So take this into consideration. I expected that when the scenario has no rules it will just be skipped or deleted. 
Note: If you are using the advanced demo app, [this](https://stackoverflow.com/questions/37451324/how-to-change-base-url-and-enable-prettyurl-in-yii2) link can be interesting for you.
 
 
Yii 2 has the speciality that index.php is hidden in the web folder. I didnt find in the official documentation the important info - how to hide the folder, because user is not interested in it ...
 
 
Our demo application is placed in folder:
 
- C:\xampp\htdocs\basic\web\index.php
 
 
Now you will need 2 files named .htaccess
 
- C:\xampp\htdocs\basic\web\\.htaccess
 
- C:\xampp\htdocs\basic\\.htaccess
 
 
The first one is mentioned in chapter **Nice URLs** and looks like this:
 
 
```
 
RewriteEngine on
 
RewriteCond %{REQUEST_FILENAME} !-d
 
RewriteCond %{REQUEST_FILENAME} !-f
 
RewriteRule . index.php [L]
 
```
 
 
The second is simpler:
 
 
```
 
RewriteEngine on
 
RewriteRule ^(.*)$ web/$1 [L]
 
```
 
 
... it only adds the word "web" into all URLs. But first we have to remove the word from URLs. Open file config/web.php and find section **request**. Add attribute **baseUrl**:
 
 
```
 
'request' => [
 
  // 'cookieValidationKey' => ...
 
  'baseUrl' => '/basic', // add this line
 
],
 
```
 
Now things will work for you. But it might be needed to use different value for devel and productive environment. Productive web is usually in the root-folder so baseUrl should be en empty string. I did it like this:
 
 
```php
 
$baseUrlWithoutWebFolder = "";
 
if (YII_ENV_DEV) {
 
  $baseUrlWithoutWebFolder = '/basic';
 
}
 
 
// ...
 
 
'request' => [
 
  // 'cookieValidationKey' => ...
 
  'baseUrl' => $baseUrlWithoutWebFolder,
 
],
 
 
```
 
 
I will test this and if I find problems and solutions I will add them.
 
 
**Auto redirection from login to desired URL **
 
---
 
... to be added  ...
 
 
**What to change when exporting to the Internet**
 
---
 
- Delete file web/index-test.php
 
- In file web/index.php comment you 2 first lines containing YII_DEBUG + YII_ENV
 
- Delete the text from view site/login which says "You may login with admin/admin or demo/demo."
 
 
**Saving contact inqueries into DB**
 
---
 
```sql
 
DROP TABLE IF EXISTS `contact` ;
 
 
CREATE TABLE IF NOT EXISTS `contact` (
 
  `id` INT NOT NULL AUTO_INCREMENT,
 
  `name` VARCHAR(45) NOT NULL,
 
  `email` VARCHAR(45) NOT NULL,
 
  `subject` VARCHAR(100) NOT NULL,
 
  `body` TEXT NOT NULL,
 
  PRIMARY KEY (`id`))
 
ENGINE = InnoDB;
 
```
 
 
- Create the DB table
 
- Generate Model + CRUD using GII
 
- In Site controller replace ContactForm with Contact (in section "use" and in actionContact) and in the action change the IF condition:
 
```php
 
use app\models\Contact;
 
// ... 
 
public function actionContact() {
 
    $model = new Contact();
 
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
 
    // ...
 
```
 
- Open the new contact model and add one attribute and 2 rules:
 
 
```php
 
public $verifyCode;
 
// ...
 
  ['verifyCode', 'captcha'],
 
  ['email', 'email'],
 
 
// and translation for Captcha
 
'verifyCode' => Yii::t('app', 'Verification'),
 
```
 
 
- You can also delete one paragraph from view/site/contact
 
```php
 
<p>
 
Note that if you turn on the Yii debugger ...
 
```
 
 
Then some security - filtering users in the new ContactController:
 
 
```php
 
public function beforeAction($action) {
 
 
  if (!parent::beforeAction($action)) {
 
    return false;
 
  }
 
 
  $guestAllowedActions = [];
 
 
  if (Yii::$app->user->isGuest) {
 
    if (!in_array($action->actionMethod, $guestAllowedActions)) {
 
      return $this->redirect(['site/index']);
 
    }
 
  }
 
  
 
  return true;
 
}
 
```
 
 
**Tests - unit + opa**
 
---
 
... text ...
 
 
 
 
**Adding a google-like calendar**
 
---
 
 
I needed to show user a list of his events in a large calendar so I used library [fullcalendar](https://fullcalendar.io/).
 
 
Great demo which you can just copy and paste:
 
- https://fullcalendar.io/js/fullcalendar-3.0.0/demos/list-views.html
 
- ... just "view source" of the web and copy the js + html code, css and js files. 
 
 
```css
 
/*I added this style to hide vertical scroll-bars*/
 
.fc-scroller.fc-day-grid-container{
 
  overflow: hidden !important;
 
}
 
```
 
- Don't forget to use these files for example in your view like this:
 
 
```php
 
$this->registerCssFile('@web/css/fullcalendar/fullcalendar.css');
 
$this->registerCssFile('@web/css/fullcalendar/fullcalendar.print.css', ['media' => 'print']); 
 
 
$this->registerJsFile('@web/js/fullcalendar/moment.min.js', ['depends' => ['yii\web\JqueryAsset']]);
 
$this->registerJsFile('@web/js/fullcalendar/fullcalendar.min.js', ['depends' => ['yii\web\JqueryAsset']]);
 
 
// details here:
 
// https://www.yiiframework.com/doc/api/2.0/yii-web-view
 
```
 
 
... if you want to go pro, use NPM. The NPM way is described [here](https://fullcalendar.io/docs/getting-started).
 
 
API is  here:
 
https://fullcalendar.io/docs
 
... you can then enhace the calendar config from the example above
 
 
In order to make things work I had to force jQuery to be loaded before calendar scripts using file config/web.php like this
 
 
```php
 
   'components' => [
 
        
 
// ...
 

 
       'assetManager' => [
 
            'bundles' => [
 
                'yii\web\JqueryAsset' => [
 
                    'jsOptions' => [ 'position' => \yii\web\View::POS_HEAD ],
 
                ],
 
            ],
 
        ],
 
```
 
 
You can customize the calendar in many ways. For example different event-color is shown [here](https://fullcalendar.io/docs/event-colors-demo). Check the source code.
 
 
**Scenarios - UNKNOWN SCENARIO EXCEPTION**
 
---
 
I have been using scenarios a lot but today I spent 1 hour on a problem - I had 2 scenarios and one of them was just assigned to the model ...
 
 
```php
 
$model->scenario = "abc";
 
```
 
 
... but had no **rule** defined yet. I wanted to implement the rule later, but I didnt know that when you set a scenario to your model it **must** be used in method rules() or defined in method scenarios(). So take this into consideration. I expected that when the scenario has no rules it will just be skipped or deleted. 
 
 
**Richtext / wysiwyg HTML editor - Summernote**
 
---
 
If you want to allow user to enter html-formatted text, you need to use some HTML wysiwyg editor, because ordinary TextArea can only work with plain text. It seems to me that [Summernote](https://summernote.org/getting-started/#simple-example) is the simplest addon available:
 
 
```javascript
 
// Add following code to file layouts/main.php .. 
 
// But make sure jquery is already loaded !! 
 
// - Read about this topic in chapter "Adding a google-like calendar"
 
 
<!-- include summernote css/js -->
 
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.css" rel="stylesheet">
 
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.js"></script>
 
 
// And then in any view you can use this code:
 
 
<script>
 
$(document).ready(function() {
 
  $('#summernote1').summernote();
 
  $('#summernote2').summernote();
 
});
 
</script>
 
<div id="summernote1">Hello Summernote</div>
 
 
<form method="post">
 
  <textarea id="summernote2" name="editordata"></textarea>
 
</form>
 
 
```
 
 
On this page I showed how to save Contacts inqueries into database. If you want to use the richtext editor in this section, open view contact/\_form.php and just add this JS code:
 
 
```javascript
 
<script>
 
$(document).ready(function() {
 
  $('#contact-body').summernote();
 
});
 
</script>
 
```
 
 
It will be saved to DB as HTML code. But this might be also a source of problems, because user can inject some dangerous HTML code. So keep this in mind.
 
 
Now you will also have to modify view contact/view.php like this in order to see nice formatted text:
 
 
```php
 
DetailView::widget([
 
  'model' => $model,
 
  'attributes' => [
 
    // ...
 
    'body:html',
 
  ],
 
])
 
```
 
... to discover all possible formatters, check all asXXX() functions on [this](https://www.yiiframework.com/doc/api/2.0/yii-i18n-formatter) page: 
 
 
**SEO optimization**
 
---
 
This is not really a YII topic but as my article is some kind of a code-library I will paste it here as well.
 
To test your SEO score you can use special webs. For example [seotesteronline](https://suite.seotesteronline.com/seo-checker), but only once per day. 
 
It will show some statistics and recommend enhancements so that your web is nicely shown on FB and Twitter or found by Google.
 
 
Important are for example OG meta tags or [TWITTER meta tags](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary). They are basicly the same. Read more [here](https://css-tricks.com/essential-meta-tags-social-media/). You can test them at [iframely.com](http://debug.iframely.com).
 
 
Basic tags are following and you should place them to head:
 
- Note that Twitter is using attribute "name" instead of "property" which is defined in OG
 
- btw OG was introduced by Facebook. Twitter can process it as well, but SEO optimizers will report an error when Twitter's tags are missing.
 
 
```html
 
 
<!DOCTYPE html>
 
<html lang="<?= Yii::$app->language ?>">
 
<head>
 
 
  <meta property="og:site_name" content="European Travel, Inc.">
 
  <meta property="og:title" content="European Travel Destinations">
 
  <meta property="og:description" content="Offering tour packages for individuals or groups.">
 
  <meta property="og:image" content="http://euro-travel-example.com/thumbnail.jpg">
 
  <meta property="og:url" content="http://euro-travel-example.com/index.htm">
 
  <meta name="twitter:card" content="summary_large_image">
 
 
  <!--  Non-Essential, But Recommended -->
 
  <meta property="og:site_name" content="European Travel, Inc.">
 
  <meta name="twitter:image:alt" content="Alt text for image">
 
 
  <!--  Non-Essential, But Required for Analytics -->
 
  <meta property="fb:app_id" content="your_app_id" />
 
  <meta name="twitter:site" content="@website-username">
 
  
 
  <!-- seotesteronline.com will also want you to add these: -->
 
  <meta name="description" content="blah blah">
 
  <meta property="og:type" content="website">
 
  <meta name="twitter:title" content="blah blah">
 
  <meta name="twitter:description" content="blah blah">
 
  <meta name="twitter:image" content="http://something.jpg">
 
```
 
 
Do not forget about file robots.txt and sitemap.xml:
 
 
```
 
// robots.txt can contain this:
 
User-agent: *
 
Allow: /
 
 
Sitemap: http://www.example.com/sitemap.xml
 
```
 
 
```
 
// And file sitemap.xml
 
<?xml version="1.0" encoding="UTF-8"?>
 
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
 
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
 
  <url>
 
    <loc>http://example.com/someFile.html</loc>
 
    <image:image>
 
      <image:loc>http://example.com/someImg.jpg</image:loc>
 
    </image:image>
 
  </url> 
 
</urlset> 
 
```
 
 
You can also minify [here](https://www.willpeavy.com/tools/minifier/) or [here](http://minifycode.com/html-minifier/) all your files. Adding "microdata" can help as well, but I have never used it. On the other hand what I do is that I compress images using these two sites [tinyjpg.com](https://tinyjpg.com/) and [tinypng.com](https://tinypng.com/).
 
 
**Other useful links**
 
---
 
 
- [SVG to CSS-background-image convertor](https://websemantics.uk/tools/svg-to-background-image-conversion/)
2 0
1 follower
Viewed: 11 540 times
Version: 2.0
Category: Tutorials
Written by: rackycz
Last updated by: rackycz
Created on: Sep 19, 2019
Last updated: 28 days ago
Update Article

Revisions

View all history