public function onAfterUpload() { //Get the full path to the image file $imagePath = $this->owner->getFullPath(); if (!file_exists($imagePath)) { return; } //Check the extension of the image to make sure we are dealing with a JPEG file //We do not need to process PNG images - they do not contain Exchangeable image file format (Exif) data $imageFileExt = strtolower(File::get_file_extension($imagePath)); if (!in_array($imageFileExt, array('jpeg', 'jpg'))) { return; } //Read the JPEG image Exif data to get the Orientation value $exif = exif_read_data($imagePath); $orientation = @$exif['IFD0']['Orientation']; if (!$orientation) { $orientation = @$exif['Orientation']; } if (!$orientation) { return; } //Create a new image from file $source = @imagecreatefromjpeg($imagePath); if (!$source) { return; } //Modify according to Orientation //Replace JPEG at source, thus no other complexities regarding renaming, etc. //Note: Replacing an image this way strips any Exif data from the image switch ($orientation) { case 3: $modifiedImage = imagerotate($source, 180, 0); imagejpeg($modifiedImage, $imagePath, 100); //save output to file system at full quality break; case 6: $modifiedImage = imagerotate($source, -90, 0); imagejpeg($modifiedImage, $imagePath, 100); //save output to file system at full quality break; case 8: $modifiedImage = imagerotate($source, 90, 0); imagejpeg($modifiedImage, $imagePath, 100); //save output to file system at full quality break; } //Delete any cached formatted versions of the image. $this->owner->deleteFormattedImages(); }
/** * Takes the human-readable URL of an embeddable resource and converts it into an * Oembed_Result descriptor (which contains a full Oembed resource URL). * * @param $url Human-readable URL * @param $type ? * @param $options array Options to be used for constructing the resulting descriptor. * @returns Oembed_Result/bool An Oembed descriptor, or false */ public static function get_oembed_from_url($url, $type = false, array $options = array()) { if (!self::is_enabled()) { return false; } // Find or build the Oembed URL. $endpoint = self::find_endpoint($url); $oembedUrl = false; if (!$endpoint) { if (self::get_autodiscover()) { $oembedUrl = self::autodiscover_from_url($url); } } elseif ($endpoint === true) { $oembedUrl = self::autodiscover_from_url($url); } else { // Build the url manually - we gave all needed information. $oembedUrl = Controller::join_links($endpoint, '?format=json&url=' . rawurlencode($url)); } // If autodescovery failed the resource might be a direct link to a file if (!$oembedUrl) { if (File::get_app_category(File::get_file_extension($url)) == "image") { return new Oembed_Result($url, $url, $type, $options); } } if ($oembedUrl) { // Inject the options into the Oembed URL. if ($options) { if (isset($options['width']) && !isset($options['maxwidth'])) { $options['maxwidth'] = $options['width']; } if (isset($options['height']) && !isset($options['maxheight'])) { $options['maxheight'] = $options['height']; } $oembedUrl = Controller::join_links($oembedUrl, '?' . http_build_query($options, '', '&')); } return new Oembed_Result($oembedUrl, $url, $type, $options); } // No matching Oembed resource found. return false; }
/** * removes the appendation from the name * @param type $filename * @param type $appendation * @return string */ public static function removeFilenameAppender($filename, $appendation) { $ext = File::get_file_extension($filename); if ($ext != 'unknown') { $outstr = substr($filename, 0, -(strlen($ext) + 1)); $outstr = substr($outstr, 0, -strlen($appendation)); $outstr .= '.' . $ext; return $outstr; } return $filename; }
/** * Given a filename and list of files, generate a new filename unique to these files * * @param string $name * @param array $files * @return string */ protected function hashedCombinedFilename($combinedFile, $fileList) { $name = pathinfo($combinedFile, PATHINFO_FILENAME); $hash = $this->hashOfFiles($fileList); $extension = File::get_file_extension($combinedFile); return $name . '-' . substr($hash, 0, 7) . '.' . $extension; }
/** * Generate an image on the specified format. It will save the image * at the location specified by cacheFilename(). The image will be generated * using the specific 'generate' method for the specified format. * @param string $format Name of the format to generate. * @param string $arg1 Argument to pass to the generate method. * @param string $arg2 A second argument to pass to the generate method. */ function generateFormattedImage($format, $arg1 = null, $arg2 = null) { $cacheFile = $this->cacheFilename($format, $arg1, $arg2); $gd = new GD($this->URL); if ($gd->hasGD()) { $generateFunc = "generate{$format}"; if ($this->hasMethod($generateFunc)) { $gd = $this->{$generateFunc}($gd, $arg1, $arg2); if ($gd) { $bucket = $this->getUploadBucket(); // TODO create bucket if it does not exist // $this->S3->putBucket($bucket, S3::ACL_PUBLIC_READ); $tempFile = tempnam(getTempFolder(), 's3images') . File::get_file_extension($cacheFile); $gd->writeTo($tempFile); $this->S3->putObjectFile($tempFile, $bucket, '_resampled/' . basename($cacheFile), S3::ACL_PUBLIC_READ); unlink($tempFile); } } else { USER_ERROR("Image::generateFormattedImage - Image {$format} function not found.", E_USER_WARNING); } } }
/** * Get the MIME type based on a file's extension. * * If the finfo class exists in PHP, and the file actually exists, then use that * extension, otherwise fallback to a list of commonly known MIME types. * * @uses finfo * @param string $filename Relative path to filename from project root, e.g. "mysite/tests/file.csv" * @return string MIME type */ public static function get_mime_type($filename) { // If the finfo module is compiled into PHP, use it. $path = BASE_PATH . DIRECTORY_SEPARATOR . $filename; if (class_exists('finfo') && file_exists($path)) { $finfo = new finfo(FILEINFO_MIME_TYPE); return $finfo->file($path); } // Fallback to use the list from the HTTP.yml configuration and rely on the file extension // to get the file mime-type $ext = File::get_file_extension($filename); // Get the mime-types $mimeTypes = Config::inst()->get('HTTP', 'MimeTypes'); // The mime type doesn't exist if (!isset($mimeTypes[$ext])) { return 'application/unknown'; } return $mimeTypes[$ext]; }
/** * Return the extension of the file based on its name. * * This function is meant to mimic the equivalent for File. * * @return string File extension */ public function getExtension() { return File::get_file_extension($this->getField('Name')); }
/** * @param SS_HTTPRequest $request * @return SS_HTTPResponse|void */ public function upload(SS_HTTPRequest $request) { if ($this->isDisabled() || $this->isReadonly() || !$this->canUpload()) { return $this->httpError(403); } // Protect against CSRF on destructive action $token = $this->getForm()->getSecurityToken(); if (!$token->checkRequest($request)) { return $this->httpError(400); } // Get form details $name = $this->getName(); $postVars = $request->postVar($name); // Save the temporary file into a File object $uploadedFiles = $this->extractUploadedFileData($postVars); $return = array('error' => 'The file upload was not successful'); $uploadedFile = reset($uploadedFiles); $strClass = CloudinaryFile::GetCloudinaryFileForFile($uploadedFile['name']); $arrOptions = array(); if ($strClass == 'CloudinaryVideo') { $arrOptions['resource_type'] = 'video'; } elseif ($strClass == 'CloudinaryFile') { $arrOptions['resource_type'] = 'raw'; $arrOptions['format'] = File::get_file_extension($uploadedFile['name']); } $arrUploaderDetails = \Cloudinary\Uploader::upload($uploadedFile['tmp_name'], $arrOptions); if ($arrUploaderDetails && is_array($arrUploaderDetails)) { if ($strClass == 'CloudinaryFile') { $arrPieces = explode('.', $arrUploaderDetails['public_id']); $strPublicID = isset($arrPieces[0]) ? $arrPieces[0] : ''; $strFormat = isset($arrPieces[1]) ? $arrPieces[1] : ''; } else { $strPublicID = $arrUploaderDetails['public_id']; $strFormat = $arrUploaderDetails['format']; } $arrData = array('Title' => $uploadedFile['name'], 'FileName' => $uploadedFile['name'], 'PublicID' => $strPublicID, 'Version' => $arrUploaderDetails['version'], 'Signature' => $arrUploaderDetails['signature'], 'URL' => $arrUploaderDetails['url'], 'SecureURL' => $arrUploaderDetails['secure_url'], 'FileType' => $arrUploaderDetails['resource_type'], 'FileSize' => $arrUploaderDetails['bytes'], 'Format' => $strFormat); if ($strClass == 'CloudinaryImage') { $arrData = array_merge($arrData, array('Width' => $arrUploaderDetails['width'], 'Height' => $arrUploaderDetails['height'])); } else { if ($strClass == 'CloudinaryVideo') { $arrData = array_merge($arrData, array('Width' => $arrUploaderDetails['width'], 'Height' => $arrUploaderDetails['height'], 'Duration' => $arrUploaderDetails['duration'], 'BitRate' => $arrUploaderDetails['bit_rate'], 'FrameRate' => $arrUploaderDetails['frame_rate'])); } } $file = new $strClass($arrData); $file->write(); $return = $this->encodeCloudinaryAttributes($file); } $response = new SS_HTTPResponse(Convert::raw2json(array($return))); $response->addHeader('Content-Type', 'text/plain'); if (!empty($return['error'])) { $response->setStatusCode(403); } return $response; }
/** * Indexes a DataObject. * * File objects have text extracted from them using subclasses of the * ZendSearchLuceneTextExtractor class. Any number of text extractors can * attempt to scan a file of any given extension; the first successful one * will be used. * * If the dataobject has a function called Link(), this will be added as an * unindexed field. * * @param DataObject $object The DataObject to index. If the DataObject * does not have the ZendSearchLuceneSearchable * extension, it is not indexed. */ public static function index($object) { if (!Object::has_extension($object->ClassName, 'ZendSearchLuceneSearchable')) { return; } $index = self::getIndex(); // Remove currently indexed data for this object self::delete($object); $doc = new Zend_Search_Lucene_Document(); if ($object->is_a('File')) { // Files get text extracted if possible if ($object->class == 'Folder') { return; } // Loop through all file text extractors... foreach (self::getTextExtractorClasses() as $extractor_class) { $extensions = new ReflectionClass($extractor_class); $extensions = $extensions->getStaticPropertyValue('extensions'); if (!in_array(strtolower(File::get_file_extension($object->Filename)), $extensions)) { continue; } // Try any that support the given file extension $content = call_user_func(array($extractor_class, 'extract'), Director::baseFolder() . '/' . $object->Filename); if (!$content) { continue; } // Use the first extractor we find that gives us content. $doc = new Zend_Search_Lucene_Document(); $field = Zend_Search_Lucene_Field::Text('body', $content, ZendSearchLuceneSearchable::$encoding); $doc->addField($field); break; } } // Index the fields we've specified in the config $fields = array_merge($object->getExtraSearchFields(), $object->getSearchFields()); foreach ($fields as $fieldName) { $field_config = $object->getLuceneFieldConfig($fieldName); // Normal database field or function call $field = self::getZendField($object, $fieldName); if (isset($field_config['boost'])) { $field->boost = $field_config['boost']; } if (!$field) { continue; } $doc->addField($field); } // Add URL if we have a function called Link(). We didn't use the // extraSearchFields mechanism for this because it's not a property on // all objects, so this is the most sensible place for it. if (method_exists(get_class($object), 'Link') && !in_array('Link', $fields)) { $doc->addField(Zend_Search_Lucene_Field::UnIndexed('Link', $object->Link())); } $index->addDocument($doc); $index->commit(); }
/** * Given a file and filename, ensure that file renaming / replacing rules are satisfied * * If replacing, this method may replace $this->file with an existing record to overwrite. * If renaming, a new value for $filename may be returned * * @param string $filename * @return string $filename A filename safe to write to * @throws Exception */ protected function resolveExistingFile($filename) { // Create a new file record (or try to retrieve an existing one) if (!$this->file) { $fileClass = File::get_class_for_file_extension(File::get_file_extension($filename)); $this->file = Object::create($fileClass); } // Skip this step if not writing File dataobjects if (!$this->file instanceof File) { return $filename; } // Check there is if existing file $existing = File::find($filename); // If replacing (or no file exists) confirm this filename is safe if ($this->replaceFile || !$existing) { // If replacing files, make sure to update the OwnerID if (!$this->file->ID && $this->replaceFile && $existing) { $this->file = $existing; $this->file->OwnerID = Member::currentUserID(); } // Filename won't change if replacing return $filename; } // if filename already exists, version the filename (e.g. test.gif to test-v2.gif, test-v2.gif to test-v3.gif) $renamer = $this->getNameGenerator($filename); foreach ($renamer as $newName) { if (!File::find($newName)) { return $newName; } } // Fail $tries = $renamer->getMaxTries(); throw new Exception("Could not rename {$filename} with {$tries} tries"); }
/** * Gets the category of this file type. Borrowed from {@see File} * * @return string */ public function appCategory() { $ext = File::get_file_extension($this->Name); switch ($ext) { case "aif": case "au": case "mid": case "midi": case "mp3": case "ra": case "ram": case "rm": case "mp3": case "wav": case "m4a": case "snd": case "aifc": case "aiff": case "wma": case "apl": case "avr": case "cda": case "mp4": case "ogg": return "audio"; case "mpeg": case "mpg": case "m1v": case "mp2": case "mpa": case "mpe": case "ifo": case "vob": case "avi": case "wmv": case "asf": case "m2v": case "qt": return "mov"; case "arc": case "rar": case "tar": case "gz": case "tgz": case "bz2": case "dmg": case "jar": case "ace": case "arj": case "bz": case "cab": return "zip"; case "bmp": case "gif": case "jpg": case "jpeg": case "pcx": case "tif": case "png": case "alpha": case "als": case "cel": case "icon": case "ico": case "ps": return "image"; } }
/** * Loads the temporary file data into a File object * * @param array $tmpFile Temporary file data * @param string $error Error message * @return AssetContainer File object, or null if error */ protected function saveTemporaryFile($tmpFile, &$error = null) { // Determine container object $error = null; $fileObject = null; if (empty($tmpFile)) { $error = _t('UploadField.FIELDNOTSET', 'File information not found'); return null; } if ($tmpFile['error']) { $error = $tmpFile['error']; return null; } // Search for relations that can hold the uploaded files, but don't fallback // to default if there is no automatic relation if ($relationClass = $this->getRelationAutosetClass(null)) { // Allow File to be subclassed if ($relationClass === 'File' && isset($tmpFile['name'])) { $relationClass = File::get_class_for_file_extension(File::get_file_extension($tmpFile['name'])); } // Create new object explicitly. Otherwise rely on Upload::load to choose the class. $fileObject = Object::create($relationClass); if (!$fileObject instanceof DataObject || !$fileObject instanceof AssetContainer) { throw new InvalidArgumentException("Invalid asset container {$relationClass}"); } } // Get the uploaded file into a new file object. try { $this->upload->loadIntoFile($tmpFile, $fileObject, $this->getFolderName()); } catch (Exception $e) { // we shouldn't get an error here, but just in case $error = $e->getMessage(); return null; } // Check if upload field has an error if ($this->upload->isError()) { $error = implode(' ' . PHP_EOL, $this->upload->getErrors()); return null; } // return file return $this->upload->getFile(); }
public function saveInto(DataObjectInterface $record) { if (!isset($_FILES[$this->name])) { return false; } $fileClass = File::get_class_for_file_extension(File::get_file_extension($_FILES[$this->name]['name'], PATHINFO_EXTENSION)); if ($this->relationAutoSetting) { // assume that the file is connected via a has-one $objectClass = $record->hasOne($this->name); if ($objectClass === 'File' || empty($objectClass)) { // Create object of the appropriate file class $file = Object::create($fileClass); } else { // try to create a file matching the relation $file = Object::create($objectClass); } } else { if ($record instanceof File) { $file = $record; } else { $file = Object::create($fileClass); } } $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->getFolderName()); if ($this->upload->isError()) { return false; } if ($this->relationAutoSetting) { if (!$objectClass) { return false; } $file = $this->upload->getFile(); $record->{$this->name . 'ID'} = $file->ID; } return $this; }
public function onAfterUpload() { if (!Config::inst()->get('Image', 'magnific_auto_rotate')) { return; } $imagePath = $this->owner->getFullPath(); $imageFileExt = strtolower(File::get_file_extension($imagePath)); if (!in_array($imageFileExt, array('jpeg', 'jpg'))) { return; } $orientation = $this->getExifOrientation(); if (!$orientation) { return; } $source = @imagecreatefromjpeg($imagePath); if (!$source) { return; } switch ($orientation) { case 3: $modifiedImage = imagerotate($source, 180, 0); imagejpeg($modifiedImage, $imagePath, 100); break; case 6: $modifiedImage = imagerotate($source, -90, 0); imagejpeg($modifiedImage, $imagePath, 100); break; case 8: $modifiedImage = imagerotate($source, 90, 0); imagejpeg($modifiedImage, $imagePath, 100); break; } $this->owner->deleteFormattedImages(); }
/** * Return path and type of given combined file * * @param string|array $file Either a file path, or an array spec * @return array array with two elements, path and type of file */ protected function parseCombinedFile($file) { // Array with path and type keys if (is_array($file) && isset($file['path']) && isset($file['type'])) { return array($file['path'], $file['type']); } // Extract value from indexed array if (is_array($file)) { $path = array_shift($file); // See if there's a type specifier if ($file) { $type = array_shift($file); return array($path, $type); } // Otherwise convent to string $file = $path; } $type = File::get_file_extension($file); return array($file, $type); }
/** * Validate that this DBFile accepts this filename as valid * * @param string $filename * @throws ValidationException * @return bool */ protected function isValidFilename($filename) { $extension = strtolower(File::get_file_extension($filename)); // Validate true if within the list of allowed extensions $allowed = $this->getAllowedExtensions(); if ($allowed) { return in_array($extension, $allowed); } // If no extensions are configured, fallback to global list $globalList = File::config()->allowed_extensions; if (in_array($extension, $globalList)) { return true; } // Only admins can bypass global rules return !File::config()->apply_restrictions_to_admin && Permission::check('ADMIN'); }
/** * Get file extension * * @return string */ public function getExtension() { $extension = File::get_file_extension($this->getName()); return strtolower($extension); }
public function testGetExtension() { $this->assertEquals('', File::get_file_extension('myfile'), 'No extension'); $this->assertEquals('txt', File::get_file_extension('myfile.txt'), 'Simple extension'); $this->assertEquals('gz', File::get_file_extension('myfile.tar.gz'), 'Double-barrelled extension only returns last bit'); }