/**
  * Find the given folder or create it as a database record
  *
  * @param string $folderPath Directory path relative to assets root
  * @return Folder|null
  */
 public static function find_or_make($folderPath)
 {
     // replace leading and trailing slashes
     $folderPath = preg_replace('/^\\/?(.*)\\/?$/', '$1', trim($folderPath));
     $parts = explode("/", $folderPath);
     $parentID = 0;
     $item = null;
     $filter = FileNameFilter::create();
     foreach ($parts as $part) {
         if (!$part) {
             continue;
             // happens for paths with a trailing slash
         }
         // Ensure search includes folders with illegal characters removed, but
         // err in favour of matching existing folders if $folderPath
         // includes illegal characters itself.
         $partSafe = $filter->filter($part);
         $item = Folder::get()->filter(array('ParentID' => $parentID, 'Name' => array($partSafe, $part)))->first();
         if (!$item) {
             $item = new Folder();
             $item->ParentID = $parentID;
             $item->Name = $partSafe;
             $item->Title = $part;
             $item->write();
         }
         $parentID = $item->ID;
     }
     return $item;
 }
 /**
  * Description
  * @return string
  */
 protected function determineFolderName()
 {
     // Grab paths
     $paths = Config::inst()->get(__CLASS__, 'upload_paths');
     // Grab ancestry from top-down
     $className = get_class($this->record);
     $classes = array_reverse(ClassInfo::ancestry($className));
     $path = $className;
     // Loop over ancestry and break out if we have a match
     foreach ($classes as $class) {
         if (array_key_exists($class, $paths)) {
             $path = $paths[$class];
             break;
         }
     }
     // If there are any parameters which require matching, search for them
     $matches = array();
     preg_match_all('/\\$[a-zA-Z0-9]+?/U', $path, $matches);
     // Replace with field values
     foreach ($matches[0] as $match) {
         $field = str_replace("\$", "", $match);
         $value = FileNameFilter::create()->filter($this->record->getField($field));
         $path = str_replace($match, $value, $path);
     }
     $this->folderName = $path;
     return $path;
 }
 public function onBeforeWrite()
 {
     parent::onBeforeWrite();
     $this->Title = FileNameFilter::create()->filter($this->Title);
     if (strlen($this->ContentFile)) {
         $templates = $this->fileBasedTemplates();
         if (!isset($templates[$this->ContentFile])) {
             $this->ContentFile = '';
         }
     }
 }
 /**
  * Save an file passed from a form post into this object.
  * 
  * @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)
 {
     if (!$folderPath) {
         $folderPath = Config::inst()->get('Upload', 'uploads_folder');
     }
     // @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
     $fileArray = explode('/', $tmpFile);
     $fileName = $fileArray[count($fileArray) - 1];
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($fileName);
     $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) && copy($tmpFile, $base . "/" . $relativeFilePath)) {
         $this->owner->ParentID = $parentFolder->ID;
         // This is to prevent it from trying to rename the file
         $this->owner->Name = basename($relativeFilePath);
         $this->owner->write();
         return true;
     } else {
         return false;
     }
 }
 public function getPdfPreviewImage()
 {
     $pdfFile = Director::getAbsFile($this->owner->getFileName());
     $pathInfo = pathinfo($pdfFile);
     if (strtolower($pathInfo['extension']) != 'pdf') {
         //@Todo if dev then exception? else fail silently
         return null;
     }
     $fileName = $pathInfo['filename'];
     $savePath = __DIR__ . '/../../';
     $saveImage = $this->imagePrefix . '-' . $fileName . '.jpg';
     // Fix illegal characters
     $filter = FileNameFilter::create();
     $saveImage = $filter->filter($saveImage);
     $saveTo = $savePath . $this->folderToSave . $saveImage;
     $image = DataObject::get_one('Image', "`Name` = '{$saveImage}'");
     if (!$image) {
         $folderObject = DataObject::get_one("Folder", "`Filename` = '{$this->folderToSave}'");
         if ($folderObject) {
             if ($this->generator->generatePreviewImage($pdfFile, $saveTo)) {
                 $image = new Image();
                 $image->ParentID = $folderObject->ID;
                 $image->setName($saveImage);
                 $image->write();
             }
         }
     } else {
         //check LastEdited to update
         $cacheInValid = false;
         if (strtotime($image->LastEdited) < strtotime($this->owner->LastEdited)) {
             $cacheInValid = true;
         }
         if ($cacheInValid) {
             $this->generator->generatePreviewImage($pdfFile, $saveTo);
             $image->setName($saveImage);
             $image->write(false, false, true);
         }
     }
     return $image;
 }
 public function createPdf()
 {
     $storeIn = $this->getStorageFolder();
     $name = FileNameFilter::create()->filter($this->Title);
     $name .= '.pdf';
     if (!$name) {
         throw new Exception("Must have a name!");
     }
     if (!$this->Template) {
         throw new Exception("Please specify a template before rendering.");
     }
     $file = new ComposedPdfFile();
     $file->ParentID = $storeIn->ID;
     $file->SourceID = $this->ID;
     $file->Title = $this->Title;
     $file->setName($name);
     $file->write();
     $content = $this->renderPdf();
     $filename = singleton('PdfRenditionService')->render($content);
     if (file_exists($filename)) {
         copy($filename, $file->getFullPath());
         unlink($filename);
     }
 }
Beispiel #7
0
 /**
  * Setter function for Name. Automatically sets a default title,
  * and removes characters that might be invalid on the filesystem.
  * Also adds a suffix to the name if the filename already exists
  * on the filesystem, and is associated to a different {@link File} database record
  * in the same folder. This means "myfile.jpg" might become "myfile-1.jpg".
  * 
  * Does not change the filesystem itself, please use {@link write()} for this.
  * 
  * @param String $name
  */
 function setName($name)
 {
     $oldName = $this->Name;
     // It can't be blank, default to Title
     if (!$name) {
         $name = $this->Title;
     }
     // Fix illegal characters
     $filter = FileNameFilter::create();
     $name = $filter->filter($name);
     // We might have just turned it blank, so check again.
     if (!$name) {
         $name = 'new-folder';
     }
     // If it's changed, check for duplicates
     if ($oldName && $oldName != $name) {
         $base = pathinfo($name, PATHINFO_BASENAME);
         $ext = self::get_file_extension($name);
         $suffix = 1;
         while (DataObject::get_one("File", "\"Name\" = '" . Convert::raw2sql($name) . "' AND \"ParentID\" = " . (int) $this->ParentID)) {
             $suffix++;
             $name = "{$base}-{$suffix}{$ext}";
         }
     }
     // Update title
     if (!$this->getField('Title')) {
         $this->__set('Title', str_replace(array('-', '_'), ' ', preg_replace('/\\.[^.]+$/', '', $name)));
     }
     // Update actual field value
     $this->setField('Name', $name);
     // Ensure that the filename is updated as well (only in-memory)
     // Important: Circumvent the getter to avoid infinite loops
     $this->setField('Filename', $this->getRelativePath());
     return $this->getField('Name');
 }
 /**
  * Given a temporary file and upload path, validate the file and determine the
  * value of the 'Filename' tuple that should be used to store this asset.
  *
  * @param array $tmpFile
  * @param string $folderPath
  * @return string|false Value of filename tuple, or false if invalid
  */
 protected function getValidFilename($tmpFile, $folderPath = null)
 {
     if (!is_array($tmpFile)) {
         throw new InvalidArgumentException("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype");
     }
     // Validate
     $this->clearErrors();
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // Clean filename
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $filename = basename($file);
     if ($folderPath) {
         $filename = File::join_paths($folderPath, $filename);
     }
     return $filename;
 }
 /**
  * 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)
 {
     if (!is_array($tmpFile)) {
         throw new InvalidArgumentException("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype");
     }
     // Validate
     $this->clearErrors();
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // Clean filename
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $filename = basename($file);
     if ($folderPath) {
         $filename = File::join_paths($folderPath, $filename);
     }
     // Validate filename
     $filename = $this->resolveExistingFile($filename);
     // Save file into backend
     $conflictResolution = $this->replaceFile ? AssetStore::CONFLICT_OVERWRITE : AssetStore::CONFLICT_RENAME;
     $this->file->setFromLocalFile($tmpFile['tmp_name'], $filename, null, null, $conflictResolution);
     // Save changes to underlying record (if it's a DataObject)
     if ($this->file instanceof DataObject) {
         $this->file->write();
     }
     //to allow extensions to e.g. create a version after an upload
     $this->file->extend('onAfterUpload');
     $this->extend('onAfterLoad', $this->file);
     return true;
 }
 /**
  * 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;
     }
 }
 /**
  * Adds a new image to the given product.
  * 
  * @param SilvercartProduct $product           Product to add image to
  * @param string            $filename          Filename
  * @param string            $description       Description
  * @param int               $consecutiveNumber Consecutive number
  */
 protected function addNewImage(SilvercartProduct $product, $filename, $description, $consecutiveNumber)
 {
     $fileEnding = strrev(substr(strrev($filename), 0, strpos(strrev($filename), '.')));
     $nameFilter = FileNameFilter::create();
     $targetFilename = $product->ProductNumberShop . '-' . $nameFilter->filter($product->Title) . '-' . $consecutiveNumber . '.' . $fileEnding;
     $originalFile = self::get_absolute_upload_folder() . '/' . $filename;
     $targetFile = self::get_absolute_product_image_folder() . '/' . $targetFilename;
     $parentFolder = Folder::find_or_make('Uploads/product-images');
     rename($originalFile, $targetFile);
     $image = new Image();
     $image->Name = basename($targetFilename);
     $image->ParentID = $parentFolder->ID;
     $image->write();
     $silvercartImage = new SilvercartImage();
     $silvercartImage->ImageID = $image->ID;
     $silvercartImage->Title = $description;
     $silvercartImage->write();
     $product->SilvercartImages()->add($silvercartImage);
 }
    public function EnquiryForm()
    {
        if (!Email::validEmailAddress($this->EmailTo) || !Email::validEmailAddress($this->EmailFrom)) {
            return false;
        }
        if (!$this->EmailSubject) {
            $this->EmailSubject = 'Website Enquiry';
        }
        $elements = $this->EnquiryFormFields();
        /* empty form, return nothing */
        if ($elements->count() == 0) {
            return false;
        }
        /* Build the fieldlist */
        $fields = FieldList::create();
        $validator = RequiredFields::create();
        $jsValidator = array();
        /* Create filter for possible $_GET parameters / pre-population */
        $get_param_filter = FileNameFilter::create();
        foreach ($elements as $el) {
            $key = $this->keyGen($el->FieldName, $el->SortOrder);
            $field = false;
            $type = false;
            if ($el->FieldType == 'Text') {
                if ($el->FieldOptions == 1) {
                    $field = TextField::create($key, htmlspecialchars($el->FieldName));
                } else {
                    $field = TextareaField::create($key, htmlspecialchars($el->FieldName));
                    $field->setRows($el->FieldOptions);
                }
            } elseif ($el->FieldType == 'Email') {
                $field = EmailField::create($key, htmlspecialchars($el->FieldName));
            } elseif ($el->FieldType == 'Select') {
                $options = preg_split('/\\n\\r?/', $el->FieldOptions, -1, PREG_SPLIT_NO_EMPTY);
                if (count($options) > 0) {
                    $tmp = array();
                    foreach ($options as $o) {
                        $tmp[trim($o)] = trim($o);
                    }
                    $field = DropdownField::create($key, htmlspecialchars($el->FieldName), $tmp);
                    $field->setEmptyString('[ Please Select ]');
                }
            } elseif ($el->FieldType == 'Checkbox') {
                $options = preg_split('/\\n\\r?/', $el->FieldOptions, -1, PREG_SPLIT_NO_EMPTY);
                if (count($options) > 0) {
                    $tmp = array();
                    foreach ($options as $o) {
                        $tmp[trim($o)] = trim($o);
                    }
                    $field = CheckboxSetField::create($key, htmlspecialchars($el->FieldName), $tmp);
                }
            } elseif ($el->FieldType == 'Radio') {
                $options = preg_split('/\\n\\r?/', $el->FieldOptions, -1, PREG_SPLIT_NO_EMPTY);
                if (count($options) > 0) {
                    $tmp = array();
                    foreach ($options as $o) {
                        $tmp[trim($o)] = trim($o);
                    }
                    $field = OptionsetField::create($key, htmlspecialchars($el->FieldName), $tmp);
                }
            } elseif ($el->FieldType == 'Header') {
                if ($el->FieldOptions) {
                    $field = LiteralField::create(htmlspecialchars($el->FieldName), '<h4>' . htmlspecialchars($el->FieldName) . '</h4>
						<p class="note">' . nl2br(htmlspecialchars($el->FieldOptions)) . '</p>');
                } else {
                    $field = HeaderField::create(htmlspecialchars($el->FieldName), 4);
                }
            } elseif ($el->FieldType == 'Note') {
                if ($el->FieldOptions) {
                    $field = LiteralField::create(htmlspecialchars($el->FieldName), '<p class="note">' . nl2br(htmlspecialchars($el->FieldOptions)) . '</p>');
                } else {
                    $field = LiteralField::create(htmlspecialchars($el->FieldName), '<p class="note">' . htmlspecialchars($el->FieldName) . '</p>');
                }
            }
            if ($field) {
                /* Allow $_GET parameters to pre-populate fields */
                $request = $this->request;
                $get_var = $get_param_filter->filter($el->FieldName);
                if (!$request->isPOST() && !$field->Value() && null != $request->getVar($get_var)) {
                    $field->setValue($request->getVar($get_var));
                }
                if ($el->RequiredField == 1) {
                    $field->addExtraClass('required');
                    /* Add "Required" next to field" */
                    $validator->addRequiredField($key);
                    $jsValidator[$key] = $el->FieldType;
                }
                if ($el->PlaceholderText) {
                    $field->setAttribute('placeholder', $el->PlaceholderText);
                }
                $fields->push($field);
            }
        }
        if ($this->AddCaptcha) {
            $label = $this->CaptchaLabel;
            $field = CaptchaField::create('CaptchaImage', $label);
            $field->addExtraClass('required');
            $validator->addRequiredField('CaptchaImage');
            $jsValidator['CaptchaImage'] = 'Text';
            if ($this->CaptchaHelp) {
                $field->setRightTitle('<span id="CaptchaHelp">' . htmlspecialchars($this->CaptchaHelp) . '</span>');
            }
            $fields->push($field);
        }
        $actions = FieldList::create(FormAction::create('SendEnquiryForm', $this->EmailSubmitButtonText));
        if (Config::inst()->get('EnquiryPage', 'js_validation')) {
            Requirements::customScript('var EnquiryFormValidator=' . json_encode($jsValidator) . ';');
            Requirements::javascript(basename(dirname(dirname(__FILE__))) . '/javascript/enquiryform.js');
        }
        $form = Form::create($this, 'EnquiryForm', $fields, $actions, $validator);
        return $form;
    }
 /**
  * Get the sanitised log path.
  * @return string
  */
 public function getSanitisedLogFilePath()
 {
     return $this->basePath . '/' . strtolower(FileNameFilter::create()->filter($this->logFile));
 }
Beispiel #14
0
 /**
  * Determines if a specified file exists
  * 
  * @param SS_HTTPRequest $request
  */
 public function fileexists(SS_HTTPRequest $request)
 {
     // Check both original and safely filtered filename
     $originalFile = $request->requestVar('filename');
     $nameFilter = FileNameFilter::create();
     $filteredFile = basename($nameFilter->filter($originalFile));
     // check if either file exists
     $folder = $this->getFolderName();
     $exists = false;
     foreach (array($originalFile, $filteredFile) as $file) {
         if (file_exists(ASSETS_PATH . "/{$folder}/{$file}")) {
             $exists = true;
             break;
         }
     }
     // Encode and present response
     $response = new SS_HTTPResponse(Convert::raw2json(array('exists' => $exists)));
     $response->addHeader('Content-Type', 'application/json');
     return $response;
 }
Beispiel #15
0
	/**
	 * Take a file uploaded via a POST form, and save it inside this folder.
	 * File names are filtered through {@link FileNameFilter}, see class documentation
	 * on how to influence this behaviour.
	 */
	function addUploadToFolder($tmpFile) {
		if(!is_array($tmpFile)) {
			user_error("Folder::addUploadToFolder() Not passed an array.  Most likely, the form hasn't got the right enctype", E_USER_ERROR);
		}
		if(!isset($tmpFile['size'])) {
			return;
		}
		
		$base = BASE_PATH;
		// $parentFolder = Folder::findOrMake("Uploads");

		// Generate default filename
		$nameFilter = FileNameFilter::create();
		$file = $nameFilter->filter($tmpFile['name']);
		while($file[0] == '_' || $file[0] == '.') {
			$file = substr($file, 1);
		}

		$file = $this->RelativePath . $file;
		Filesystem::makeFolder(dirname("$base/$file"));
		
		$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;

		$i = 1;
		while(file_exists("$base/$file$ext")) {
			$i++;
			$oldFile = $file;
			
			if(strpos($file, '.') !== false) {
				$file = preg_replace('/[0-9]*(\.[^.]+$)/', $i . '\\1', $file);
			} elseif(strpos($file, '_') !== false) {
				$file = preg_replace('/_([^_]+$)/', '_' . $i, $file);
			} else {
				$file .= '_'.$i;
			}

			if($oldFile == $file && $i > 2) user_error("Couldn't fix $file$ext with $i", E_USER_ERROR);
		}
		
		if (move_uploaded_file($tmpFile['tmp_name'], "$base/$file$ext")) {
			// Update with the new image
			return $this->constructChild(basename($file . $ext));
		} else {
			if(!file_exists($tmpFile['tmp_name'])) user_error("Folder::addUploadToFolder: '$tmpFile[tmp_name]' doesn't exist", E_USER_ERROR);
			else user_error("Folder::addUploadToFolder: Couldn't copy '$tmpFile[tmp_name]' to '$base/$file$ext'", E_USER_ERROR);
			return false;
		}
	}
 /**
  * Folder name sanitizer.
  * Checks for valid names and sanitizes
  * against directory traversal.
  * 
  * @param  string $foldername
  * @return string
  */
 public static function sanitize_folder_name($foldername)
 {
     //return $foldername;
     return FileNameFilter::create()->filter(basename($foldername));
 }
 /**
  * File names are filtered through {@link FileNameFilter}, see class documentation
  * on how to influence this behaviour.
  *
  * @deprecated 3.2
  */
 public function loadUploadedImage($tmpFile)
 {
     Deprecation::notice('3.2', 'Use the Upload::loadIntoFile()');
     if (!is_array($tmpFile)) {
         user_error("Image::loadUploadedImage() Not passed an array.  Most likely, the form hasn't got the right" . "enctype", E_USER_ERROR);
     }
     if (!$tmpFile['size']) {
         return;
     }
     $class = $this->class;
     // Create a folder
     if (!file_exists(ASSETS_PATH)) {
         mkdir(ASSETS_PATH, Config::inst()->get('Filesystem', 'folder_create_mask'));
     }
     if (!file_exists(ASSETS_PATH . "/{$class}")) {
         mkdir(ASSETS_PATH . "/{$class}", Config::inst()->get('Filesystem', 'folder_create_mask'));
     }
     // Generate default filename
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     if (!$file) {
         $file = "file.jpg";
     }
     $file = ASSETS_PATH . "/{$class}/{$file}";
     while (file_exists(BASE_PATH . "/{$file}")) {
         $i = $i ? $i + 1 : 2;
         $oldFile = $file;
         $file = preg_replace('/[0-9]*(\\.[^.]+$)/', $i . '\\1', $file);
         if ($oldFile == $file && $i > 2) {
             user_error("Couldn't fix {$file} with {$i}", E_USER_ERROR);
         }
     }
     if (file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], BASE_PATH . "/{$file}")) {
         // Remove the old images
         $this->deleteFormattedImages();
         return true;
     }
 }
