Friday, February 09, 2018

Laravel quick application tutorial

Ok, so we have installed Laravel. Now let's start coding our CRUD (create/read/update/delete) application.

First, we will create our new application so go to a directory of choice and type:
laravel new market
Laravel will create a new directory with the name market and place all its framework files inside, ready to work. Now go to this directory with cd market and let start our web server on port 8000 with:
php artisan serve
Then open up the browser at: http://localhost:8000 to see the default laravel installation page.

Models
Now let's create our database and let laravel manage the tables inside by doing migrations and creating models around the database logic.
In order to create the database we will use our mysql client:
mysql -u root -p
(where username is root, here you can use the user which mysql is installed on your system)
Next, we will create our main database:
create database market
then exit the mysql client
and we will connect laravel to the database. For this open up the environment file: /market/.env and set up mysql user and password sections with your own.
 
Laravel uses ORM (Object-relational mapping) to abstract database table operations, so it wraps models around the tables, making ordinary operations easier via php objects. Models reside in the directory: market/app/model.php.
Let's create our first model:
php artisan make:model -m Product
(here the command creates table products (in plural) and model Product, connected to it).
You can use phpmyadmin to see the newly created table.

Migrations
Next, we need to specify the fields we would like to have in our tables. By using migrations we can change the structure of our tables add/change/remove fields and their properties. Migrations are text files residing in: market/database/migrations
If you look inside a migration file there are usually two functions up()->when the table will be created and down() for when the table will be deleted.
Inside up() place:
$table->increments('id');
$table->string('title')->unique();
$table->string('description');
$table->integer('price');
$table->timestamps();
next to perform the actions described in the migration we will just refresh (redo) the performed migrations so type:
php artisan migrate:refresh
you can go ahead and check within phpmyadmin that the new table's structure is actually changed having more fields inside.

Controllers
In order to work with the data from the tables laravel uses controllers. Let's create one:
php artisan make:controller -m Product ProductController
with this command, we create ProductController file connected to our Product model. Controllers reside in app/Http/Controllers/ . We can see our file there, it is already prepared with the basic actions as functions() we would like to fill in.

Routes
One way for the user to trigger a controller action is via routes (routes/web.php). Routes connect an URL with a controller action or a view. So open up the file and replace the default: return view('welcome'); with: return 'Hello';
then refresh the browser and see the change.
Now, let's replace the file contents with:
Route::resource('products','ProductController');
this will create a so-called resource-route which will connect our ProductController to url: /products
In order to see how many rules this resource-route handles type: php artisan route:list



We see that whenever we access /products it invokes the index() method of ProductsController. From the table you can follow the rest of the urls and their representative actions.
Next, we modify the controller's index action and trigger a view from there:
$products="Hello from products"
return view('products.index',['products'=>$products]);
to decrypt :) this will invoke a view file from directory view/products called index.blade.php and pass $products as a parameter to it.
Now is time to create this directory market/resources/views/products.
As well as the index.blade.php inside, with the following content to display the products:
 {{$products}} 
( Using double curly braces in the view we could output parameters passed from the controller. )
 
Please test in the browser.
Next, create some fake products inside phpmyadmin and in order to see them just replace in our controller:
$products=Product::all();
(this is the ORM way of doing it)


Layouts
So far we have only displayed the products list, so let's extend the current view. First we will explore how to work with layouts. They allow us to include common HTML and CSS parts across multiple views, reducing potential code repetition.
In order to use layouts create app.blade.php into views/layouts folder and place all your main HTML including CSS links there. Inside put also: yield('main'). This yield will become a placeholder where Laravel will include all information fetched from the .blade view files.
The following is our completed view index.blade.php file which uses our layouts.app layout and inside its 'main' section inserts:

@extends('layouts.app')
@section('main')

<a href="{{route('products.create')}}" class="btn">Add new product</a>
<br/>

@foreach($products as $product)
<div class="products">
<a href="{{route('products.show',$product)}}">{{ $product->title }} </a> - ${{ $product->price }}  <br/>
<br />

<a href="{{route('products.edit',$product)}}" class="btn">Edit</a>

<form method="post"  action={{route('products.destroy',$product)}} >
{{method_field('DELETE')}}
{{csrf_field()}}

<input class="inline btn" type="submit" value="Delete" />

