/**
  * @param  DataObjectInterface $record
  * @return bool|DataArchiveFileField
  */
 public function saveInto(DataObjectInterface $record)
 {
     if (!isset($_FILES[$this->name])) {
         return false;
     }
     if (!$record instanceof DNDataArchive) {
         throw new LogicException('Saving into wrong type, expected DNDataArchive');
     }
     $dataArchive = $record;
     /** @var DNDataTransfer $dataTransfer */
     $dataTransfer = $dataArchive->DataTransfers()->First();
     if (!$dataTransfer) {
         throw new LogicException('No transfer found');
     }
     $fileClass = File::get_class_for_file_extension(pathinfo($_FILES[$this->name]['name'], PATHINFO_EXTENSION));
     $file = new $fileClass();
     // Hack: loadIntoFile assumes paths relative to assets,
     //  otherwise it creates the whole structure *within* that folder
     $absolutePath = $dataArchive->generateFilepath($dataTransfer);
     $relativePath = preg_replace('#^' . preg_quote(ASSETS_PATH) . '/#', '', $absolutePath);
     $this->upload->loadIntoFile($_FILES[$this->name], $file, $relativePath);
     if ($this->upload->isError()) {
         return false;
     }
     $file = $this->upload->getFile();
     if ($this->relationAutoSetting) {
         // save to record
         $record->{$this->name . 'ID'} = $file->ID;
     }
     return $this;
 }
Example #2
0
 public function saveInto(DataObjectInterface $record)
 {
     if (!isset($_FILES[$this->name])) {
         return false;
     }
     $fileClass = File::get_class_for_file_extension(pathinfo($_FILES[$this->name]['name'], PATHINFO_EXTENSION));
     if ($this->relationAutoSetting) {
         // assume that the file is connected via a has-one
         $hasOnes = $record->has_one($this->name);
         // try to create a file matching the relation
         $file = is_string($hasOnes) ? Object::create($hasOnes) : new $fileClass();
     } else {
         $file = new $fileClass();
     }
     $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->folderName);
     if ($this->upload->isError()) {
         return false;
     }
     $file = $this->upload->getFile();
     if ($this->relationAutoSetting) {
         if (!$hasOnes) {
             return false;
         }
         // save to record
         $record->{$this->name . 'ID'} = $file->ID;
     }
     return $this;
 }
 /**
  * Gets the classname for the file, e.g. from the declared
  * file relation on the record.
  *
  * If given a filename, look at the extension and upgrade it
  * to an Image if necessary.
  * 
  * @param  string $filename 
  * @return string
  */
 public function getFileClass($filename = null)
 {
     $name = $this->getName();
     $record = $this->getRecord();
     $ext = pathinfo($filename, PATHINFO_EXTENSION);
     $defaultClass = File::get_class_for_file_extension($ext);
     if (empty($name) || empty($record)) {
         return $defaultClass;
     }
     if ($record) {
         $class = $record->getRelationClass($name);
         if (!$class) {
             $class = "File";
         }
     }
     if ($filename) {
         if ($defaultClass == "Image" && $this->config()->upgrade_images && !Injector::inst()->get($class) instanceof Image) {
             $class = "Image";
         }
     }
     return $class;
 }