Beispiel #18
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;
		}
	}
Beispiel #19
0
 /**
  * Returns a path unique to a specific transfer, including project/environment details.
  * Does not create the path on the filesystem. Can be used to store files related to this transfer.
  *
  * @param DNDataTransfer
  * @return String Absolute file path
  */
 public function generateFilepath(DNDataTransfer $dataTransfer)
 {
     $data = DNData::inst();
     $transferDir = $data->getDataTransferDir();
     $filter = FileNameFilter::create();
     return sprintf('%s/%s/%s/transfer-%s/', $transferDir, $filter->filter(strtolower($this->OriginalEnvironment()->Project()->Name)), $filter->filter(strtolower($this->OriginalEnvironment()->Name)), $dataTransfer->ID);
 }
 /**
  * Generates an actual report file.
  *
  * @param string $format
  */
 public function generateReport($format = 'html')
 {
     $field = strtoupper($format) . 'FileID';
     $storeIn = $this->getReportFolder();
     // SS hates spaces in here :(
     $name = preg_replace('/ +/', '-', trim($this->Title));
     $name = $name . '.' . $format;
     $name = FileNameFilter::create()->filter($name);
     $childId = $storeIn->constructChild($name);
     $file = DataObject::get_by_id('File', $childId);
     // it's a new file, so trigger the onAfterUpload method for extensions that expect it
     if (method_exists($file, 'onAfterUpload')) {
         $file->onAfterUpload();
     }
     // okay, now we should copy across... right?
     $file->setName($name);
     $file->write();
     // create the raw report file
     $output = $this->createReport($format, true);
     if (is_object($output)) {
         if (file_exists($output->filename)) {
             if ($this->config()->store_file_content) {
                 $file->Content = base64_encode(file_get_contents($output->filename));
                 $file->write();
             } else {
                 copy($output->filename, $file->getFullPath());
             }
         }
     }
     // make sure to set the appropriate ID
     $this->{$field} = $file->ID;
     $this->write();
 }