</form>

<br /><br/>
</div>
@endforeach

@endsection

In short, we have added buttons for adding, editing and deleting products using a loop for each of our products. We are also using the internal Laravel function route() in order to construct user clickable urls, taken from the route list table discussed above. The route generation in some cases requires additional parameter like $product information in order for Laravel to know which product to work with. For security reasons, the delete button functionality uses a form. Inside you can see uniquely generated csrf() field to ensure that we could only send the form thus protecting it from malicious usage. Lastly in order to make the form to function Laravel requires to modify or model and add the fields allowed to be mass-modified. So in /app/Product.php add
protected $fillable=['title','description','price','image_url'];
So go ahead save, and let's move on.

Adding new products
please add to our ProductsController:
 public function create()
    {
        return view('products.create');
    }
which will show the create.blade.php:
@extends('layouts.app')
@section('main')

@if ($errors->any())
<ul>
    @foreach ($errors->all() as $error)
    <li>{{$error}}</li>
    @endforeach
</ul>
@endif

<form action="{{ route('products.store') }}" method="post" >
{{csrf_field()}}
<label for="title">Product Name</label>
<input placeholder="product 1" type="text" name="title" id="title" />

<label for="description">Description</label>
<input placeholder="product description" type="text" name="description" id="description" />

<label for="price">Price</label>
<input placeholder="100" type="text" name="price" id="price" />

<button type="submit">Create</button>

@endsection

By far the code looks familiar, the first few lines just display if any errors occur while adding our product. We notice that when submitted, this form goes to products.store route, leading to our controller. So let's create the corresponding ProductController method:
   public function store(Request $request)
    {
        $customMessages = [
            'title.unique'=>'Please choose another product title'
        ];

        $this->validate($request,
            ['title' => 'required|unique:products'],
            $customMessages
        );
    
        Product::create($request->all());
        return redirect('products');
    }

Here we have included a custom message to be displayed when the 'title' of the product about to be entered already exists in the database ->yes Laravel do this for us automatically. If everything is ok, the product is created, using all the parameters sent from the $request and we display the product view.

Editing products
In the ProductController we would like to trigger the edit.blade.app view:
  public function edit(Product $product)
    {
        return view('products.edit',['product'=>$product]);
    }

wherein edit.blade.app:

@extends('layouts.app')
@section('main')

@if ($errors->any())
<ul>
    @foreach ($errors->all() as $error)
    <li>{{$error}}</li>
    @endforeach
</ul>
@endif

<form action="{{ route('products.update',$product) }}" method="post" >
{{csrf_field()}}
{{method_field('patch')}}
<label for="title">Product Name</label>
<input placeholder="product 1" type="text" name="title" id="title" value="{{$product->title}}" />

<label for="description">Description</label>
<input placeholder="product description" type="text" name="description" id="description" value="{{$product->description}}" />

<label for="price">Price</label>
<input placeholder="100" type="text" name="price" id="price" value="{{$product->price}}"/>

<button type="submit">Update</button>

@endsection

The update form above is being pre-filled with information about the product we already have, using the {{$product->property}} notation. We have also included the 'patch' method, as described in the route table above in order for Laravel to trigger the ProductController update method:

 public function update(Request $request, Product $product)
    {
        $customMessages = [
            'title.unique'=>'Please choose another product title'
        ];

        $this->validate($request,
            ['title' => 'required|unique:products'],
            $customMessages
        );

        $product->update($request->all());
        return redirect('products');
    }

We see almost the same code as in the create method, just using the update() function.

Deleting products
For the delete button, we don't need a view, here is just its code in the controller:
   public function destroy(Product $product)
    {
        $product->delete($product->id);
        return redirect('products');
    }
We believe that by now you can do the view method very easy!

That's it! Enjoy!

Wednesday, July 26, 2017

Install PHPMyAdmin and Nginx on Ubuntu 19.04

Knowing how to install PHPMyAdmin and Nginx is essential when developing web applications, it is also very useful while taking comprehensive course projects, which prefer local installations.

References: Practical Ubuntu Linux Server for beginners

You can watch the video on the subject: 

So let's start first the installation of Nginx:
sudo apt-get install nginx
(optional) check if its ports are enabled in the firewall: sudo ufw status
and enable port 80 if necessary:
sudo ufw allow 'Nginx HTTP'
find and note your ip address with: ifconfig

