Jump to content
Sign in to follow this  
brhue

Classe upload

Recommended Posts

Estou continuando meus estudos sobre oop e SOLID, e queria saber se minhas classes estão violando algum principio do SOLID.

Segue a tentativa:

 

Upload.class.php

<?php 

class Upload {

	private $fileName;
	private $fileSize = 2.0;
	private $fileType;
	private $filePath;
	private $token;

	protected $userFile;

	public function __construct(Token $token) {
		$this->token= $token;
	}

	public function setFileSize($maxSize) {
		$this->fileSize = (float)$maxSize * 1024 * 1024;
	}

	public function setFileType(Array $type) {
		$this->fileType = $type;
	}

	public function setFilePath($path) {
		$this->filePath = $path;
	}

	public function setUserFile($userFile) {
		$this->userFile = $userFile;
	}

	public function getFileName() {
		if (is_null($this->fileName))
			$this->randomName();

		return $this->fileName;
	}

	public function uploadFile() {
		if (!in_array($this->getExtension(), $this->fileType)) 
			throw new RuntimeException("Extensão de arquivo não permitido.");
		else if ($this->fileSize < $_FILES[$this->userFile]['size'])
			throw new RuntimeException("Tamanho de arquivo não permitido.");
		else if (!move_uploaded_file($_FILES[$this->userFile]['tmp_name'], $this->filePath.$this->getFileName()))
			throw new RuntimeException("Falha ao mover arquivo.");	
	}

	private function randomName() {
		$this->fileName = $this->token->generateToken().'.'.$this->getExtension();
	}

	private function getExtension() {
		return pathinfo($_FILES[$this->userFile]['name'], PATHINFO_EXTENSION);
	}
}

?>

Esses sets, seria ideal colocar tudo no construtor?

 

 

Token.php

<?php 

interface Token {

	public function generateToken();
}

?>

Bin2Hex.class.php

class Bin2Hex implements Token {

	public function generateToken() {
		return bin2hex(openssl_random_pseudo_bytes(32));
	}
}

UploadImage.class.php

<?php 

class UploadImage extends Upload {

	private $height;
	private $width;

	public function setImageHeight($height) {
		$this->height = $height;
	}	

	public function setImageWidth($width) {
		$this->width = $width;
	}

	public function uploadFile() {

		list($height, $width) = getimagesize($_FILES[$this->userFile]['tmp_name']);

		if ($this->height < $height) {
			throw new RuntimeException("Altura da imagem não permitida.");
		} else if ($this->width < $width) {
			throw new RuntimeException("Largura da imagem não permitida.");
		}

		parent::uploadFile();
	}
}

->A ideia aqui seria uma classe mais especifica para imagem...

E a maior dúvida é se nessa parte viola o LSP (herança).

 

index.php

$upload = new UploadImage(new Bin2Hex());
$upload->setUserFile('photo');
$upload->setFilePath('uploads/');
$upload->setFileType(array('jpg', 'png'));
$upload->setFileSize(1.0);
$upload->setImageHeight(800);
$upload->setImageWidth(600);

try {
    $upload->uploadFile();
} catch (RuntimeException $e) {
   echo $e->getMessage();
}

Share this post


Link to post
Share on other sites

Uma coisa que eu faria seria separar a sua classe upload.

interface FileInterface{
 ... get e set dos atributos da $_FILE
}
class File implements FileInterface
{
  ... atributos da $_FILE

  .. Metodos get e set

}
class Upload{

   public function uploadFile(FileInterface $file){
      ...
   }


}

Share this post


Link to post
Share on other sites

Entendi.... Agora em relação em passar os set's pelo construtor não é melhor? pois o File::setUserFile($userfile) tem que ser setado primeiro, mas ai eu penso, se eu quiser fazer varios uploads, vou ter que criar varios objetos.

 

Outra dúvida, então a antiga classe UploadImage, eu criaria apenas classe Image que extenderia File? E Qual seria a melhor maneira de fazer as consistencia, seria mesmo na classe Upload utilizando exceptions?

 

Segue a tentativa:

 

FileInterface

interface FileInterface {

	public function setFilePath($path);
	public function setFileSize($size);
	public function setFileType(Array $type);
	public function setRandomName(Token $token);
	public function getUserFile();
	public function getFilePath();
	public function getFileType();
	public function getFileSize();
	public function getFileName();
	public function getExtension();
}

File

class File implements FileInterface {

	private $fileName;
	private $filePath;
	private $fileType;
	private $fileSize = 2;

	protected $userFile;
	
	public function __construct($userFile) {
		$this->userFile = $userFile;
	}