Beispiel #21
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;
     }
 }
 /**
  * Find the given folder or create it both as {@link Folder} database record
  * and on the filesystem. If necessary, creates parent folders as well. If it's
  * unable to find or make the folder, it will return null (as /assets is unable
  * to be represented by a Folder {@link DataObject}).
  *
  * @param string $folderPath    Absolute or relative path to the file.
  *                              If path is relative, it's interpreted relative 
  *                              to the "assets/" directory.
  * @return Folder | null
  */
 public static function find_or_make_secured($folderPath)
 {
     // Create assets directory, if it is missing
     if (!file_exists(ASSETS_PATH)) {
         Filesystem::makeFolder(ASSETS_PATH);
     }
     $folderPath = trim(Director::makeRelative($folderPath));
     // replace leading and trailing slashes
     $folderPath = preg_replace('/^\\/?(.*)\\/?$/', '$1', $folderPath);
     $parts = explode("/", $folderPath);
     $parentID = 0;
     $item = null;
     $filter = FileNameFilter::create();
     foreach ($parts as $part) {
         if (!$part) {
             continue;
             // happens for paths with a trailing slash
         }
         // Ensure search includes folders with illegal characters removed, but
         // err in favour of matching existing folders if $folderPath
         // includes illegal characters itself.
         $partSafe = $filter->filter($part);
         $item = Folder::get()->filter(array('ParentID' => $parentID, 'Name' => array($partSafe, $part), 'CanViewType' => 'Anyone', 'CanEditType' => 'LoggedInUsers'))->first();
         if (!$item) {
             $item = new Folder();
             $item->ParentID = $parentID;
             $item->Name = $partSafe;
             $item->Title = $part;
             $item->Secured = true;
             $item->write();
             // when initial the secured root folder, set its CanViewType to be
             if (!$parentID) {
                 $item->CanViewType = 'Anyone';
                 $item->CanEditType = 'LoggedInUsers';
             }
         }
         if (!file_exists($item->getFullPath())) {
             Filesystem::makeFolder($item->getFullPath());
         }
         $parentID = $item->ID;
     }
     return $item;
 }
