private static function makeASafeCopy(array $files) { if (true === self::$dontPullOutMyHair) { foreach ($files as $file) { if (is_file($file)) { $target = self::$safePath . "/" . $file; if (true === FileSystemTool::mkdir(dirname($target), 0777, true)) { copy($file, $target); } } else { trigger_error("not a file: {$file}", E_USER_WARNING); } } } }
/** * * Works like php's native touch function, except that intermediate dirs are created if necessary, * and that the method throws an Exception if something goes wrong. * * bool touch ( string $filename [, int $time = time() [, int $atime ]] ) * */ public static function touchDone($fileName) { if (is_string($fileName)) { $dir = dirname($fileName); if (false === FileSystemTool::mkdir($dir, 0777, true)) { throw new \Exception("Could not create dir: {$dir}"); } $n = func_num_args(); if (1 === $n) { $ret = touch($fileName); } elseif (2 === $n) { $ret = touch($fileName, func_get_arg(1)); } elseif (3 === $n) { $ret = touch($fileName, func_get_arg(1), func_get_arg(2)); } if (false === $ret) { throw new \Exception("Could not touch the file {$fileName}"); } } else { throw new \InvalidArgumentException(sprintf("fileName argument must be of type string, %s given", gettype($fileName))); } }
protected function prepare(&$path, &$isChunk) { $this->isLastChunk = false; if (false === parent::prepare($path, $isChunk)) { return false; } if (null === $this->timServer) { throw new \RuntimeException("Invalid object: timServer not set"); } // Make sure file is not cached (as it happens for example on iOS devices) header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); @set_time_limit(5 * 60); // Settings $targetDir = realpath($this->tmpDir); $cleanupTargetDir = true; // Remove old files $maxFileAge = 5 * 3600; // Temp file age in seconds // Create target dir if (false === FileSystemTool::mkdir($targetDir, 0777, true)) { $this->timServer->error("The target dir couldn't be created"); return false; } // Create destination dir if (false === FileSystemTool::mkdir($this->dstDir, 0777, true)) { $this->timServer->error("The destination dir couldn't be created"); return false; } // Get a file name if (isset($_REQUEST["name"])) { $fileName = $_REQUEST["name"]; } elseif (isset($_FILES["file"]["name"])) { $fileName = $_FILES["file"]["name"]; } else { $fileName = uniqid($this->randomSeed); } $fileName = preg_replace('!\\.+!', '.', $fileName); // prevent parent access $this->fileName = $fileName; $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; // Chunking might be enabled $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; // Remove old temp files if ($cleanupTargetDir) { if (!($dir = opendir($targetDir))) { $this->timServer->error("Failed to open temp directory."); return false; } while (($file = readdir($dir)) !== false) { $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file; // If temp file is current file proceed to the next if ($tmpfilePath == "{$filePath}" . $this->tmpFileSuffix) { continue; } // Remove temp file if it is older than the max age and is not the current file if (preg_match('/' . preg_quote($this->tmpFileSuffix, '/') . '$/', $file) && filemtime($tmpfilePath) < time() - $maxFileAge) { @unlink($tmpfilePath); } } closedir($dir); } // Open temp file if (!($out = @fopen("{$filePath}" . $this->tmpFileSuffix, $chunks ? "ab" : "wb"))) { $this->timServer->error("Failed to open output stream."); return false; } if (!empty($_FILES)) { if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) { $this->timServer->error("Failed to move uploaded file."); return false; } // Read binary input stream and append it to temp file if (!($in = @fopen($_FILES["file"]["tmp_name"], "rb"))) { $this->timServer->error("Failed to open input stream."); return false; } } else { if (!($in = @fopen("php://input", "rb"))) { $this->timServer->error("Failed to open input stream."); return false; } } while ($buff = fread($in, 4096)) { fwrite($out, $buff); } @fclose($out); @fclose($in); // Check if file has been uploaded if (!$chunks || $chunk == $chunks - 1) { if (!$chunks) { $isChunk = false; } else { $isChunk = true; $this->isLastChunk = true; } $path = $filePath . $this->tmpFileSuffix; } else { // chunking, but not the last part $isChunk = true; $path = $filePath . $this->tmpFileSuffix; } }
/** * * Create the biggest thumbnail possible given the maxWidth and maxHeight. * * Ratio is always preserved. * The destination directory is created if necessary. * The function ensures that an image is created (handy to use with uploaded files for security). * * If maxWidth is null and maxHeight is null, the created image will have the same dimensions * as the original image. * * If maxWidth is set and maxHeight is null, then the created image's width will be maxWidth, and the image's height will * be the natural height that maintain the ratio. * * Conversely, if maxHeight is set and maxWidth is null, then the created image's height will be maxHeight, and the image's width will * be the natural width that maintain the ratio. * * If both maxWidth and maxHeight are set, then the created image will have dimensions so that it honors both limitations, * and in accordance with the image original ratio. * * * * maxWidth and maxHeight must be strictly positive integers. * * * * * * * Notes: * Tested transparency of gif and png successfully using * gif to gif * and * png to png * * With (from phpinfo): * - imac 10.11.1 * - php: 5.6.12 * - gdVersion: bundled (2.1.0 compatible) * * * * * * @param $src * @param $dst * @param int $maxWidth * @param int $maxHeight * @return bool */ public static function biggest($src, $dst, $maxWidth = null, $maxHeight = null) { list($srcWidth, $srcHeight, $srcType) = getimagesize($src); //------------------------------------------------------------------------------/ // Compute height and width //------------------------------------------------------------------------------/ $ratio = $srcWidth / $srcHeight; $width = $srcWidth; $height = $srcHeight; $maxWidth = (int) $maxWidth; $maxHeight = (int) $maxHeight; $res = false; if (0 !== $maxWidth && 0 === $maxHeight) { $width = $maxWidth; $height = $width / $ratio; } elseif (0 !== $maxHeight && 0 === $maxWidth) { $height = $maxHeight; $width = $height * $ratio; } elseif (0 !== $maxWidth && 0 !== $maxHeight) { // taller if ($height > $maxHeight) { $width = $maxHeight / $height * $width; $height = $maxHeight; } // wider if ($width > $maxWidth) { $height = $maxWidth / $width * $height; $width = $maxWidth; } } $imageFinal = imagecreatetruecolor($width, $height); switch ($srcType) { case IMAGETYPE_JPEG: case IMAGETYPE_JPEG2000: $image = imagecreatefromjpeg($src); break; case IMAGETYPE_PNG: $image = imagecreatefrompng($src); imagealphablending($imageFinal, false); imagesavealpha($imageFinal, true); $transparent = imagecolorallocatealpha($imageFinal, 255, 255, 255, 127); imagefilledrectangle($imageFinal, 0, 0, $width, $height, $transparent); break; case IMAGETYPE_GIF: $image = imagecreatefromgif($src); $transparent_index = imagecolortransparent($image); if ($transparent_index >= 0) { imagepalettecopy($image, $imageFinal); imagefill($imageFinal, 0, 0, $transparent_index); imagecolortransparent($imageFinal, $transparent_index); imagetruecolortopalette($imageFinal, true, 256); } break; default: throw new \RuntimeException("Unsupported image format: {$srcType}"); break; } imagecopyresampled($imageFinal, $image, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight); // assuming the file has an explicit extension (otherwise accept an array as argument...) $ext = strtolower(FileSystemTool::getFileExtension($dst)); if (true === FileSystemTool::mkdir(dirname($dst), 0777, true)) { switch ($ext) { case 'jpeg': case 'jpg': $res = imagejpeg($imageFinal, $dst); break; case 'png': $res = imagepng($imageFinal, $dst); break; case 'gif': $res = imagegif($imageFinal, $dst); break; default: throw new \RuntimeException("Unsupported destination image extension: {$ext}"); break; } imagedestroy($imageFinal); imagedestroy($image); } else { $dst_parent = dirname($dst); trigger_error("Couldn't create the target directory {$dst_parent}", E_USER_WARNING); } return $res; }