Example #4
0
 /**
  * Save an file passed from a form post into this object.
  * File names are filtered through {@link FileNameFilter}, see class documentation
  * on how to influence this behaviour.
  * 
  * @param $tmpFile array Indexed array that PHP generated for every file it uploads.
  * @param $folderPath string Folder path relative to /assets
  * @return Boolean|string Either success or error-message.
  */
 public function load($tmpFile, $folderPath = false)
 {
     $this->clearErrors();
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     if (!is_array($tmpFile)) {
         user_error("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype", E_USER_ERROR);
     }
     if (!$tmpFile['size']) {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // @TODO This puts a HUGE limitation on files especially when lots
     // have been uploaded.
     $base = Director::baseFolder();
     $parentFolder = Folder::find_or_make($folderPath);
     // Create a folder for uploading.
     if (!file_exists(ASSETS_PATH . "/" . $folderPath)) {
         Filesystem::makeFolder(ASSETS_PATH . "/" . $folderPath);
     }
     // Generate default filename
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $fileName = basename($file);
     $relativeFilePath = ASSETS_DIR . "/" . $folderPath . "/{$fileName}";
     // Create a new file record (or try to retrieve an existing one)
     if (!$this->file) {
         $fileClass = File::get_class_for_file_extension(pathinfo($tmpFile['name'], PATHINFO_EXTENSION));
         if ($this->replaceFile) {
             $this->file = File::get()->filter(array('Name' => $fileName, 'ParentID' => $parentFolder ? $parentFolder->ID : 0))->First();
         }
         if (!$this->file) {
             $this->file = new $fileClass();
         }
     }
     // if filename already exists, version the filename (e.g. test.gif to test1.gif)
     if (!$this->replaceFile) {
         while (file_exists("{$base}/{$relativeFilePath}")) {
             $i = isset($i) ? $i + 1 : 2;
             $oldFilePath = $relativeFilePath;
             // make sure archives retain valid extensions
             if (substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.gz')) == '.tar.gz' || substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.bz2')) == '.tar.bz2') {
                 $relativeFilePath = preg_replace('/[0-9]*(\\.tar\\.[^.]+$)/', $i . '\\1', $relativeFilePath);
             } else {
                 if (strpos($relativeFilePath, '.') !== false) {
                     $relativeFilePath = preg_replace('/[0-9]*(\\.[^.]+$)/', $i . '\\1', $relativeFilePath);
                 } else {
                     if (strpos($relativeFilePath, '_') !== false) {
                         $relativeFilePath = preg_replace('/_([^_]+$)/', '_' . $i, $relativeFilePath);
                     } else {
                         $relativeFilePath .= '_' . $i;
                     }
                 }
             }
             if ($oldFilePath == $relativeFilePath && $i > 2) {
                 user_error("Couldn't fix {$relativeFilePath} with {$i} tries", E_USER_ERROR);
             }
         }
     } else {
         //reset the ownerID to the current member when replacing files
         $this->file->OwnerID = Member::currentUser() ? Member::currentUser()->ID : 0;
     }
     if (file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], "{$base}/{$relativeFilePath}")) {
         $this->file->ParentID = $parentFolder ? $parentFolder->ID : 0;
         // This is to prevent it from trying to rename the file
         $this->file->Name = basename($relativeFilePath);
         $this->file->write();
         $this->extend('onAfterLoad', $this->file);
         //to allow extensions to e.g. create a version after an upload
         return true;
     } else {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
 }