	public function setFilePath($path) {
		$this->filePath = $path;
	}

	public function setFileType(Array $type) {
		$this->fileType = $type;
	}

	public function setFileSize($size) {
		$this->fileSize = (float)$size * 1024 * 1024;
	}

	public function setRandomName(Token $token) {
		$this->fileName = $token->generateToken().'.'.$this->getExtension();
	} 

	public function getUserFile() {
		return $this->userFile;
	}

	public function getFilePath() {
		return $this->filePath;
	}

	public function getFileType() {
		return $this->fileType;
	}

	public function getFileSize() {
		return $this->fileSize;
	}

	public function getFileName() {
		return $this->fileName;
	}

	public function getExtension() {
		return pathinfo($_FILES[$this->userFile]['name'], PATHINFO_EXTENSION);
	}

} 

Upload

class Upload {

	public function uploadFile(FileInterface $file) {

		if (!in_array($file->getExtension(), $file->getFileType())) 
			throw new RuntimeException("Extensão de arquivo não permitido.");
		else if ($file->getFileSize() < $_FILES[$file->getUserFile()]['size'])
			throw new RuntimeException("Tamanho de arquivo não permitido.");
		else if (!move_uploaded_file($_FILES[$file->getUserFile()]['tmp_name'], $file->getFilePath().$file->getFileName()))
			throw new RuntimeException("Falha ao mover arquivo.");
	}
}

testeUpload

<?php 

require_once 'autoload.php';
require_once 'display_error.php';

if (isset($_POST['submit'])) {

    $file = new File('file');
    $file->setFilePath('uploads/');
    $file->setFileType(array('jpg', 'png', 'gif'));
    $file->setFileSize(1.0);
    $file->setRandomName(new Bin2Hex());

    echo 'Teste1: '.$file->getFileName().'<br>';

    $upload = new Upload();
    $upload->uploadFile($file);

    echo 'Teste2: '.$file->getFileName().'<br>';
}

?>

<form action="testeUpload.php" method="post" enctype="multipart/form-data">

<h2>Upload File</h2>

<label for="fileSelect">Filename:</label>

<input type="file" name="file"><br>

<input type="submit" name="submit" value="Upload">

