analyze($filepath); if (array_key_exists('error', $results)) { return null; } if (array_key_exists('playtime_string', $results)) { return \strval($results['playtime_string']); } return null; } /** * Get ID3 video dimensions * * @param string $filepath * @return array|null Containing 'width' and 'height' */ public static function getId3VideoDimensions(string $filepath): ?array { $getID3 = new getID3(); $results = $getID3->analyze($filepath); if (array_key_exists('error', $results)) { return null; } if (isset($results['video']['resolution_x']) and isset($results['video']['resolution_y'])) { return [ 'width' => \intval($results['video']['resolution_x']), 'height' => \intval($results['video']['resolution_y']) ]; } return null; } /** * resolution in pixels per centimeter * * @param string $filepath * @return array|null Containing 'resolutionX', 'resolutionY', 'width' and 'height' */ public static function getImageDimensions(string $filepath): ?array { $ext = \pathinfo($filepath, \PATHINFO_EXTENSION); try { $im = new Imagick($filepath); if ( in_array($ext, [ MediaExtension::pdf->value, MediaExtension::ai->value, MediaExtension::psd->value, MediaExtension::gif->value ]) ) { $im->setIteratorIndex(0); } $r = $im->getImageResolution(); $u = $im->getImageUnits(); // Force image resolution to pixel per centimeters. if ($u == Imagick::RESOLUTION_PIXELSPERINCH) { $r['x'] = (int)round($r['x'] / 2.54); $r['y'] = (int)round($r['y'] / 2.54); $im->setImageUnits(Imagick::RESOLUTION_PIXELSPERCENTIMETER); $im->setImageResolution($r['x'], $r['y']); // Note that the number type is double again. $r = $im->getImageResolution(); } $imageprops = $im->getImageGeometry(); $im->destroy(); return [ 'resolutionX' => \intval($r['x']), 'resolutionY' => \intval($r['y']), 'width' => \intval($imageprops['width']), 'height' => \intval($imageprops['height']) ]; } catch (ImagickException $e) { report($e); } //end try return null; } /** * Sanitize File name for uploaded files * * @param string $filename The original uploaded client file name. * @param boolean $beautify Beautify the filename. * @return string The sanitized file name. */ public static function sanitizeFileName(string $filename, bool $beautify = true): string { // * Sanitize filename // phpcs:disable Generic.Files.LineLength.TooLong $filename = preg_replace( '~ [<>:"/\\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words [\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx [\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN [#\[\]@!$&\'()+,;=]| # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2 [{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt ~x', '-', $filename ); // phpcs:enable // * Avoids '.' '..' or '.hiddenFiles' . $filename = Str::of($filename)->ltrim('.-'); // * Optional beautification if ($beautify) { $filename = static::beautifyFilename($filename); } // * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086 /** @var string */ $extension = pathinfo($filename, \PATHINFO_EXTENSION); /** @var string */ $filename = pathinfo($filename, \PATHINFO_FILENAME); $encoding = mb_detect_encoding($filename); $encoding = $encoding ? $encoding : null; return \mb_strcut( $filename, 0, 255 - (!empty($extension) ? strlen($extension) + 1 : 0), $encoding ) . (!empty($extension) ? ".$extension" : ''); } /** * Beautify a filename * * @param string $filename * @return string */ private static function beautifyFilename(string $filename): string { // Reduce consecutive characters. $filename = preg_replace([ // * "file name.zip" becomes 'file-name.zip' '/ +/', // * "file___name.zip" becomes 'file-name.zip' '/_+/', // * "file---name.zip" becomes 'file-name.zip' '/-+/' ], '-', $filename); $filename = preg_replace([ // * "file--.--.-.--name.zip" becomes "file.name.zip" '/-*\.-*/', // * "file...name..zip" becomes "file.name.zip" '/\.{2,}/' ], '.', $filename); // Lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 . $filename = mb_strtolower($filename, mb_detect_encoding($filename)); // * ".file-name.-" becomes "file-name" $filename = trim($filename, '.-'); return $filename; } /** * Convert file size to human readable string * * @param mixed $octet * @param integer $precision * @return string */ public static function formatBytes(mixed $octet, int $precision = 2): string { // * Array contenant les differents unités $unite = ['octet', 'Kio', 'Mio', 'Gio']; $octet = \floatval($octet); $Kio = 1024; $Mio = 1024 * $Kio; $Gio = 1024 * $Mio; switch (true) { // * octet case $octet < $Kio: return $octet . $unite[0]; // * kio case $octet < $Mio: return $octet . $unite[1]; // * Mio case $octet < $Gio: return \round($octet / $Mio, $precision) . $unite[2]; // * Gio default: // * Gio return \round($octet / $Gio, $precision) . $unite[3]; } } /** * * Register CSP report URI * * Put this function inside RouteServiceProvider, * and call it in RouteServiceProvider::boot * * ! Use this in conjonction with kwaadpepper/exception-handler * * @return void */ public static function cspReportRoute() { // * CSP REPORT URI, Please add /csp-report to VerifyCsrfToken $except middleware \Illuminate\Support\Facades\Route::post('/csp-report', function () { $isCspRequest = request()->header('Content-Type') === 'application/csp-report'; if (!$isCspRequest or !request()->json('csp-report') or !is_array(request()->json('csp-report'))) { abort(401); } // * Flatten if needed $cspReport = collect(request()->json('csp-report')) ->flatMap(function ($v, $k) { return [$k => is_array($v) ? collect($v)->flatten()->implode(', ') : $v]; })->all(); // * Filter array keys $cspReport = collect(array_intersect_key($cspReport, [ 'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '', 'referrer' => '', 'violated-directive' => '' ])); report(new \Illuminate\Http\Client\HttpClientException(sprintf( "CSP REPORT for %s : \n %s", $cspReport->get('document-uri'), $cspReport->implode("\n") ))); })->middleware('throttle:5,2') ->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class) ->name('cspReportUri'); } }