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-debugbarPacchetti Base sviluppo:
Standards: https://bit.ly/2I2eA6h

Auth Scaffolding

Daniele Barbaro
php artisan make:authLaravel 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/TweetModels\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