Month: December 2021

Enable Chinese in Windows 10

Enable Chinese in Windows 10

Add Preferred Languages

  • Go to Settings => Time & Language

  • Go to Language => Preferred languages

  • Click on Add a language to add Chinese

Add Keyboard (Input Method)

After language added in previous step

  • Go to Language options => Keyboards

  • Select Add a keyboard, then select input method to be added

Change locale (Default non-Unicode language)

After language added in first step

  • Click on Administrative language settings, then Region => Administrative window appears

  • Click on Change system locale..., Region Settings window appears

  • Select Chinese in Current system locale

  • Click on OK button

Turn on Hibernate in Windows 10

Turn on Hibernate in Windows 10

In power menu

  • Goto Control Panel\Hardware and Sound\Power Options\System Settings

  • Click on Change settings that are currently unavailable, this is to enable check box of Hibernate

  • Check Hibernate

  • Click on Save Changes

Minutes before Hibernate

  • Goto Control Panel\Hardware and Sound\Power Options\Edit Plan Settings

  • Click on Change plan settings beside current plan

  • Click on Change advanced power settings, then Power Options window appears

  • Expand Sleep->Hibernate after, change value in Settings

Remote Desktop

  • Goto Settings=>For developers=>Remote Desktop

  • Deselect Change settings so that the PC never hibernates when plugged in

Learning – Fat-Free PHP Framework (Template Hierarchy)

Learning - Fat-Free PHP Framework (Template Hierarchy)

Template Hierarchy

Copy from bootstrap

  • Go to https://getbootstrap.com/getting-started/#examples, select Dashboard.

  • Copy dashboard.htm to app/views/dashboard.htm

  • Copy dashboard.css into app/css/dashboard.css

  • Create app/views/header.htm

    • Move html header in dashboard.htm into header.htm
    • Delete unecessary javascript for IE8
    • Update bootstrap.min.css to CBN version
    • Update the path of dashboard.css
  • Create app/views/layout.htm

<include href="header.htm" />
<include href="{{ @view }}" />
  • Update MainController class
<?php

