partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

UploadedFileService.php (6263B)


      1 <?php
      2 
      3 namespace PartKeepr\UploadedFileBundle\Services;
      4 
      5 use Gaufrette\Exception\FileNotFound;
      6 use Gaufrette\Filesystem;
      7 use PartKeepr\UploadedFileBundle\Entity\UploadedFile;
      8 use PartKeepr\UploadedFileBundle\Exceptions\DiskSpaceExhaustedException;
      9 use Symfony\Component\DependencyInjection\Container;
     10 use Symfony\Component\DependencyInjection\ContainerAware;
     11 use Symfony\Component\HttpFoundation\File\File;
     12 
     13 class UploadedFileService extends ContainerAware
     14 {
     15     /**
     16      * @var Container
     17      */
     18     protected $container;
     19 
     20     public function __construct(Container $container)
     21     {
     22         $this->setContainer($container);
     23     }
     24 
     25     /**
     26      * Replaces the current file with a new file.
     27      *
     28      * @param UploadedFile $file           The target file
     29      * @param File         $filesystemFile The source file
     30      */
     31     public function replace(UploadedFile $file, File $filesystemFile)
     32     {
     33         $this->replaceFromFilesystem($file, $filesystemFile);
     34     }
     35 
     36     /**
     37      * Replaces the current file with a new file.
     38      *
     39      * @param UploadedFile $file           The target file
     40      * @param File         $filesystemFile The source file
     41      */
     42     public function replaceFromFilesystem(UploadedFile $file, File $filesystemFile)
     43     {
     44         $file->setOriginalFilename($filesystemFile->getBasename());
     45         $file->setExtension($filesystemFile->getExtension());
     46         $file->setMimeType($filesystemFile->getMimeType());
     47         $file->setSize($filesystemFile->getSize());
     48 
     49         $storage = $this->getStorage($file);
     50 
     51         if ($filesystemFile->getSize() > $this->container->get('partkeepr_systemservice')->getFreeDiskSpace()) {
     52             throw new DiskSpaceExhaustedException();
     53         }
     54 
     55         $storage->write($file->getFullFilename(), file_get_contents($filesystemFile->getPathname()), true);
     56     }
     57 
     58     public function replaceFromData(UploadedFile $file, $data, $filename)
     59     {
     60         $tmpdir = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir();
     61         $tempName = tempnam($tmpdir, 'PARTKEEPR');
     62 
     63         file_put_contents($tempName, $data);
     64 
     65         $this->replaceFromFilesystem($file, new File($tempName));
     66         $file->setOriginalFilename($filename);
     67 
     68         unlink($tempName);
     69     }
     70 
     71     public function delete(UploadedFile $file)
     72     {
     73         $storage = $this->getStorage($file);
     74 
     75         try {
     76             $storage->delete($file->getFullFilename());
     77         } catch (FileNotFound $e) {
     78             $this->container->get('logger')->alert(
     79                 sprintf('Unable to delete file %s', $file->getFullFilename()),
     80                 [$e, $file]
     81             );
     82         }
     83     }
     84 
     85     /**
     86      * Replaces an existing uploaded file with another uploaded file.
     87      *
     88      * @param UploadedFile $target The target file
     89      * @param UploadedFile $source The source file
     90      */
     91     public function replaceFromUploadedFile(UploadedFile $target, UploadedFile $source)
     92     {
     93         $storage = $this->getStorage($source);
     94         $this->replaceFromData($target, $storage->read($source->getFullFilename()), $source->getFullFilename());
     95         $target->setOriginalFilename($source->getOriginalFilename());
     96     }
     97 
     98     /**
     99      * Replaces the file from an URL. Does some tricks to avoid 403 forbidden on some sites, like setting a proper
    100      * browser identification.
    101      *
    102      * @param UploadedFile $file The target file
    103      * @param string       $url  The URL to replace from
    104      *
    105      * @throws \Exception An exception if the curl operation failed
    106      *
    107      * @todo Parse the filename from the return headers
    108      */
    109     public function replaceFromURL(UploadedFile $file, $url)
    110     {
    111         /* Some sites don't like automated requests. But the internet is meant to be open for anybody,
    112          * even for scripts. So we are evil and fake the headers.
    113          *
    114          * Credit goes to Ryan Rampersad from whom I copied most code.
    115          * http://blog.ryanrampersad.com/2008/11/07/get-remote-html-with-curl-and-php/
    116          */
    117         $curl = curl_init();
    118 
    119         $header[0] = 'Accept: text/xml,application/xml,application/xhtml+xml,';
    120         $header[0] .= 'text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
    121         $header[] = 'Cache-Control: max-age=0';
    122         $header[] = 'Connection: keep-alive';
    123         $header[] = 'Keep-Alive: 300';
    124         $header[] = 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7';
    125         $header[] = 'Accept-Language: en-us,en;q=0.5';
    126         $header[] = 'Pragma: ';
    127 
    128         $browser = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 ';
    129         $browser .= 'Ubuntu/8.04 (hardy) Firefox/3.0.3';
    130 
    131         curl_setopt($curl, CURLOPT_URL, $url);
    132         curl_setopt($curl, CURLOPT_USERAGENT, $browser);
    133         curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    134         curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    135         curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    136         curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    137         curl_setopt($curl, CURLOPT_MAXREDIRS, 7);
    138         curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    139 
    140         $data = curl_exec($curl);
    141 
    142         if ($data === false) {
    143             $curlError = curl_error($curl);
    144             // Strip ANY tags from the error message. curl tends to spit out <url> is not valid, which then
    145             // confuses the error message parser on the client side.
    146             $curlError = str_replace(['>', '<'], '', $curlError);
    147 
    148             throw new \Exception('replaceFromURL error: '.$curlError);
    149         }
    150 
    151         curl_close($curl);
    152 
    153         $this->replaceFromData($file, $data, basename($url));
    154     }
    155 
    156     /**
    157      * Returns the storage directory for a given UploadedFile.
    158      *
    159      * @param UploadedFile $file The file to get the storage directory for
    160      *
    161      * @return string The storage directory for the type of the given UploadedFile
    162      */
    163     public function getStorageDirectory(UploadedFile $file)
    164     {
    165         return $this->container->getParameter('partkeepr.directories.'.$file->getType());
    166     }
    167 
    168     /**
    169      * @param UploadedFile $file
    170      *
    171      * @return Filesystem
    172      */
    173     public function getStorage(UploadedFile $file)
    174     {
    175         $type = strtolower($file->getType());
    176 
    177         return $this->container->get('filesystem_'.$type);
    178     }
    179 }