open up in browser: http://127.0.0.1 and you should see: Welcome to NGINX

now is time to install MySQL-server:
sudo apt-get install mysql-server
remember to set a password!

(optional) secure mysql: sudo mysql_secure_installation


change the connection of MySQL from a socket to password authentication and set its password to password (to be able to use the root account within PHPMyAdmin):
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
next, apply the changes with:
FLUSH PRIVILEGES;
EXIT


install php-fpm to enable Nginx to communicate with PHP, as well as php-mysql to enable PHP to communicate with MySQL databases:
sudo apt-get install php-fpm php-mysql
(optional) security for PHP (fix closest name script execution): sudo nano /etc/php/7.3/fpm/php.ini (replace /php/7.x with your PHP version (type: php -v)
inside php.ini change cgi.fix_pathinfo=0

enable Nginx to process PHP:
sudo nano /etc/nginx/sites-available/default

server {

listen 80 default_server;

listen [::]:80 default_server;

root /var/www/html;

#add index.php for processing PHP files first

index index.php index.html index.htm index.nginx-debian.html;


#you can replace 127.0.0.1 with your own ip address

server_name 127.0.0.1;


location / {

try_files $uri $uri/ =404;

}

#the actual PHP processing

location ~ \.php$ {

#enable only these two:

include snippets/fastcgi-php.conf;

fastcgi_pass unix:/run/php/php7.3-fpm.sock;

}


location ~ /\.ht {

deny all;

}

}


reload Nginx configuration:

sudo systemctl reload nginx

(optional) if problems occur: test the configuration with: sudo nginx -t


test if php is running: by creating a test file:

sudo nano /var/www/html/test_php.php

<?php

echo "php is running";

?>

save and exit with ctrl + W and ctrl + X


(optional)(if you don't have nano: sudo apt install nano )


point the browser to 127.0.0.1 you should get: php is running


Final step:

Install PHPMyAdmin (remember your MySQL password)
sudo apt-get install phpmyadmin
select apache2 installation from the dialogue.

add PHPMyAdmin configuration into Nginx in order enable /phpmyadmin directory location (127.0.0.1/phpmyadmin)
sudo nano /etc/nginx/sites-available/default
then add into the server directive:


location /phpmyadmin {

root /usr/share/;

index index.php index.html index.htm;

location ~ ^/phpmyadmin/(.+\.php)$ {

try_files $uri =404;

root /usr/share/;

fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include /etc/nginx/fastcgi_params;

}

location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {

root /usr/share/;

}

}



location /phpMyAdmin {

rewrite ^/* /phpmyadmin last;

}


notice the php7.3-fpm.sock -> replace it with your PHP version!


Here you go you are ready to run: 127.0.0.1/phpmyadmin
you can log in with "phpmyadmin" and "your_mysql_password"
( if you don't have permissions to create databases log as root and "your_mysql_password" )

phpmyadmin running on nginx in ubuntu

Cheers!

Tuesday, December 20, 2016

Screen capture video and sound on Ubuntu

There are a couple of ways you can do a screen capture on Ubuntu. The problem is that most of the integrated graphical user interfaces are either not stable and crash in the middle of recording, or are not using proper codecs thus creating huge files, which one has to convert in order to edit or publish.

I'll share the two basic and reliable tools I'm using: Simple Screen Recorder and manually recording via FFmpeg:
For the Simple Screen Recorder is notable that it has pause shortcuts as well as one can adjust its various options very easily.
Image: screenshot.png
Installation:
sudo add-apt-repository ppa:maarten-baert/simplescreenrecorder
sudo apt-get update
sudo apt-get install simplescreenrecorder
Afterward, just start using the program.

The second option is to manually record your screen. The first step is to install FFmpeg
sudo apt-get install ffmpeg
 Then create capture.sh file with
sudo nano capture.sh
and place the following information inside. Contents of the screen recorder:
#!/bin/sh
#
REC_iface=$(pactl list sources short | awk '{print$2}')
SCREEN_res=$(xrandr -q --current | grep '*' | awk '{print$1}')
REC_iface=alsa_input.usb-Superlux_digit_Superlux_E205U-00.analog-stereo
ffmpeg -async 1 -threads auto -f pulse -i $REC_iface -ac 2 -acodec vorbis -f x11grab -thread_queue_size 1024 -r 15 -s $SCREEN_res -i :0.0 -vcodec libx264 -crf 36 -preset slow -pix_fmt yuv420p  screencast.mp4
the only thing you need to change in this file is the REC_iface, this is your microphone input which you can find with the command:
pactl list sources short
Afterward, give chmod +x capture.sh to the file to make it executable.

then start the capturing process:
./capture.sh
this will start the recorder. Wait 5 seconds and start your screencast. When ready just click CTRL+C to stop the recording.

Cheers!

Saturday, December 10, 2016

Install OpenStack Mitaka under Virtualbox

First, let's get VirtualBox and set up our VirtualBox machine:

Give it at least 6 GB RAM, having a 64-bit processor
Then create 3 networks:
NatNetwork(for connection with the external world) with address: 10.0.2.0/24, to support DHCP
and allow port forwarding which we will use to connect to the internal Virtual Machine (VM)s:
name:ssh, protocol: TCP, host IP: 10.0.2.15, host port 22, guest IP: 127.0.0.1, guest port:2022
this way you can use ssh or putty to connect to 127.0.0.1:2022 and access the internal Virtual machines.
Next, create 2 other host-only networks with the following details(for communication and data transfer):
ip:10.50.0.1
mask:255.255.255.0
and
ip:10.254.254.1
mask:255.255.255.0
both with DHCP disabled

SSH access:
If you experience problems connecting to the Virtual Machine, you can try to disable and stop the firewall:
sudo systemctl disable firewalld
sudo systemctl stop firewalld
add an exception for SSH access in the firewall
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
check the selinux configuration
sudo nano /etc/selinux/config
check the open ports on your network with:
1. find all the networks you would like to inspect:
ip a |more
2. Install and use Nmap to portscan those networks:
sudo yum install nmap
scan the open ports on the virtual machines:
nmap 10.0.2.*
nmap 10.254.254.*

Install CentOS host system
Download CentOS minimal ISO and boot up the machine via VirtualBox.
Once logged in in the VM, edit the sudoers file and place your account there:  sudo cat /etc/sudoers
(instead of always typing sudo in front of the commands, you can write: sudo -i and continue working)
sudo dhclient - to make DHCP give access to the Virtual machines to outside(Internet) IP addresses
then edit /etc/resolv.conf sudo nano /etc/resolv.conf and add google nameserver 8.8.8.8 to be able to fetch internet websites from VM.

Configure the three network interfaces using information such as IP addresses from above :
cd /etc/sysconfig/network-scripts/
sudo nano ifcfg-enp0s3
sudo ifdown enp0s3
sudo ifup enp0s3
(repeat the process for enp0s9 and enp0s8)
check if the configuration is correct
ip a

Preparing installation
We need to install additional packages:
sudo yum install wget tcpdump curl
install network synchronizing time server
sudo yum install ntp
set the hostname of our virtual machine:
sudo hostnamectl set-hostname myopenstack.com
stop and disable network interference from Network Manager:
sudo systemctl stop NetworkManager.service
sudo systemctl disable NetworkManager.service


Upgrade to the latest available kernel to ensure better performance on virtualization and integration with VirtualBox:
enable elrepo kernel repository
yum --enablerepo=elrepo-kernel install kernel-ml
install ncurses library:
sudo  yum install gcc ncurses ncurses-devel
sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
sudo rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
install fastestmirror to get closest repository:
sudo yum install yum-plugin-fastestmirror
install the kernel:
sudo yum --enablerepo=elrepo-kernel install kernel-ml
Reboot the system to make new kernel effectively loading
sudo reboot
check the kernel version
uname -a

Installing OpenStack Mitaka
get the RDO-release:
sudo yum install http://rdo.fedorapeople.org/rdo-release.rpm
then install the RPM package: sudo yum install openstack-packstack
Generate answers file for easier installation configuration of OpenStack
sudo packstack --gen-answers-file=.answers.cfg
install OpenStack using the answer-file:
sudo packstack --answer-file=.answers.cfg
Upgrade the openstack distribution as well as all other CentOS packages
sudo yum upgrade

Enter OpenStack dashboard using browser
(in Windows you can install xming server - to allow access from outside to OpenStack via ssh graphical screen )

install xauth authorization
sudo yum install xauth
sudo yum groupinstall fonts
*start the graphical terminal xterm
export DISPLAY=:0.0
start firefox and open up OpenStack dashboard
firefox 10.254.254.100/dashboard

Congratulations, you can now start using OpenStack :)
Enjoy!

Saturday, December 03, 2016

How to install the newest kernel on Ubuntu

Being with the latest stable kernel usually brings lots of benefits resulting in:

- having the latest supported drivers for your hardware
- fixing commonly reported bugs
- increase in overall system performance
- various speed and stability related, software-oriented optimizations
Reference: Practical Ubuntu Linux Server for beginners

Here is a video of the update process:



In order to do a simple kernel upgrade, so to be sure to have the latest one installed.
First visit: https://www.kernel.org/
Then choose from stable or unstable(mainline) kernel branch you would like to have your kernel installed. Just look up the numbers. Note: r.c. has the meaning of release candidate, so the kernel is still in development.
Then go to http://kernel.ubuntu.com/~kernel-ppa/mainline/
You'll find a huge directory with supported kernels tailored for Ubuntu distributions.
Scroll down, to pick the chosen one and enter its directory. Then open up a terminal and write:

cd /tmp
This way we will enter the temporary folder, which will be erased automatically when we reboot our machine.
We have to download the proper kernel version. To check if we have 32 or 64-bit system installed  type:
uname -m
which if shows i686 then your kernel should be 32 bit, and if shows x86_64 then you have to download the 64-bit kernel packages.
Next point at the right kernel with the right mouse click, copy the link location from 3 files: one with a name ending on: _all, and two _generic .deb packages
  linux-headers-4.15.2-041502_4.15.2-041502.201802072230_all.deb
  linux-headers-4.15.2-041502-generic_4.15.2-041502.201802072230_amd64.deb
  linux-headers-4.15.2-041502-lowlatency_4.15.2-041502.201802072230_amd64.deb
  linux-image-4.15.2-041502-generic_4.15.2-041502.201802072230_amd64.deb
  linux-image-4.15.2-041502-lowlatency_4.15.2-041502.201802072230_amd64.deb

from those we need to download everything, except the 2 lowlatency packages.
In terminal just enter wget then paste the link location. Here follows an example of the first package:
wget linux-headers-4.15.2-041502_4.15.2-041502.201802072230_all.deb
The last step is to install the downloaded packages using sudo privileges:
sudo dpkg -i linux*
Reboot the computer in order to load the new kernel:
sudo reboot

If you have problems with the newly installed kernel, just press several times on restart the 'ESC' key and choose from Advanced options the previous working stable kernel version.
After some time you may notice that kernels begin to pile up, thus reducing your disk space. I advise you to remove the redundant ones with: sudo apt remove linux- and then list the not used: modules, image and headers packages.
Congratulations and happy learning!

Wednesday, November 30, 2016

Install Laravel on Ubuntu

Here is briefly how to do a basic install of Laravel on Ubuntu. First, get the PHP language interpreter. And here is updated video on how to do the installation on Ubuntu 19.04 / 19.10, also, please enjoy the Ubuntu admin course



sudo apt-get install php
Then install and run composer which will take care of packages dependencies:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
copy composer binary file into /sbin directory to be able to run composer from everywhere.
sudo mv composer.phar /usr/local/sbin/composer
or update the local path to be able to access composer vendor binaries and later be able to run laravel: export PATH = "$HOME/.config/composer/vendor/bin:$PATH" . If you would like the path change to be persistent just add the line into the .bashrc file.

install the two minimal PHP libraries required for laravel:
sudo apt-get install php-mbstring
sudo apt-get install php-xml
use composer to create a new project called learning-laravel from a package named laravel/laravel. The new directory which package would get installed will be called learning-laravel:
composer create-project laravel/laravel learning-laravel
enter into the new directory
cd learning-laravel
and start a local listening PHP server on port 8888 and address localhost(127.0.0.1). This will also make PHP interpret all the files within the subdirectory /public:
php -S localhost:8888 -t public
Open a browser on localhost:8888 Congratulations! You have installed a running Laravel project!

Subscribe To My Channel for updates