Beispiel #23
0
 /**
  * Check if file exists, both checking filtered filename and exact filename
  * 
  * @param string $originalFile Filename
  * @return bool
  */
 protected function checkFileExists($originalFile)
 {
     // Check both original and safely filtered filename
     $nameFilter = FileNameFilter::create();
     $filteredFile = $nameFilter->filter($originalFile);
     // Resolve expected folder name
     $folderName = $this->getFolderName();
     $folder = Folder::find_or_make($folderName);
     $parentPath = $folder ? BASE_PATH . "/" . $folder->getFilename() : ASSETS_PATH . "/";
     // check if either file exists
     return file_exists($parentPath . $originalFile) || file_exists($parentPath . $filteredFile);
 }
 /**
  * Returns the location of the projects key dir if one exists.
  *
  * @return string|null
  */
 public function getKeyDir()
 {
     $keyDir = $this->DNData()->getKeyDir();
     if (!$keyDir) {
         return null;
     }
     $filter = FileNameFilter::create();
     $name = $filter->filter($this->Name);
     return $this->DNData()->getKeyDir() . '/' . $name;
 }
Beispiel #25
0
 /**
  * Setter function for Name. Automatically sets a default title,
  * and removes characters that might be invalid on the filesystem.
  * Also adds a suffix to the name if the filename already exists
  * on the filesystem, and is associated to a different {@link File} database record
  * in the same folder. This means "myfile.jpg" might become "myfile-1.jpg".
  *
  * Does not change the filesystem itself, please use {@link write()} for this.
  *
  * @param String $name
  */
 public function setName($name)
 {
     $oldName = $this->Name;
     // It can't be blank, default to Title
     if (!$name) {
         $name = $this->Title;
     }
     // Fix illegal characters
     $filter = FileNameFilter::create();
     $name = $filter->filter($name);
     // We might have just turned it blank, so check again.
     if (!$name) {
         $name = 'new-folder';
     }
     // If it's changed, check for duplicates
     if ($oldName && $oldName != $name) {
         $base = pathinfo($name, PATHINFO_FILENAME);
         $ext = self::get_file_extension($name);
         $suffix = 1;
         while (File::get()->filter(array('Name' => $name, 'ParentID' => (int) $this->ParentID))->exclude(array('ID' => $this->ID))->first()) {
             $suffix++;
             $name = "{$base}-{$suffix}.{$ext}";
         }
     }
     // Update actual field value
     $this->setField('Name', $name);
     // Ensure that the filename is updated as well (only in-memory)
     // Important: Circumvent the getter to avoid infinite loops
     $this->setField('Filename', $this->getRelativePath());
     // Update title
     if (!$this->Title) {
         $this->Title = str_replace(array('-', '_'), ' ', preg_replace('/\\.[^.]+$/', '', $name));
     }
     return $name;
 }
 /**
  * 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());
     }
 }