Let's tweet

with Laravel

Daniele Barbaro

Daniele Barbaro

Classe 84, workaholic, inge, in eterna lotta per la conquista del mondo. Da ormai 10 anni ha fatto del PHP la sua arma di conquista.

Cosa ci faccio qui?

Capire:

  • chi è il biondo che parla
  • cos'è Laravel
  • come si affronta un progetto in Laravel senza ansie
     

 

 

Daniele Barbaro

Laravel

Il framework degli artigiani web

Laravel è un framework php sviluppato da Taylor Otwell come evoluzione/alternativa di CodeIgniter/Symfony.

Usa un pattern architetturale MVC e permette di avere un approccio logico e schematico di lavorare con il codice orientato agli oggetti.

Daniele Barbaro

Daniele Barbaro

Pro

  • Artisan 
  • Documentazione
  • Community
  • Semplicità, leggibilità
  • Packages
  • ORM Eloquent
  • PSR-2 coding std and the PSR-4 autoloading std.

Daniele Barbaro

Contro

  • ORM eloquent
  • Oneman show framework
  • accessibile a tutti
  • troppa "magia"

Test tecnico colloqui

Il talk nasce dall'esigenza di dover testare le competenze di un possibile dipendente.

 

L'esercizio è: Scrivere Twitter.

 

https://bit.ly/2X8QzRj

 

Daniele Barbaro

Daniele Barbaro

Let's Start!

Daniele Barbaro

composer create-project --prefer-dist laravel/laravel twitter
composer require --dev squizlabs/php_codesniffer
composer require --dev barryvdh/laravel-ide-helper
composer require --dev barryvdh/laravel-debugbar

Pacchetti Base sviluppo:

Standards: https://bit.ly/2I2eA6h

Auth Scaffolding

Daniele Barbaro

php artisan make:auth

Laravel offre un layer base di autenticazione e registrazione semplicemente con un comando

Daniele Barbaro

    /**
     * Set a password hashed
     * @param $password
     */
    public function setPasswordAttribute($password)
    {
        $this->attributes['password'] = Hash::make($password);
    }

    /**
     * Get the route key for the model.
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'username';
    }
    

Setter e getter:

Tweet

Costruzione entità base per il progetto

Creiamo le migrazioni, la Factory e il modello dei tweet

Daniele Barbaro

php artisan make:migration CreateTweetsTable
php artisan make:migration CreateFollowersTable

php artisan make:factory Tweet
php artisan make:model Models/Tweet

Models\Tweet

Daniele Barbaro

    public function tweets()
    {
        return $this->hasMany(Tweet::class);
    }
  
    public function following()
    {
        return $this->belongsToMany(User::class, 'followers', 'follower_id', 'following_id')->withTimestamps();
    }

    public function followers()
    {
        return $this->belongsToMany(User::class, 'followers', 'following_id', 'follower_id')->withTimestamps();
    }
    public function user()
    {
        return $this->belongsTo(User::class);
    }

Models\User

Controllers

Follow, Unfollow, Tweet, User

Daniele Barbaro

php artisan make:controller Tweet/TweetsController -r

php artisan make:controller Users/FollowingController -r

php artisan make:controller Users/UserFollowersController -r

php artisan make:controller Users/UserFollowingController -r

php artisan make:controller Users/UsersController -r

Daniele Barbaro

class FollowingController extends Controller
{
    /**
     * Store a newly created resource in storage.
     *
     * @param  FollowingRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(FollowingRequest $request)
    {
        try {
            $userToFollow = User::whereUsername($request->validated())->firstOrFail();
            $this->me()->follow($userToFollow);
        } catch (\Exception $exception) {
            abort(404, "You can't follow the user");
        }

        return redirect()->route('user-following.index', ['username' => $this->me()->username]);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  User  $username
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $username)
    {
        try {
            $this->me()->unfollow($username);
        } catch (\Exception $exception) {
            abort(404, "You can't unfollow the user");
        }

        return redirect()->route('user-following.index', ['username' => $this->me()->username]);
    }
}

Routes

Daniele Barbaro

Auth::routes();

Route::get('/', 'HomeController@index')->name('home');

Route::group(['middleware' => 'auth'], function () {
    Route::post('/tweets', 'Tweets\TweetsController@store')->name('tweets.store');

    Route::post('/following', 'Users\FollowingController@store')->name('following.store');
    Route::delete('/following/{username}', 'Users\FollowingController@destroy')->name('following.destroy');

    Route::get('/{user}/followers', 'Users\UserFollowersController@index')->name('user-followers.index');
    Route::get('/{user}/following', 'Users\UserFollowingController@index')->name('user-following.index');
});

Route::get('/{user}', 'Users\UsersController@show')->name('users.show');

Daniele Barbaro

UserFollowersController:

class UserFollowersController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param  User  $user
     * @return \Illuminate\Http\Response
     */
    public function index(User $user)
    {
        return view('user-followers.index', [
            'user' => $user,
            'followers' => $user->followers,
        ]);
    }
}

Daniele Barbaro

UserFollowingController:

class UserFollowingController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param  User  $user
     * @return \Illuminate\Http\Response
     */
    public function index(User $user)
    {
        return view('user-following.index', [
            'user' => $user,
            'following' => $user->following,
        ]);
    }
}

Requests

Gestiamo le requests dei controller in maniera efficiente

Decidiamo rules, auth e messages per gestire al meglio e in maniera atomica ogni singola richiesta

Daniele Barbaro

class TweetRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'body' => 'required|max:160',
        ];
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'body.required' => 'Please fill the textarea.',
            'body.max' => 'Max value of tweet is 160.',
        ];
    }
}
class FollowingRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'username' => 'required'
        ];
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'username.required' => 'Dude we need a username.',
        ];
    }
}

Daniele Barbaro

Daniele Barbaro

Ho finito!

Daniele Barbaro

Tests tests and Tests!

Feature and unit test

Daniele Barbaro

php artisan make:test UserTest --unit
php artisan make:test TweetTest --unit

php artisan make:test PostNewTweetTest
php artisan make:test UnfollowUsersTest
php artisan make:test FollowUsersTest

php artisan make:test LoginTest
php artisan make:test RegisterTest
php artisan make:test ResetsPasswordTest

Daniele Barbaro

Daniele Barbaro

Demo Time!

Scrivimi a

barbaro.daniele@gmail.com

antani@iakta.it

  

Daniele Barbaro

Grazie!

https://github.com/danielebarbaro/let-s-tweet-with-laravel

https://slides.com/danielebarbaro/let-s-tweet-with-laravel

Let's tweet with laravel

By Daniele Barbaro

Let's tweet with laravel

  • 234