INSTALL LARAVEL 9 on a shared server bootcamp tutorial install php, composer composer create-project laravel/laravel example-app cd example-app php artisan serve sudo apt-get install php-curl composer update zip files to upload to www root unzip in directory change setting as webroot for public folder which has index.php file DOCUMENT ROOT for xxx.xxxx.ca need to cpanel SUBDOMAIN and change to /public Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 8.1.0". use multiphp manager not php selector checkbox domain, select at top 8.1 touch database/database.sqlite edit .env file, must enable hidden files DB_CONNECTION=sqlite DB_DATABASE=/absolute/path/to/database.sqlite DB_FOREIGN_KEYS=true chirper composer create-project laravel/laravel chirper cd chirper php artisan serve #edit .env #remove everything put DB_CONNECTION=sqlite #laravel breeze for auth composer require laravel/breeze --dev php artisan breeze:install blade #run vite in new terminal tab npm run dev #update database for breeze php artisan migrate #make a model php artisan make:model -mrc Chirp #click register link #edit route routes/web.php use App\Http\Controllers\ChirpController; Route::resource('chirps', ChirpController::class) ->only(['index', 'store']) ->middleware(['auth', 'verified']); #The auth middleware ensures that only logged-in users can access the route. #The verified middleware will be used if you decide to enable email verification. #edit app/Http/Controllers/ChirpController.php #REMOVE return 'Hello, World!'; in public function index() return view('chirps.index'); #create new folder and file #resources/views/chirps/index.blade.php #control c vite server , recompile css, http://localhost:8000/chirps npm run dev #edit resources/views/layouts/navigation.blade.php #add at {{ __('Chirps') }} #also {{ __('Chirps') }} #app/Http/Controllers/ChirpController.php edit to create and store #edit public function store(), make sure not to play around with comments since attributes can change function of software $validated = $request->validate([ 'message' => 'required|string|max:255', ]); $request->user()->chirps()->create($validated); return redirect(route('chirps.index')); #user has many chirps, edit user model #app/Models/User.php #add function chirps public function chirps() { return $this->hasMany(Chirp::class); } #app/Models/Chirp.php change mass assignment for protected $fillable = [ 'message', ]; #edit migration file databases/migration/_create_chirps_table.php #2022_10_29_131754_create_chirps_table.php #edit up function, edit create $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('message'); #update migration php artisan migrate #warning you may rebuild your database from scratch using the php artisan migrate:fresh #testing out database php artisan tinker Chirp::all(); /** >>> Chirp::all(); [!] Aliasing 'Chirp' to 'App\Models\Chirp' for this Tinker session. => Illuminate\Database\Eloquent\Collection {#4635 all: [ App\Models\Chirp {#4637 id: 1, user_id: 1, message: "sumo wrestler", created_at: "2022-10-29 13:47:57", updated_at: "2022-10-29 13:47:57", }, App\Models\Chirp {#4638 id: 2, user_id: 1, message: "fffffffffffffffffffffffffj6poj6k", created_at: "2022-10-29 13:48:57", updated_at: "2022-10-29 13:48:57", }, ], } **/ exit #app/Http/Controllers/ChirpController.php edit #edit function index see all user chirps return view('chirps.index', [ 'chirps' => Chirp::with('user')->latest()->get(), ]); #need pagination https://laravel.com/docs/pagination for production #edit app/Models/Chirp.php to create user relationship public function user() { return $this->belongsTo(User::class); } #edit resources/views/chirps/index.blade.php #paste after form
@foreach ($chirps as $chirp)
{{ $chirp->user->name }} {{ $chirp->created_at->format('j M Y, g:i a') }}

{{ $chirp->message }}

@endforeach
#edit route for editing chirps routes/web.php #replace resource chipr index store with 2 more options ->only(['index', 'store', 'edit', 'update']) #edit resources/views/chirps/index.blade.php #drop down for author, and compare edit with update @unless ($chirp->created_at->eq($chirp->updated_at)) · {{ __('edited') }} @endunless @if ($chirp->user->is(auth()->user())) {{ __('Edit') }} @endif #resources/views/chirps/edit.blade.php create
@csrf @method('patch')
{{ __('Save') }} {{ __('Cancel') }}
#app/Http/Controllers/ChirpController.php user has to authorize function edit $this->authorize('update', $chirp); return view('chirps.edit', [ 'chirp' => $chirp, ]); #do same update function $this->authorize('update', $chirp); $validated = $request->validate([ 'message' => 'required|string|max:255', ]); $chirp->update($validated); return redirect(route('chirps.index')); #remove duplicate validation test https://laravel.com/docs/validation#form-request-validation #authorization php artisan make:policy ChirpPolicy --model=Chirp #app/Policies/ChirpPolicy. #This will create a policy class at app/Policies/ChirpPolicy.php which we can update to specify that only the author is authorized to update a Chirp: #allow deleting chirp #routes/web.php ->only(['index', 'store', 'edit', 'update', 'destroy']) #You may view all of the routes for your application by running the php artisan route:list #app/Http/Controllers/ChirpController.php public function destroy(Chirp $chirp) { // $this->authorize('delete', $chirp); $chirp->delete(); return redirect(route('chirps.index')); #app/Policies/ChirpPolicy.php reuse update for delete public function delete(User $user, Chirp $chirp) { return $this->update($user, $chirp); #resources/views/chirps/index.blade.php add delete button to .. menu
@csrf @method('delete') {{ __('Delete') }}
#creating notifications php artisan make:notification NewChirp #app/Notifications/NewChirp.php use App\Models\Chirp; use Illuminate\Support\Str; public function __construct(public Chirp $chirp) ->subject("New Chirp from {$this->chirp->user->name}") ->greeting("New Chirp from {$this->chirp->user->name}") ->line(Str::limit($this->chirp->message, 50)) ->action('Go to Chirper', url('/')) #creating event php artisan make:event ChirpCreated #Events are a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other. app/Events/ChirpCreated.php #app/Models/Chirp.php use App\Events\ChirpCreated; protected $dispatchesEvents = [ 'created' => ChirpCreated::class, ]; #create listener php artisan make:listener SendChirpCreatedNotifications --event=ChirpCreated #app/Listeners/SendChirpCreatedNotifications.php use App\Models\User; use App\Notifications\NewChirp; class SendChirpCreatedNotifications implements ShouldQueue foreach (User::whereNot('id', $event->chirp->user_id)->cursor() as $user) { $user->notify(new NewChirp($event->chirp)); } ##Registering the event listener #App\Providers\EventServiceProvider.php use App\Events\ChirpCreated; use App\Listeners\SendChirpCreatedNotifications; ChirpCreated::class => [ SendChirpCreatedNotifications::class, ], #you will need an SMTP server, or a transactional email provider, such as Mailgun, Postmark, or Amazon SES #https://laravel.com/docs/mail#introduction #https://laravel.com/docs/mail#configuration #DEPLOY zip all files inside folder extract change root for subdomain to public chnge php 8.1 multiphpmanager #edit .env variable APP_DEBUG=false APP_URL=http://xxx.xxx.ca