Hej, proszę o ocenę kodu, dopiero uczę się php i nie wiem czy dobrze to zaprojektowałem. Formularzem przesyłam plik który odbiera kontroler, który korzysta z klasy odpowiadającej za obsługę żądania, następnie ta klasa korzysta z serwisu obsługującego dodawanie zipów, rozpakowywanie, itp..
kontroler:
<?php
use App\Validations\ZipFileValidator;
use App\Models\File\ZipFile;
use Symfony\Component\HttpFoundation\Request;
use App\Requests\AddAppRequest;
class testController extends Controller
{
private $request;
public $errors;
/**
* STRONA
*/
public function indexAction()
{
$this->request = Request::createFromGlobals();
#Request - create new app
if ($this->request->get('action') == 'app_add') {
//create data file from input
$zipFileInputName = 'fileToUpload';
//try add file
$AddAppRequest = new AddAppRequest($zipFileInputName);
$this->errors = $AddAppRequest->getErrors();
$this->feedback = $AddAppRequest->getFeedback();
}
//widok
$this->render('test/index.twig', ['errors' => $this->errors, 'feedback' => $this->feedback]);
}
}
Klasa obsługująca formularz przesyłająca plik zip:
<?php
namespace App\Requests;
use Symfony\Component\HttpFoundation\Request;
use Entity\Apps;
use App\Models\App\App;
use App\Validations\AppValidator;
use App\Validations\ImageValidator;
use App\Services\Files\IconServices;
use App\Services\Files\ZipFileServices;
use App\Validations\ZipFileValidator;
use App\Models\File\ZipFile;
class AddAppRequest
{
private $appsEntity;
public $errors = [];
public $feedback = [];
public $zipFileServices;
public function __construct($zipFileInputName)
{
$this->request = Request::createFromGlobals();
$this->appsEntity = new Apps();
//
$this->zipFileServices = new ZipFileServices($zipFileInputName);
$this->zipFileServices->validZipFile();
$this->zipFileServices->moveFile();
$this->zipFileServices->unzipFile();
$this->mergeErrors();
$this->mergeFeedbacks();
}
public function getErrors()
{
return $this->errors;
}
public function getFeedback()
{
return $this->feedback;
}
private function mergeErrors()
{
$this->errors = array_merge($this->errors, $this->zipFileServices->getErrors());
}
private function mergeFeedbacks()
{
$this->feedback = array_merge($this->feedback, $this->zipFileServices->getFeedback());
}
}
Serwis Zip:
<?php
namespace App\Services\Files;
use App\Validations\ZipFileValidator;
use Symfony\Component\HttpFoundation\Request;
use ZipArchive;
use App\Models\File\ZipFile;
class ZipFileServices
{
private $request;
private $zipFileName;
private $zipArchive;
public $errors = [];
public $feedback = [];
public function __construct($zipFileInputName)
{
$this->request = Request::createFromGlobals();
$this->zipArchive = new ZipArchive;
$this->zipFile = $this->request->files->get($zipFileInputName);
$this->zipFileName = $this->request->files->get($zipFileInputName)->getClientOriginalName();
$this->zipFileInputName = $zipFileInputName;
}
public function moveFile($dir = ROOT_ZIP_FOLDER)
{
if (empty($this->errors)) {
//OK
if ($this->request->files->get('fileToUpload')->move($dir, $this->zipFileName)) {
$this->feedback[] = 'Plik został przesłany do :' . $dir;
return true;
} else {
$this->errors[] = 'Błąd podczas przenoszenia!';
}
} else {
$this->errors[] = 'Plik nie został przesłany, ponieważ nie spełnił warunków!';
}
}
public function validZipFile()
{
$zipFileValidation = new ZipFileValidator(new ZipFile($this->zipFileInputName, $this->zipFile));
$this->errors = $zipFileValidation->getErrors();
}
public function unzipFile($dir = ROOT_ZIP_FOLDER)
{
$this->zipArchive->open($dir . $this->zipFileName);
$this->zipArchive->extractTo($dir . '/nazwa_pliku/');
$this->zipArchive->close();
$this->feedback[] = 'Plik został rozpakowany w katalogu ' . $dir . $this->zipFileName;
}
public function getErrors()
{
return $this->errors;
}
public function getFeedback()
{
return $this->feedback;
}
}
Walidacja pliku:
<?php
namespace App\Validations;
use App\Models\File\ZipFile;
class ZipFileValidator
{
//Modificators
private $fileMaxSize = 23000000;//23MB
private $maxCountChar = 30;
//Zip File
private $zipFile;
private $fileName;
private $fileSize;
//Errors after validation
private $errors = [];
public function __construct(ZipFile $zipFile)
{
$this->zipFile = $zipFile;
$this->fileName = $this->zipFile->getFileName();
$this->fileSize = $this->zipFile->getFileSize();
//sprawdź walidacje
$this->validFile();
}
public function validFile()
{
if (file_exists(ROOT_ZIP_FOLDER . $this->fileName)) {
$this->errors[] = "Plik o nazwie ". $this->fileName . ' już istnieje w ' . ROOT_ZIP_FOLDER;
}
if (mb_strlen($this->fileName) >= $this->maxCountChar) {
$this->errors[] = "Nazwa przesyłanego pliku jest zbyt długa. Plik ma w swojej nazwię za dużo znaków";
}
if (strpos($this->fileName, '.zip') == false) {
$this->errors[] = "To nie jest plik *.zip";
}
if ($this->fileName == null) {
$this->errors[] = "Nie przesłałeś pliku!";
}
if ($this->fileSize > $this->fileMaxSize) {
$this->errors[] = "Plik jest za duży ma: " . $this->fileSize . "kb";
}
}
public function getErrors()
{
return $this->errors;
}
}
model pliku zip:
<?php
namespace App\Models\File;
use Symfony\Component\HttpFoundation\Request;
class ZipFile
{
private $request;
private $fileName;
private $fileSize;
public function __construct($inputName, $requestFile)
{
$this->request = Request::createFromGlobals();
$this->inputFile = $requestFile;
$this->fileName = $this->request->files->get("$inputName")->getClientOriginalName();
$this->fileSize = $this->request->files->get("$inputName")->getClientSize();
}
public function getFileName()
{
return $this->fileName;
}
public function getFileSize()
{
return $this->fileSize;
}
}
ogólnie przepływ danych wygląda tak:
Kontroler <-> Obsługa zapytania <-> (Serwis zip -> walidacja) <-> model.
ps. napisałem własne mvc w którym korzystam z Twiga do wyświetlania widoku..
Czy to wogóle ma sens?