Example #5
0
 /**
  * Save an file passed from a form post into this object.
  * File names are filtered through {@link FileNameFilter}, see class documentation
  * on how to influence this behaviour.
  * 
  * @param $tmpFile array Indexed array that PHP generated for every file it uploads.
  * @param $folderPath string Folder path relative to /assets
  * @return Boolean|string Either success or error-message.
  */
 public function load($tmpFile, $folderPath = false)
 {
     $this->clearErrors();
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     if (!is_array($tmpFile)) {
         user_error("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype", E_USER_ERROR);
     }
     if (!$tmpFile['size']) {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // @TODO This puts a HUGE limitation on files especially when lots
     // have been uploaded.
     $base = Director::baseFolder();
     $parentFolder = Folder::find_or_make($folderPath);
     // Generate default filename
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $fileName = basename($file);
     $relativeFolderPath = $parentFolder ? $parentFolder->getRelativePath() : ASSETS_DIR . '/';
     $relativeFilePath = $relativeFolderPath . $fileName;
     // Create a new file record (or try to retrieve an existing one)
     if (!$this->file) {
         $fileClass = File::get_class_for_file_extension(pathinfo($tmpFile['name'], PATHINFO_EXTENSION));
         $this->file = new $fileClass();
     }
     if (!$this->file->ID && $this->replaceFile) {
         $fileClass = $this->file->class;
         $file = File::get()->filter(array('ClassName' => $fileClass, 'Name' => $fileName, 'ParentID' => $parentFolder ? $parentFolder->ID : 0))->First();
         if ($file) {
             $this->file = $file;
         }
     }
     // if filename already exists, version the filename (e.g. test.gif to test2.gif, test2.gif to test3.gif)
     if (!$this->replaceFile) {
         $fileSuffixArray = explode('.', $fileName);
         $fileTitle = array_shift($fileSuffixArray);
         $fileSuffix = !empty($fileSuffixArray) ? '.' . implode('.', $fileSuffixArray) : null;
         // make sure files retain valid extensions
         $oldFilePath = $relativeFilePath;
         $relativeFilePath = $relativeFolderPath . $fileTitle . $fileSuffix;
         if ($oldFilePath !== $relativeFilePath) {
             user_error("Couldn't fix {$relativeFilePath}", E_USER_ERROR);
         }
         while (file_exists("{$base}/{$relativeFilePath}")) {
             $i = isset($i) ? $i + 1 : 2;
             $oldFilePath = $relativeFilePath;
             $pattern = '/([0-9]+$)/';
             if (preg_match($pattern, $fileTitle)) {
                 $fileTitle = preg_replace($pattern, $i, $fileTitle);
             } else {
                 $fileTitle .= $i;
             }
             $relativeFilePath = $relativeFolderPath . $fileTitle . $fileSuffix;
             if ($oldFilePath == $relativeFilePath && $i > 2) {
                 user_error("Couldn't fix {$relativeFilePath} with {$i} tries", E_USER_ERROR);
             }
         }
     } else {
         //reset the ownerID to the current member when replacing files
         $this->file->OwnerID = Member::currentUser() ? Member::currentUser()->ID : 0;
     }
     if (file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], "{$base}/{$relativeFilePath}")) {
         $this->file->ParentID = $parentFolder ? $parentFolder->ID : 0;
         // This is to prevent it from trying to rename the file
         $this->file->Name = basename($relativeFilePath);
         $this->file->write();
         $this->file->onAfterUpload();
         $this->extend('onAfterLoad', $this->file);
         //to allow extensions to e.g. create a version after an upload
         return true;
     } else {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
 }
 public function testGetClassForFileExtension()
 {
     $orig = File::config()->class_for_file_extension;
     File::config()->class_for_file_extension = array('*' => 'MyGenericFileClass');
     File::config()->class_for_file_extension = array('foo' => 'MyFooFileClass');
     $this->assertEquals('MyFooFileClass', File::get_class_for_file_extension('foo'), 'Finds directly mapped file classes');
     $this->assertEquals('MyFooFileClass', File::get_class_for_file_extension('FOO'), 'Works without case sensitivity');
     $this->assertEquals('MyGenericFileClass', File::get_class_for_file_extension('unknown'), 'Falls back to generic class for unknown extensions');
     File::config()->class_for_file_extension = $orig;
 }