</form>

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • By marcossantana10
      Opa, to precisando muito de uma ajuda: estou tentando fazer o upload de arquivos de um app hibrido (rodando android) para um servidor. O código abaixo é executado sem erro, mas o upload não acontece. Será que alguem tem ideia de onde pode estar o erro?
       
      var images = []; var $imagesDiv; document.addEventListener("deviceready", init, false); function init() { $("#addPicture").on("touchend", selPic); $imagesDiv = $("#images"); $("#uploadPictures").on("touchend", uploadPics); } function selPic() { navigator.camera.getPicture(function(f) { var newHtml = "<img src='"+f+"'>"; $imagesDiv.append(newHtml); images.push(f); if(images.length === 1) { $("#uploadPictures").removeAttr("disabled"); } }, function(e) { alert("Error, check console."); console.dir(e); }, { quality: 50, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, destinationType: Camera.DestinationType.FILE_URI }); } function uploadPics() { alert("Ok, going to upload "+images.length+" images."); var defs = []; var fd = new FormData(); images.forEach(function(i) { alert('processing '+i); var def = $.Deferred(); window.resolveLocalFileSystemURL(i, function(fileEntry) { alert('got a file entry'); fileEntry.file(function(file) { alert('now i have a file ob'); console.dir(file); var reader = new FileReader(); reader.onloadend = function(e) { var imgBlob = new Blob([this.result], { type:file.type}); fd.append('file'+(images.indexOf(i)+1), imgBlob); fd.append('fileName'+(images.indexOf(i)+1), file.name); def.resolve(); }; reader.readAsArrayBuffer(file); }, function(e) { alert('error getting file', e); }); }, function(e) { alert('Error resolving fs url', e); }); defs.push(def.promise()); }); $.when.apply($, defs).then(function() { alert("all things done"); var request = new XMLHttpRequest(); request.open('POST', 'url', true); request.send(fd); }); } Do lado do servidor, onde eu deveria receber a requisição e upar os arquivos, está conforme código abaixo:
      <?php header("Access-Control-Allow-Origin: *"); $imgFileName=date("Y").date("m").date("j")."_".$_POST['index']."_".rand(1000,9999).".jpg"; if(move_uploaded_file($_FILES['file']['tmp_name'], "anuncios/".$imgFileName)){ echo "upload ok"; //or anything you need } ?>  
    • By joelzsbit
      Pessoal implementei o link (https://xkeshi.github.io/image-compressor/) no meu site para fazer a compressão de imagens, porem preciso que essa imagem seja salva no banco.
      Não estou conseguindo pegar essa imagem comprimida e enviar para um arquivo salvar.php que é o responsável para salvar no banco.
      A imagem comprimida fica nesse bloco:
      <div class="w-100 text-center" v-if="outputURL"> <img class="mw-100" :src="outputURL" :alt="output.name"> <div class="mt-2"> <a class="btn btn-sm btn-blocks btn-outline-primary mt-2" :download="output.name" :href="outputURL" title="Download the compressed image">Download</a> </div> </div> Pensei em colocar um botão de salvar ali no lugar do Download, porem como que vou enviar os dados da imagem que estão em javascript para um arquivo salvar.php ?
    • By avelar.avelar
      Turma esta dando erro neste item em negritom, estou tentando , pegar um pdf que esta convertido em base64 e mandando ele gerar o arquivo e gravar numa pasta determinada com um nome, alguem poderias me ajudar? urgente.  Ovbrigado
       
       
      TrablheController.php
       
      public function post(Request $request)
          {
              $rules = [
                  'nome' => 'required|string',
                  'data_nascimento' => 'required|date',
                  'email' => 'required|string',
                  'cpf' => 'required|string',
                  'curriculo' => ['required','mime:/application\/(?:docx||pdf\+xml);base64,.+/'],
              ];
       
              $validator = Validator::make(request()->json()->all(), $rules);
       
              if ($validator->fails()) {
                  return response()->json($validator->errors()->toArray(), 422);
              }
       
              $vagas = Vagas::select('id')->firstOrFail();
       
              $data = $request->json()->all();
       
              $fileB64 = isset($data['curriculo']) ? $data['curriculo'] : false;

              unset($data['curriculo']);
       
              $trabalheconosco = new TrabalheConosco;
       
              foreach (array_keys($rules) as $key) {
                  if (array_key_exists($key, $data)) {
                      $trabalheconosco->{$key} = $data[$key];
                  }
              }
              $trabalheconosco->save();
       
              if ($fileB64) {
                  $trabalheconosco->curriculo = $this->saveFileB64($fileB64, 'images/curriculos', $trabalheconosco->id);
                  $trabalheconosco->save();
              }
       
              $vagas->TrabalheConosco()->save($trabalheconosco);
       
              return response()->json(['data' => $trabalheconosco->toArray()], 201);
          }
       
      Controller.php

          public function saveFileB64($fileB64, $path = '', $id = null): string
          {
              $chunkf = explode(';base64,', $fileB64, 2);
              $chunkf[0] = str_replace('data:', '', $chunkf[0]);
              if (!isset(self::MIMES[$chunkf[0]], $chunkf[1])) {
                  return null;
              }
              $extension = self::MIMES[$chunkf[0]];
              $fileBin = base64_decode($chunkf[1]);
              $time = time();
              $pathName = null;
              do {
                  $pathName = "$path/{$id}_{$time}_"
                      . abs(crc32(uniqid('f', true))) . $extension;
              } while ($this->storage->exists($pathName));
              $this->storage->put(file_put_contents($pathName, $fileBin));
              return $pathName;
          }
       
      ERROR NO INSOMNIA ( 500 INTERNAL SERVER ERROR)
    • By FabianoSouza
      Pessoal, estou garimpando alguns códigos para fazer upload sem necessidade de componente.
      Notei que em todos esses códigos ocorre um problema: truncamento de caracteres acentuados.
       
      Já pesquisei muito em busca da solução.
      Geralmente sugerem para colocar esse código no topo da página
      Response.AddHeader "Content-Type", "text/html;charset=UTF-8" 'caractéres em PT-BR Response.ContentType = "text/html" Response.CharSet = "UTF-8" Já fiz isso...mas não resolveu.
       
      Alguém pode ajudar?
       
      Grato.
    • By GiovannaRamos
      Olá pessoal,  gostaria de adicionar outra função ao meu botão 'Finalizar10()' ,  por enquanto ele faz a exportação dos dados da minha 'tabela' para um Excel e salva na pasta downloads do meu computador,  alguém sabe se teria alguma forma fazer esse arquivo gerado (Excel) ao invés de  fazer download, fazer o upload no caminho do meu servidor?
      function Finalizar10() { $(document).ready(function Finalizar() { $("#btnExport").click(function exportar (e) { e.preventDefault(); var blobData = new Blob(['\ufeff'+tabela], { type: 'application/vnd.ms-excel' }); var url = window.URL.createObjectURL(blobData); var a = document.createElement('a'); a.href = url; a.download = codigo; a.click(); }); }); }  
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.