class MainController extends Controller {
    function render() {
        $this->f3->set(&#039;view&#039;, &#039;dashoboard.htm&#039;);
        $template = new Template;
        echo $template->render(&#039;layout.htm&#039;);
    }
}
  • Create nav.htm

Move the body contents before Dashboard div into file nav.htm

<body>
    ...
    ...
            <ui class="nav nav-sidebar">
                ...
            </ui>
        </div>

References

Template Hierarchy in Fat-Free PHP Framework Sample Project

Learning – Fat-Free PHP Framework (Bootstrap & Authentication)

Learning - Fat-Free PHP Framework (Bootstrap & Authentication)

Bootstrap & Authentication

Bootstrap

Front design, https://getbootstrap.com, includes CCS, Components, etc.

Getting start has examples, sign in page can be downloaded as well.

Bootstrap CDN - Content delivery network online

Content to be included

Include css into the head tag of the page

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

Include the java script just before the closing of body tag

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

Create structure for login page

  • Create app/views/login.htm

  • Create app/models/User.php

  • Create app/controllers/UserController.php

  • Create app/css/signin.css or a static folder for this

  • Copy bootstrap login sample html to login.htm

  • Copy bootstrap login sample css to signin.css

Create page

  • Clean up login.htm

  • Create UserController.php

class UserController extends Controller {
    function render() {
        $template = new Template;

        echo $template->render('login.htm');
    }
}
  • Update routes.ini

Add

GET /login=UserController->render

The login page built as https://localhost:8088/login

Customize login page

Remove Remember me and change variable names, and name attribute for input fields

Authentication

Update routes.ini

Add following line

POST /authenticate=UserController->authenticate

Update form in login.htm

<form class="form-signin" method="POST" action="/authenticate">

Create table

Create table user with id, username, password.

Create password

$ php -a
echo password_hash('f3password', PASSWORD_DEFAULT);
$2y......

Add user and password

Add an user with username=f3user and the password=$2y......

Create model for user

Create User.php by modifying Messages.php

class User extends DB\SQL\Mapper {
    public function __construct(DB\SQL $db) {
        parent::__construct($db, 'user');
    }

    public function getByName() {
        $this->load(array('username=?', $name));
    }

    public function all() {
        $this->load();
        return $this->query;
    }

    ...

*Note: Function all() can be used to assign to a variable, getByName() is return the object itself.

Add authenticate function in UserController class

function authenticate() {
    $username = $this->f3->get('POST.username');
    $password = $this->f3->get('POST.password');

    $user = new User($this->db);
    $user->getByName($username);

    if ($user->dry()) {
        // echo 'User does not exist.';
        $this->f3->reroute('/login')
    }

    if (password_verify($password, $user->password)) {
        // echo 'password OK';
        $this->f3->reroute('/');
    }
    else {
        // echo 'password NOT OK';
        $this->f3->reroute('/login')
    }
}

Note: dry() is db function.

Create session

Look for Fat-Free Session Handler

  • Enable cache

Add following line in config.ini

CACHE=true
  • Update index.php
...
new Session();

$f3->run();
  • Add following line in function authenticate in UseController class
if (password_verify($password, $user->password)) {
    $this->f3->set('SESSION.user', $user->usename)'
    $this->f3->reroute('/');
}

Update function beforeroute in Controller class

function beforeroute() {
    if ($this->f3->get('SESSION.user') === null) {
        $this->f3->reroute('/login');
        exit;
    }
}

Update UserController class

Because this update is in Controller class, so every page will go thru the verification. To ignore this behavior for login.htm, update UserController class. Adding following empty function to overwrite beforeroute()

function beforeroute() {
}

References

Adding Bootstrap and User Authentication to Fatfree PHP MVC Project

Mount SMB3 in Linux

Mount SMB3 in Linux

Install package

sudo apt install cifs-utils

Mount from command line

sudo mount -t cifs //192.168.1.100/Movies /mnt/Media vers=3.0,credentials=/etc/smbcredentials,uid=111,gid=1000,pass=PASSWORD

Add into /etc/fstab

  • Create credentials file /etc/smbcredentials
username=user
password=password
domain=domain
  • Update mode
chown root:root /etc/smbcredentials
chmod 600 /etc/smbcredentials
  • Update /etc/fstab
//server/share_name  /mnt/smbshare  cifs  credentials=/etc/smbcredentials,vers=3.0,file_mode=0755,dir_mode=0755 0       0

References

How to Mount Windows Share on Linux using CIFS

Learning Fat-Free PHP Framework

Learning Fat-Free PHP Framework

Fat-Free PHP Framework is used to create MVC application.

Make Fat-Free work

Install composer

  • Go to https://getcomposer.org

  • Select Installation => Globally

  • Download installer and run it using php, then composer.phar is created

  • Move composer.phar to system directory

mv composer.phar /usr/local/bin/composer

Install Fat-Free

  • Create a new project folder

  • Init composer, and answer some questions, then composer.json is created

composer init
  • Go to http://getcomposer.org, select Browse Packages, then go to https://packagist.org.

  • Search fatfree to find out package name, bcosca/fatfree

  • Install bcosca/fatfree

    • by editing composer.json file

    Add following lines

      "require": {
        "bcosca/fatfree": 3.5.0
      }
    }

    Run composer update, to install fatfree in vendor directory, and composer.lock is created

    • by command
    composer require bcosca/fatfree

Autoload

There is an autoload.php file in vendor/composer directory, this is to load packages

In base.php

  • Singleton Base class extends from abstract class Prefab

  • $hive has all configuration, context

  • Function set is to set variables

  • Function get is to read variables

  • Function run needs to be called to make F3 work and running

Create index.html

require_once("vendor/autoload.php");

$f3 = Base::instance();

$f3->route('GET /',
  function() {
    echo 'Hello, world!';
  }
);

...

$f3->run();

Note, if don't use composer, then will be like

$f3 = require('path/to/base.php');
...
$f3->run();

Launch PHP server

php -S localhost:8088 -t .

Config, Controller, View

Set/get global variables

$f3->set('message', 'Hello, World!');

$f3->route('GET /',
  function($f3) {
    echo $f3->get('message');
  }
);

Create route class

class MainController {
  function render() {
    echo 'Hello, World!';
  }
}

$f3->route('GET /', 'MainController->render');

beforeroute and afterroute function

Mainly for session management

class Controller {
  function beforeroute() {
    echo 'before';
  }

  function afterroute() {
    echo 'after';
  }
}

class MainController extends Controller {

}

configuration variables

  • DEBUG

  • AUTOLAD - to load a folder which contains the classes

  • CACHE

  • UI - location of UI templates, separate folders using delimiter

$f3->set('DEBUG', 1);

Create config.ini

In config.ini file

[globals]

DEBUG=1
messagehello=Hello hello!

In index.php

$f3->config('config.ini');

class MainController extends Controller {
  function render($f3) {
    echo $f3->get('messagehello');
  }
}

Create routes.ini

In routes.ini

[routes]

GET /=MainController->render
GET /hello=MainController->sayhello
GET /about=AboutPage->render

In index.php

$f3->config('routes.ini');

Templates

In normal php

<p>Hello, <?php echo $name; ?>!</p>

In F3

<p>Hello, {{ @name }}!</p>

In index.php

  function render($f3) {
    $f3 ->set('name', 'world');
    $template = new Template;
    echo $template->render('template.htm');
  }

Template file template.htm

<!DOCTYPE html>
<html>
<head>
    <title>Tutorial page</title>
</head>
<body>
    <p>Hello, {{ @name }}!</p>
</body>
</html>

Create project structure

In project folder

project/index.php
project/config.ini
project/routes.ini
project/app
project/app/controllers
project/app/controllers/Controller.php
project/app/controllers/MainController.php
project/app/views
project/app/views/template.htm

In config.ini file

[globals]

DEBUG=3
UI=app/views/
AUTOLOAD=app/controllers/

In index.php file

<?php

require_once("vendor/autoload.php");

$f3 = Base::instance();

$f3->config('config.ini');
$f3->config('routes.ini');

$f3->run();

Model (database)

Create database

  • Install PHP development environment XAMPP or MAMP

  • Install MySQL workbench

apt install mysql-workbench
  • Create database

  • Create schema

database Connection

  • Update database info in config.ini
devdb = "mysql:host=127.0.0.1;port=3306;dbname=f3MVC"
devdbusername = "f3admin"
devdbpassword = "f3admin"

Update Controller class

class Controller {
    protected $f3;
    protected $db;

    function __construct() {
        $f3 = Base::instance();
        $this->f3 = $f3;

        $db = new DB\SQL(
            $f3->get('devdb'),
            $f3->get('devdbusename'),
            $f3->get('devdbpassword'),
            array( \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION )
        );

        $this->db = $db;
    }
}

For other classes

$this->f3

Create project models

Create folder and a file project/models/Messages.php, which is reading all data from messages table, and then create objects.

<?php

class Messages extends DB\SQL\Mapper {
    public function __construct(DB\SQL $db) {
        parent::__construct($db, 'messages');
    }

    public function all() {
        $this->load();
        return $this->query;
    }
}

Update config.ini

AUTOLOAD=app/controllers/|app/models/

Update render function in MainController class

$messages = new Messages($this->db);
$msg = $messages->all()[0];

$f3->set('msg', $msg);

Update template.htm

<p>Hello, {{ @msg.message }}</p>

Standard implementation of model

<?php

class Messages extends DB\SQL\Mapper {
    public function __construct(DB\SQL $db) {
        parent::__construct($db, 'messages');
    }

    public function all() {
        $this->load();
        return $this->query;
    }

    public function getById($id) {
        $this->load(array('id=?', $id));
        return $this->query;
    }

    public function add() {
        $this->copyFrom('POST');
        $this->save();
    }

    public function edit() {
        $this->load(array('id=?', $id))
        $this->copyFrom('POST');
        $this->update();
    }

    public function delete($id) {
        $this->load(array('id=?', $id))
        $this->erase();
    }
}

Note: copyFrom also can do from hashmap

Save record

$message = new Messages($this->db);
$message->key = 'Secondmessage';
$message->message = 'This is the second message inserted from code.';
$message->save();

Change global to class protected variable

This allow all functions in the class do not need to pass f3 as parameter

class Controller {
    ...
    protected $f3;

    ...
}

class MainController extends Controller {
    function render() {         // Don't need f3 as parameter
        ...
        $this->f3->set('msg', $msg);
        ...
    }
}

getById

$msg = $messages->getById(8)[0];

References

Fatfree PHP Framework Tutorial - 1
Fatfree PHP Framework Tutorial - 2
Fatfree PHP Framework Tutorial - 3
Fatfree PHP Framework Tutorial - 4

Disable Apple mouse swipe action

Disable Apple mouse swipe action

It is very easy for Apple mouse understands wrongly, and take action to back to my previous page. As the result, my few hours working on WordPress disappered.

Change mouse

Then I start using normal mouse, but hard to change between screen using keyboard, my remote control and virtual machine doesn't understand the keys, and holding keyboard actions made wrong password in login screen.

Disable swipe action

Then I found the way to disable swipe action as below

system preferences>trackpad or mouse>more gestures tab>uncheck "swipe between pages".

References

I just accidentally swiped right on my web page...how do I get it back?

Docker Compose – Basic

Docker Compose - Basic

Commands

  • Start all services
docker-compose up
  • Stop all services
docker-compose down
  • Command to install Docker Compose
pip install -U docker-compose
  • Command to check the version of Docker Compose
docker-compose -v
  • Command to run docker compose file
docker-compose up -d
  • Command to list done all the process
docker-compose up -d --scale
  • Command to use YAML file to configure application services
docker-compose.yaml
  • Check logs
docker-compose logs