Example #7
0
	/**
	 * Construct a child of this Folder with the given name.
	 * It does this without actually using the object model, as this starts messing
	 * with all the data.  Rather, it does a direct database insert.
	 */
	function constructChild($name) {
		// Determine the class name - File, Folder or Image
		$baseDir = $this->FullPath;
		if(is_dir($baseDir . $name)) {
			$className = "Folder";
		} else {
			$className = File::get_class_for_file_extension(pathinfo($name, PATHINFO_EXTENSION));
		}

		if(Member::currentUser()) $ownerID = Member::currentUser()->ID;
		else $ownerID = 0;
		
		$filename = Convert::raw2sql($this->Filename . $name);
		if($className == 'Folder' ) $filename .= '/';

		$name = Convert::raw2sql($name);
		
		DB::query("INSERT INTO \"File\" 
			(\"ClassName\", \"ParentID\", \"OwnerID\", \"Name\", \"Filename\", \"Created\", \"LastEdited\", \"Title\")
			VALUES ('$className', $this->ID, $ownerID, '$name', '$filename', " . DB::getConn()->now() . ',' . DB::getConn()->now() . ", '$name')");
			
		return DB::getGeneratedID("File");
	}
 /**
  * 
  * @param string $name
  * @return number
  */
 public function constructChildSecuredWithSecuredFlag($name)
 {
     // Determine the class name - File, Folder or Image
     $baseDir = $this->owner->FullPath;
     if (is_dir($baseDir . $name)) {
         $className = "Folder";
     } else {
         $className = File::get_class_for_file_extension(pathinfo($name, PATHINFO_EXTENSION));
     }
     $ownerID = 0;
     if (Member::currentUser()) {
         $ownerID = Member::currentUser()->ID;
     }
     $filename = Convert::raw2sql($this->owner->Filename . $name);
     if ($className == 'Folder') {
         $filename .= '/';
     }
     $name = Convert::raw2sql($name);
     $secured = $this->owner->Secured ? '1' : '0';
     DB::query("INSERT INTO \"File\"\n\t\t\t(\"ClassName\",\"ParentID\",\"OwnerID\",\"Name\",\"Filename\",\"Created\",\"LastEdited\",\"Title\",\"Secured\")\n\t\t\tVALUES ('{$className}', " . $this->owner->ID . ", {$ownerID}, '{$name}', '{$filename}', " . DB::getConn()->now() . ',' . DB::getConn()->now() . ", '{$name}', '{$secured}')");
     return DB::getGeneratedID("File");
 }
 /**
  * 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");
 }
Example #10
0
	/**
	 * Save an file passed from a form post into this object.
	 * File names are filtered through {@link FileNameFilter}, see class documentation
	 * on how to influence this behaviour.
	 * 
	 * @param $tmpFile array Indexed array that PHP generated for every file it uploads.
	 * @param $folderPath string Folder path relative to /assets
	 * @return Boolean|string Either success or error-message.
	 */
	function load($tmpFile, $folderPath = false) {
		$this->clearErrors();
		
		if(!$folderPath) $folderPath = self::$uploads_folder;
		
		if(!$this->file) {
			$fileClass = File::get_class_for_file_extension(pathinfo($tmpFile['name'], PATHINFO_EXTENSION));
			$this->file = new $fileClass();
		}
		
		if(!is_array($tmpFile)) {
			user_error("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype", E_USER_ERROR);
		}
		
		if(!$tmpFile['size']) {
			$this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
			return false;
		}
		
		$valid = $this->validate($tmpFile);
		if(!$valid) return false;
		
		// @TODO This puts a HUGE limitation on files especially when lots
		// have been uploaded.
		$base = Director::baseFolder();
		$parentFolder = Folder::find_or_make($folderPath);

		// Create a folder for uploading.
		if(!file_exists(ASSETS_PATH)){
			mkdir(ASSETS_PATH, Filesystem::$folder_create_mask);
		}
		if(!file_exists(ASSETS_PATH . "/" . $folderPath)){
			mkdir(ASSETS_PATH . "/" . $folderPath, Filesystem::$folder_create_mask);
		}

		// Generate default filename
		$nameFilter = FileNameFilter::create();
		$file = $nameFilter->filter($tmpFile['name']);
		$fileName = basename($file);

		$relativeFilePath = ASSETS_DIR . "/" . $folderPath . "/$fileName";
		
		// if filename already exists, version the filename (e.g. test.gif to test1.gif)
		while(file_exists("$base/$relativeFilePath")) {
			$i = isset($i) ? ($i+1) : 2;
			$oldFilePath = $relativeFilePath;
			// make sure archives retain valid extensions
			if(substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.gz')) == '.tar.gz' ||
				substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.bz2')) == '.tar.bz2') {
					$relativeFilePath = preg_replace('/[0-9]*(\.tar\.[^.]+$)/', $i . '\\1', $relativeFilePath);
			} else if (strpos($relativeFilePath, '.') !== false) {
				$relativeFilePath = preg_replace('/[0-9]*(\.[^.]+$)/', $i . '\\1', $relativeFilePath);
			} else if (strpos($relativeFilePath, '_') !== false) {
				$relativeFilePath = preg_replace('/_([^_]+$)/', '_'.$i, $relativeFilePath);
			} else {
				$relativeFilePath .= '_'.$i;
			}
			if($oldFilePath == $relativeFilePath && $i > 2) user_error("Couldn't fix $relativeFilePath with $i tries", E_USER_ERROR);
		}

		if(file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], "$base/$relativeFilePath")) {
			$this->file->ParentID = $parentFolder->ID;
			// This is to prevent it from trying to rename the file
			$this->file->Name = basename($relativeFilePath);
			$this->file->write();
			return true;
		} else {
			$this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
			return false;
		}
	}
 /**
  * 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();
 }
Example #12
0
 /**
  * Construct a child of this Folder with the given name.
  * It does this without actually using the object model, as this starts messing
  * with all the data.  Rather, it does a direct database insert.
  *
  * @param string $name Name of the file or folder
  * @return integer the ID of the newly saved File record
  */
 public function constructChild($name)
 {
     // Determine the class name - File, Folder or Image
     $baseDir = $this->FullPath;
     if (is_dir($baseDir . $name)) {
         $className = "Folder";
     } else {
         $className = File::get_class_for_file_extension(pathinfo($name, PATHINFO_EXTENSION));
     }
     $ownerID = Member::currentUserID();
     $filename = $this->Filename . $name;
     if ($className == 'Folder') {
         $filename .= '/';
     }
     $nowExpression = DB::get_conn()->now();
     DB::prepared_query("INSERT INTO \"File\"\n\t\t\t(\"ClassName\", \"ParentID\", \"OwnerID\", \"Name\", \"Filename\", \"Created\", \"LastEdited\", \"Title\")\n\t\t\tVALUES (?, ?, ?, ?, ?, {$nowExpression}, {$nowExpression}, ?)", array($className, $this->ID, $ownerID, $name, $filename, $name));
     return DB::get_generated_id("File");
 }
 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;
 }
 /**
  * Handles media objects from kapost
  * @param {mixed} $blog_id Site Config related to this content object
  * @param {array} $content Content object to be handled
  * @return {xmlrpcresp} XML-RPC Response object
  */
 protected function newMediaObject($blog_id, $content)
 {
     $fileName = $content['name'];
     $validator = new Upload_Validator(array('name' => $fileName));
     $validator->setAllowedExtensions(File::config()->allowed_extensions);
     //Verify we have a valid extension
     if ($validator->isValidExtension() == false) {
         return $this->httpError(403, _t('KapostService.FILE_NOT_ALLOWED', '_File extension is not allowed'));
     }
     //Generate default filename
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($fileName);
     while ($file[0] == '_' || $file[0] == '.') {
         $file = substr($file, 1);
     }
     $doubleBarrelledExts = array('.gz', '.bz', '.bz2');
     $ext = "";
     if (preg_match('/^(.*)(\\.[^.]+)$/', $file, $matches)) {
         $file = $matches[1];
         $ext = $matches[2];
         // Special case for double-barrelled
         if (in_array($ext, $doubleBarrelledExts) && preg_match('/^(.*)(\\.[^.]+)$/', $file, $matches)) {
             $file = $matches[1];
             $ext = $matches[2] . $ext;
         }
     }
     $origFile = $file;
     //Find the kapost media folder
     $kapostMediaFolder = Folder::find_or_make($this->config()->kapost_media_folder);
     if (file_exists($kapostMediaFolder->getFullPath() . '/' . $file . $ext)) {
         if (self::config()->duplicate_assets == 'overwrite') {
             $obj = File::get()->filter('Filename', Convert::raw2sql($kapostMediaFolder->Filename . $file . $ext))->first();
             if (!empty($obj) && $obj !== false && $obj->ID > 0) {
                 //Update the Title for the image
                 $obj->Title = !empty($content['alt']) ? $content['alt'] : str_replace(array('-', '_'), ' ', preg_replace('/\\.[^.]+$/', '', $obj->Name));
                 $obj->write();
                 //Write the file to the file system
                 $f = fopen($kapostMediaFolder->getFullPath() . '/' . $file . $ext, 'w');
                 fwrite($f, $content['bits']);
                 fclose($f);
                 return array('id' => $obj->ID, 'url' => $obj->getAbsoluteURL());
             }
             return $this->httpError(404, _t('KapostService.FILE_NOT_FOUND', '_File not found'));
         } else {
             if (self::config()->duplicate_assets == 'ignore') {
                 return $this->httpError(409, _t('KapostService.DUPLICATE_FILE', '_Duplicate file detected, please rename the file and try again'));
             } else {
                 if (self::config()->duplicate_assets == 'smart_rename' && file_exists($kapostMediaFolder->getFullPath() . '/' . $file . $ext)) {
                     $obj = File::get()->filter('Filename', Convert::raw2sql($kapostMediaFolder->Filename . $file . $ext))->first();
                     if (!empty($obj) && $obj !== false && $obj->ID > 0) {
                         $fileHash = sha1_file($kapostMediaFolder->getFullPath() . '/' . $file . $ext);
                         if ($fileHash == sha1($content['bits'])) {
                             return array('id' => $obj->ID, 'url' => $obj->getAbsoluteURL());
                         }
                     }
                 }
                 $i = 1;
                 while (file_exists($kapostMediaFolder->getFullPath() . '/' . $file . $ext)) {
                     $i++;
                     $oldFile = $file;
                     if (strpos($file, '.') !== false) {
                         $file = preg_replace('/[0-9]*(\\.[^.]+$)/', $i . '\\1', $file);
                     } else {
                         if (strpos($file, '_') !== false) {
                             $file = preg_replace('/_([^_]+$)/', '_' . $i, $file);
                         } else {
                             $file .= '_' . $i;
                         }
                     }
                     if ($oldFile == $file && $i > 2) {
                         return $this->httpError(500, _t('KapostService.FILE_RENAME_FAIL', '_Could not fix {filename} with {attempts} attempts', array('filename' => $file . $ext, 'attempts' => $i)));
                     }
                 }
                 //Write the file to the file system
                 $f = fopen($kapostMediaFolder->getFullPath() . '/' . $file . $ext, 'w');
                 fwrite($f, $content['bits']);
                 fclose($f);
                 //Write the file to the database
                 $className = File::get_class_for_file_extension(substr($ext, 1));
                 $obj = new $className();
                 $obj->Name = $file . $ext;
                 $obj->Title = !empty($content['alt']) ? $content['alt'] : str_replace(array('-', '_'), ' ', preg_replace('/\\.[^.]+$/', '', $obj->Name));
                 $obj->FileName = $kapostMediaFolder->getRelativePath() . '/' . $file . $ext;
                 $obj->ParentID = $kapostMediaFolder->ID;
                 //If subsites is enabled add it to the correct subsite
                 if (File::has_extension('FileSubsites')) {
                     $obj->SubsiteID = $blog_id;
                 }
                 $obj->write();
                 $this->extend('updateNewMediaAsset', $blog_id, $content, $obj);
                 return array('id' => $obj->ID, 'url' => $obj->getAbsoluteURL());
             }
         }
     } else {
         //Write the file to the file system
         $f = fopen($kapostMediaFolder->getFullPath() . '/' . $file . $ext, 'w');
         fwrite($f, $content['bits']);
         fclose($f);
         //Write the file to the database
         $className = File::get_class_for_file_extension(substr($ext, 1));
         $obj = new $className();
         $obj->Name = $file . $ext;
         $obj->Title = !empty($content['alt']) ? $content['alt'] : str_replace(array('-', '_'), ' ', preg_replace('/\\.[^.]+$/', '', $obj->Name));
         $obj->FileName = $kapostMediaFolder->getRelativePath() . '/' . $file . $ext;
         $obj->ParentID = $kapostMediaFolder->ID;
         //If subsites is enabled add it to the correct subsite
         if (File::has_extension('FileSubsites')) {
             $obj->SubsiteID = $blog_id;
         }
         $obj->write();
         $this->extend('updateNewMediaAsset', $blog_id, $content, $obj);
         return array('id' => $obj->ID, 'url' => $obj->getAbsoluteURL());
     }
 }
 /**
  * Create a local file record for a given url
  *
  * @param string $filename Path relative to site root
  * @return File Created file record
  */
 protected function makeLocalFile($filename)
 {
     // Create folder structure
     $parentFolder = Folder::find_or_make(preg_replace('/^assets\\//', '', dirname($filename)));
     // Find remote file with this name
     $remoteFile = $this->findRemoteFile(array('"File"."Filename" LIKE \'' . Convert::raw2sql($filename) . '\''));
     // Create local file from this data
     $className = File::get_class_for_file_extension(pathinfo($filename, PATHINFO_EXTENSION));
     $localFile = $className::create();
     $localFile->ParentID = $parentFolder->ID;
     if ($remoteFile) {
         $this->updateLocalFile($localFile, $remoteFile);
     } else {
         $localFile->Name = basename($filename);
         $localFile->write();
     }
     return $localFile;
 }