Upload – download files

per salvare un file inviato tramite form:

$req->validate([
'file' => 'required|mimes:csv,txt,xlx,xls,pdf,jpg,jpeg|max:2048'
]);
$filePath = $req->file('file')->storeAs('uploads', $fileName, 'public');

il file viene caricato nella cartella:

\storage\app\public\uploads

come definito nel file di configurazione:

\config\filesystems.php

per rendere disponibile il file per il download:

php artisan storage:link

crea un link da public/storage a storage/app/public

come configurato nella sezione links di filesystems.php

il link al file caricato si può generare con:

echo asset('storage/file.txt');

o generare il file come risposta nel controller:

use Illuminate\Support\Facades\Storage;
return Storage::download('file.jpg', $name, $headers);

in questo caso specificando il “nome file” che lo maschera, o forzando diversi headers

Laravel Queue

php artisan queue:table

crea la migration per creare la tabella jobs.

Creare il job worker:

php artisan make:job ProcessTPlinkSendSms

crea il job dentro app/Jobs/ProcessTPlinkSendSms.php

e lo fai partire con:

php artisan queue:work

Per non dover far partire il worker a mano e tenerlo aperto si può installare supervisor:

sudo apt-get install supervisor

e creiamo la configurazione:

cd /etc/supervisor/conf.d

laravel-queue-emails.conf

e ci incolliamo:

[program:yacatechEmailsQueue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/sites/yacatech/artisan queue:work --queue=emails database --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/sites/yacatech/storage/logs/emails-worker.log
stopwaitsecs=30

E far partire i processi con:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
sudo supervirorctl status

Molti a molti

Per creare un legame molti a molti serve innanzitutto una tabella che leghi i due modelli, quindi vai di

MIGRATION

Schema::create('destination_user', function (Blueprint $table) {
        $table->id();
        $table->foreignId('user_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
        $table->foreignId('destination_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
        $table->timestamps();                                    
        $table->softDeletes();              
    });

quindi aggiorniamo i:

MODEL

class User extends Authenticatable
{
    public function destinations()
    {
        return $this->belongsToMany(Destination::class);
    }
}
class Destination extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class);
    }
}

e ora modifichiamo i blade:

CREATE BLADE

<div class="row mb-3" style="display: none" id="destinations_select">
  <label for="destinations_id" class="col-md-4 col-form-label text-md-right">{{ __('Destinations access') }}</label>

<div class="col-md-6">                       
 <select name="destinations_id" id="destinations_id" multiple class="form-select" >    
   @foreach($array['destinations'] as $destination)                                    
     <option value="{{$destination->id}}"  @if ($array['filter']->input('destinations_id') == $destination->id) selected @endif >
      {{ __($destination->name) }}</option>                                    
   @endforeach
 </select> 
</div>
</div> 

EDIT BLADE

<select name="destinations_id[]" id="destinations_id" multiple class="form-select" >    
 @foreach($array['destinations'] as $destination) 
  <option value="{{$destination->id}}" 
     @foreach ($array['user']->destinations->all() as $us_destination)  
        @if ($destination->id == $us_destination->id) selected @endif 
     @endforeach 
  >{{__($destination->name)}}</option> 
 @endforeach 
</select>

STORE CONTROLLER

$user = new User($input);
$user->push();    

UPDATE CONTROLLER

$user->destinations()->sync($input['destinations_id']);

Inviare mail con laravel

creare il mailable in app/Mail con:

php artisan make:mail preRegistration

in content cambiamo la view con una creata da noi:

return new Content(
view: 'preregistrations.mail',
);

nel costruttore definiamo le variabili da “passare” al blade per personalizzare la mail:

public function __construct(
        public \App\Models\Preregistration $preregistration,            
)
{}

aggiungere la mail al controller:

use App\Mail\preRegistration;
use Illuminate\Support\Facades\Mail;

e per inviare:

Mail::to($preregistration->email)->queue(
    (new \App\Mail\preRegistration($preregistration))->afterCommit()
   );

AfterCommit serve per attendere che il record sia salvato/modificato prima di inviare la mail, in modo da inviarla con i dati aggiornati.

Usare queue per accordare l’invio, o send per inviare instantaneamente ( potrebbe rallentare il caricamento della pagina )

Select multiplo

Serve un select con più opzioni selezionabili?

Lato Blade:

<select id="roles" name="role_id[]" multiple class="form-select">
  @foreach($array['roles'] as $role)
  <option value="{{$role->id}}">{{$role->name}}</option>
  @endforeach
</select>

e nel controller:

$user->roles()->sync($request['role_id']);

Model

Per creare un model

php artisan make:model 'Object' -mcrf

crea model – factory – migration – controller

in routes/web.php agiungere la rotta:

Route::resource('Object', App\Http\Controllers\ObjectController::class);

Localization (traduzioni)

php artisan make:middleware Localization

In resources/lang creare it.json e en.json

In config/app.php cambiare en con it

