public function onBeforeWrite() { parent::onBeforeWrite(); // Create the base folder if (!$this->owner->BaseFolder && $this->owner->Title) { $filter = new FileNameFilter(); $this->owner->BaseFolder = $filter->filter($this->owner->getTitle()); $this->owner->BaseFolder = str_replace(' ', '', ucwords(str_replace('-', ' ', $this->owner->BaseFolder))); } // If name has changed, rename existing groups $changes = $this->owner->getChangedFields(); if (isset($changes['Title']) && !empty($changes['Title']['before'])) { $filter = new URLSegmentFilter(); $groupName = $this->getAdministratorGroupName($changes['Title']['before']); $group = self::getGroupByName($groupName); if ($group) { $group->Title = $this->getAdministratorGroupName($changes['Title']['after']); $group->Code = $filter->filter($group->Title); $group->write(); } $membersGroupName = $this->getMembersGroupName($changes['Title']['before']); $membersGroup = self::getGroupByName($membersGroupName); if ($membersGroup) { $membersGroup->Title = $this->getMembersGroupName($changes['Title']['after']); $membersGroup->Code = $filter->filter($membersGroup->Title); $membersGroup->write(); } } }
function testFilterWithEmptyString() { $name = 'ö ö ö.jpg'; $filter = new FileNameFilter(); $result = $filter->filter($name); $this->assertFalse(empty($result)); $this->assertStringEndsWith('.jpg', $result); $this->assertGreaterThan(strlen('.jpg'), strlen($result)); }
public function run($request) { $filesWithSpaces = File::get()->where('"Filename" LIKE \'% %\''); $filter = new FileNameFilter(); foreach ($filesWithSpaces as $file) { DB::alteration_message("Updating file #" . $file->ID . " with filename " . $file->Filename); $parts = explode('/', $file->Filename); $filtered = array_map(function ($item) use($filter) { return $filter->filter($item); }, $parts); $file->Filename = implode('/', $filtered); $file->write(); } DB::alteration_message("All done!"); }
/** * 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; }
/** * 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; }
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 = ''; } } }
function checkFolder() { if (!$this->exists()) { return; } if (!$this->URLSegment) { return; } $baseFolder = ''; if (class_exists('Subsite') && self::config()->use_subsite_integration) { if ($this->SubsiteID) { $subsite = $this->Subsite(); if ($subsite->hasField('BaseFolder')) { $baseFolder = $subsite->BaseFolder; } else { $filter = new FileNameFilter(); $baseFolder = $filter->filter($subsite->getTitle()); $baseFolder = str_replace(' ', '', ucwords(str_replace('-', ' ', $baseFolder))); } $baseFolder .= '/'; } } $folderPath = $baseFolder . "galleries/{$this->URLSegment}"; $folder = Folder::find_or_make($folderPath); if ($this->RootFolderID && $folder->ID != $this->RootFolderID) { if ($this->RootFolder()->exists()) { // We need to rename current folder $this->RootFolder()->setFilename($folder->Filename); $this->RootFolder()->write(); $folder->deleteDatabaseOnly(); //Otherwise we keep a stupid clone that will be used as the parent } else { $this->RootFolderID = $folder->ID; } } else { $this->RootFolderID = $folder->ID; } }
/** * 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); } }
/** * 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; } }
/** * 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; } }
/** * 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; }
/** * Generate export fields for Excel. * * @param GridField $gridField * @return PHPExcel */ public function generateExportFileData($gridField) { $class = $gridField->getModelClass(); $columns = $this->exportColumns ? $this->exportColumns : ExcelImportExport::exportFieldsForClass($class); $fileData = ''; $singl = singleton($class); $singular = $class ? $singl->i18n_singular_name() : ''; $plural = $class ? $singl->i18n_plural_name() : ''; $filter = new FileNameFilter(); if ($this->exportName) { $this->exportName = $filter->filter($this->exportName); } else { $this->exportName = $filter->filter('export-' . $plural); } $excel = new PHPExcel(); $excelProperties = $excel->getProperties(); $excelProperties->setTitle($this->exportName); $sheet = $excel->getActiveSheet(); if ($plural) { $sheet->setTitle($plural); } $row = 1; $col = 0; if ($this->hasHeader) { $headers = array(); // determine the headers. If a field is callable (e.g. anonymous function) then use the // source name as the header instead foreach ($columns as $columnSource => $columnHeader) { $headers[] = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; } foreach ($headers as $header) { $sheet->setCellValueByColumnAndRow($col, $row, $header); $col++; } $endcol = PHPExcel_Cell::stringFromColumnIndex($col - 1); $sheet->setAutoFilter("A1:{$endcol}1"); $sheet->getStyle("A1:{$endcol}1")->getFont()->setBold(true); $col = 0; $row++; } // Autosize $cellIterator = $sheet->getRowIterator()->current()->getCellIterator(); try { $cellIterator->setIterateOnlyExistingCells(true); } catch (Exception $ex) { continue; } foreach ($cellIterator as $cell) { $sheet->getColumnDimension($cell->getColumn())->setAutoSize(true); } //Remove GridFieldPaginator as we're going to export the entire list. $gridField->getConfig()->removeComponentsByType('GridFieldPaginator'); $items = $gridField->getManipulatedList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } foreach ($items->limit(null) as $item) { if (!$item->hasMethod('canView') || $item->canView()) { foreach ($columns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); if ($value === null) { $value = $gridField->getDataFieldValue($item, $columnHeader); } } $value = str_replace(array("\r", "\n"), "\n", $value); $sheet->setCellValueByColumnAndRow($col, $row, $value); $col++; } } if ($item->hasMethod('destroy')) { $item->destroy(); } $col = 0; $row++; } return $excel; }
/** * Get a random image * @return Image */ public static function image() { $images = DataObject::get('Image', "Filename LIKE 'assets/Faker/%'"); if (!count($images)) { $rss = file_get_contents(self::$imageRss); $xml = simplexml_load_string($rss); $nodes = $xml->xpath("//image"); $i = 0; $folder = Folder::find_or_make('Faker'); $dir = $folder->getFullPath(); $filter = new FileNameFilter(); foreach ($nodes as $node) { $i++; $image = file_get_contents((string) $node->url); $filename = $dir . '/' . basename($filter->filter((string) $node->title) . '.jpg'); file_put_contents($filename, $image); } $folder->syncChildren(); $images = DataObject::get('Image', "Filename LIKE 'assets/Faker/%'"); } $rand = rand(0, count($images)); foreach ($images as $key => $image) { if ($key == $rand) { return $image; } } return $images->First(); }
/** * Send the email through mandrill * * @param string|array $to * @param string $from * @param string $subject * @param string $plainContent * @param array $attachedFiles * @param array $customheaders * @param bool $inlineImages * @return array|bool */ protected function send($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false, $plainContent = false, $inlineImages = false) { $original_to = $to; // Process recipients $to_array = array(); $to_array = $this->appendTo($to_array, $to, 'to'); if (isset($customheaders['Cc'])) { $to_array = $this->appendTo($to_array, $customheaders['Cc'], 'cc'); unset($customheaders['Cc']); } if (isset($customheaders['Bcc'])) { $to_array = $this->appendTo($to_array, $customheaders['Bcc'], 'bcc'); unset($customheaders['Bcc']); } // Process sender $fromArray = $this->processRecipient($from); $fromEmail = $fromArray['email']; $fromName = $fromArray['name']; // Create params to send to mandrill message api $default_params = array(); if (self::getDefaultParams()) { $default_params = self::getDefaultParams(); } $params = array_merge($default_params, array("subject" => $subject, "from_email" => $fromEmail, "to" => $to_array)); if ($fromName) { $params['from_name'] = $fromName; } // Inject additional params into message if (isset($customheaders['X-MandrillMailer'])) { $params = array_merge($params, $customheaders['X-MandrillMailer']); unset($customheaders['X-MandrillMailer']); } if ($plainContent) { $params['text'] = $plainContent; } if ($htmlContent) { $params['html'] = $htmlContent; } // Attach tags to params if (self::getGlobalTags()) { if (!isset($params['tags'])) { $params['tags'] = array(); } $params['tags'] = array_merge($params['tags'], self::getGlobalTags()); } // Attach subaccount to params if (self::getSubaccount()) { $params['subaccount'] = self::getSubaccount(); } $bcc_email = Config::inst()->get('Email', 'bcc_all_emails_to'); if ($bcc_email) { if (is_string($bcc_email)) { $params['bcc_address'] = $bcc_email; } } // Google analytics domains if (self::getUseGoogleAnalytics() && !Director::isDev()) { if (!isset($params['google_analytics_domains'])) { // Compute host $host = str_replace(Director::protocol(), '', Director::protocolAndHost()); // Define in params $params['google_analytics_domains'] = array($host); } } // Handle files attachments if ($attachedFiles) { $attachments = array(); // Include any specified attachments as additional parts foreach ($attachedFiles as $file) { if (isset($file['tmp_name']) && isset($file['name'])) { $attachments[] = $this->encodeFileForEmail($file['tmp_name'], $file['name']); } else { $attachments[] = $this->encodeFileForEmail($file); } } $params['attachments'] = $attachments; } if ($customheaders) { $params['headers'] = $customheaders; } if (self::getEnableLogging()) { // Append some extra information at the end $logContent = $htmlContent; $logContent .= '<pre>'; $logContent .= 'To : ' . print_r($original_to, true) . "\n"; $logContent .= 'Subject : ' . $subject . "\n"; $logContent .= 'Headers : ' . print_r($customheaders, true) . "\n"; if (!empty($params['from_email'])) { $logContent .= 'From email : ' . $params['from_email'] . "\n"; } if (!empty($params['from_name'])) { $logContent .= 'From name : ' . $params['from_name'] . "\n"; } if (!empty($params['to'])) { $logContent .= 'Recipients : ' . print_r($params['to'], true) . "\n"; } $logContent .= '</pre>'; // Store it $logFolder = BASE_PATH . '/' . self::getLogFolder(); if (!is_dir($logFolder)) { mkdir($logFolder, 0777, true); } $filter = new FileNameFilter(); $title = substr($filter->filter($subject), 0, 20); $r = file_put_contents($logFolder . '/' . time() . '-' . $title . '.html', $logContent); if (!$r) { throw new Exception('Failed to store email in ' . $logFolder); } } if (self::getSendingDisabled()) { $customheaders['X-SendingDisabled'] = true; return array($original_to, $subject, $htmlContent, $customheaders); } try { $ret = $this->getMandrill()->messages->send($params); } catch (Exception $ex) { $ret = array(array('status' => 'rejected', 'reject_reason' => $ex->getMessage())); } $this->last_result = $ret; $sent = 0; $failed = 0; $reasons = array(); if ($ret) { foreach ($ret as $result) { if (in_array($result['status'], array('rejected', 'invalid'))) { $failed++; if (!empty($result['reject_reason'])) { $reasons[] = $result['reject_reason']; } else { if ($result['status'] == 'invalid') { $reasons[] = 'Email "' . $result['email'] . '" is invalid'; } } continue; } $sent++; } } if ($sent) { $this->last_is_error = false; return array($original_to, $subject, $htmlContent, $customheaders); } else { $this->last_is_error = true; $this->last_error = $ret; SS_Log::log("Failed to send {$failed} emails", SS_Log::DEBUG); foreach ($reasons as $reason) { SS_Log::log("Failed to send because: {$reason}", SS_Log::DEBUG); } return false; } }
/** * 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); }
public function testDuplicateDashesRemoved() { $name = 'test--document.txt'; $filter = new FileNameFilter(); $this->assertEquals('test-document.txt', $filter->filter($name)); }
/** * 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; }
/** * 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; } }
/** * 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; } }
/** * 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; } }
/** * 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(); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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; }