Aggiungere:

        'available_locales' => [ 
        'English' => 'en',
        'Italiano' => 'it'
    ],

creare la rotta per lo switch di lingua

ogni voce deve avere il file corrispondente in resources\lang

in app\http\middleware\localisation.php aggiungere in handle:

    if (Session::has('locale')) {
        App::setLocale(Session::get('locale'));   
        app()->setLocale(Session::get('locale'));   
    }

In app/http/kernel.php

Aggiungere:

\App\Http\Middleware\Localization::class

Nella sezione

  protected $middlewareGroups = [
        'web' => [
        .....
        \App\Http\Middleware\Localization::class,
        ],

In app\Http\Middleware\Localization.php aggiungere:

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;

basi di github

CREAZIONE DEL REPOSITORY

_ GitHub; creare l’utente, nel mio caso: IvanDurighettoCamon

_ GitHub: creare il repository: prj_git_test, l’indirizzo quindi sarà:

HTTPS: https://github.com/IvanDurighettoCamon/prj_git_test.git
SSH: git@github.com:IvanDurighettoCamon/prj_git_test.git

_ NetBeans: creare il progetto

_ NetBeans: inizializzare il repository git (da terminale):
git remote add github https://github.com/IvanDurighettoCamon/prj_git_test.git

_ caricare tutto:

git add *

git commit -m “descrizione”

git push github

il branch master viene sincronizzato con github e su github trovi i file sincronizzati

MODIFICA IN REMOTO

_ apro il file su github web e faccio una modifica
_ faccio un commit da github web, su stesso branch
git pull github master, e ti trovi le modifiche fatte

MODIFICA SIA LOCALE CHE REMOTA

versione 2 sia in locale che in remoto

git pull github master

mi trovo in locale entrambe le modifiche, con l’indicazione di sistemare i conflitti
sistemo i conflitti

git add *

git commit -m “merge fatto”

git push github master

CREAZIONE DI UN BRANCH

da github modificato index e creato un branch test_branch_001

da github fatto il pull request

da github fatto il merge

da github eliminato il branch

Creare un server Git

Per il backup e il versionamento dei nostri progetti, o per un deploy rapido:

info prese da questa guida:
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-git-server-on-a-vps

Locale: creare una chiave ssh che ci permetterà di accedere al server senza password:

ssh-keygen

Server: creare la cartella dove copiarle:

mkdir ~/.ssh && touch ~/.ssh/authorized_keys

Locale->Server: copiamo in authorized_keys il contenuto di id_rsa.pub creato con ssh-keygen

cat .ssh/id_rsa.pub | ssh {{utente_remoto}}@{{server}} "cat >> ~/.ssh/authorized_keys"

o lo carichi con WinSCP e lo rinomini authorized_keys, se dovessi un giorno aggiungere altre chiavi, vanno accodate nel file authorized_keys

Server: nella home crei il repository con:

git init --bare {{progetto}}.git

Locale: aggiungi il nuovo sito remoto al repository locale già creato:

git remote add {{nome_remoto}} {{utente_remoto}}@{{server}}:{{progetto}}.git

Locale: carica con push:

git push {{nome_remoto}}

Laravel System setup

Composer

Installare composer, seguendo le istruzioni qui: https://getcomposer.org/download/

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

scarica il file composer-setup.php

php composer-setup.php 

esegue l’installazione, creando il file composer.phar

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

rende disponibile composer in tutto il sistema

sudo apt install composer

Database

impostare un utente e database per l’applicazione

sudo mysql -u root 
mysql> CREATE USER 'laraTest_user'@'%' IDENTIFIED WITH mysql_native_password BY 'laraTest_pass'; 
mysql> CREATE DATABASE laraTest;
mysql> GRANT ALL PRIVILEGES ON laraTest.* TO 'laraTest_user'@'%';
mysql> quit;

Apache

dentro /etc/apache2/sites-available creare il file di configurazione e linkarlo poi in sites-enabled prima di riavviare il servizio. All’interno la configurazione dovrebbe essere circa:

ServerName www.test.progetto.local
Options Indexes FollowSymLinks
DocumentRoot /var/www/html/progetto/public/
<Directory "/var/www/html/progetto/public/">
    Order Allow,Deny
    Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error_progetto.log
CustomLog ${APACHE_LOG_DIR}/access_progetto.log combined

In /etc/apache2/mods-enabled: sudo ln -s ../mods-available/rewrite.load

_ impostare i diritti su alcune cartelle del progetto:

chmod 777 storage/logs
chmod 777 storage/framework/sessions
chmod 777 storage/framework/views
chmod 777 bootstrap/cache

il resto della cartella di progetto dovrebbe essere:
_ del gruppo www-data
_ dell’utente “developer”
_ chmod 775

PHP

nel file php.ini de-commentare:

extension=curl
extension=fileinfo
extension=imap
extension=openssl
extension=pdo_mysql

Other requirements

sudo apt install nodejs
sudo apt install npm