/**
  * Run through the rules for this validator checking against
  * the temporary file set by {@link setTmpFile()} to see if
  * the file is deemed valid or not.
  * 
  * @return boolean
  */
 public function validate()
 {
     // we don't validate for empty upload fields yet
     if (!isset($this->tmpFile['name']) || empty($this->tmpFile['name'])) {
         return true;
     }
     $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
     //needed to allow XHR uploads
     /*if(isset($this->tmpFile['tmp_name']) && !is_uploaded_file($this->tmpFile['tmp_name']) && !$isRunningTests) {
     			$this->errors[] = _t('File.NOVALIDUPLOAD', 'File is not a valid upload');
     			return false;
     		}*/
     $pathInfo = pathinfo($this->tmpFile['name']);
     // filesize validation
     if (!$this->isValidSize()) {
         $ext = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
         $arg = File::format_size($this->getAllowedMaxFileSize($ext));
         $this->errors[] = sprintf(_t('File.TOOLARGE', 'Filesize is too large, maximum %s allowed.', PR_MEDIUM, 'Argument 1: Filesize (e.g. 1MB)'), $arg);
         return false;
     }
     // extension validation
     if (!$this->isValidExtension()) {
         $this->errors[] = sprintf(_t('File.INVALIDEXTENSION', 'Extension is not allowed (valid: %s)', PR_MEDIUM, 'Argument 1: Comma-separated list of valid extensions'), wordwrap(implode(', ', $this->allowedExtensions)));
         return false;
     }
     return true;
 }
Example #2
0
 /**
  * Test the File::format_size() method
  */
 function testFormatSize()
 {
     $this->assertEquals("1000 bytes", File::format_size(1000));
     $this->assertEquals("1023 bytes", File::format_size(1023));
     $this->assertEquals("1 KB", File::format_size(1025));
     $this->assertEquals("9.8 KB", File::format_size(10000));
     $this->assertEquals("49 KB", File::format_size(50000));
     $this->assertEquals("977 KB", File::format_size(1000000));
     $this->assertEquals("1 MB", File::format_size(1024 * 1024));
     $this->assertEquals("954 MB", File::format_size(1000000000));
     $this->assertEquals("1 GB", File::format_size(1024 * 1024 * 1024));
     $this->assertEquals("9.3 GB", File::format_size(10000000000.0));
     // It use any denomination higher than GB.  It also doesn't overflow with >32 bit integers
     $this->assertEquals("93132.3 GB", File::format_size(100000000000000.0));
 }
 public function Field($properties = array())
 {
     Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js');
     Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/javascript/lang');
     // Avoid conflicts
     Requirements::block(FRAMEWORK_DIR . '/javascript/UploadField_uploadtemplate.js');
     Requirements::block(FRAMEWORK_DIR . '/javascript/UploadField_downloadtemplate.js');
     Requirements::block(FRAMEWORK_DIR . '/javascript/UploadField.js');
     Requirements::combine_files('frontenduploadfield.js', array(THIRDPARTY_DIR . '/javascript-templates/tmpl.js', THIRDPARTY_DIR . '/javascript-loadimage/load-image.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.iframe-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/cors/jquery.xdr-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload-ui.js', FORM_EXTRAS_PATH . '/javascript/uploadfield/FrontendUploadField_uploadtemplate.js', FORM_EXTRAS_PATH . '/javascript/uploadfield/FrontendUploadField_downloadtemplate.js', FORM_EXTRAS_PATH . '/javascript/uploadfield/FrontendUploadField.js'));
     Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
     // TODO hmmm, remove it?
     Requirements::css(FRAMEWORK_DIR . '/css/UploadField.css');
     // Calculated config as per jquery.fileupload-ui.js
     $allowedMaxFileNumber = $this->getAllowedMaxFileNumber();
     $config = array('url' => $this->Link('upload'), 'urlSelectDialog' => $this->Link('select'), 'urlAttach' => $this->Link('attach'), 'urlFileExists' => $this->link('fileexists'), 'acceptFileTypes' => '.+$', 'maxNumberOfFiles' => $allowedMaxFileNumber ? $allowedMaxFileNumber - count($this->getItemIDs()) : null);
     // Validation: File extensions
     if ($allowedExtensions = $this->getAllowedExtensions()) {
         $config['acceptFileTypes'] = '(\\.|\\/)(' . implode('|', $allowedExtensions) . ')$';
         $config['errorMessages']['acceptFileTypes'] = _t('File.INVALIDEXTENSIONSHORT', 'Extension is not allowed');
     }
     // Validation: File size
     if ($allowedMaxFileSize = $this->getValidator()->getAllowedMaxFileSize()) {
         $config['maxFileSize'] = $allowedMaxFileSize;
         $config['errorMessages']['maxFileSize'] = _t('File.TOOLARGESHORT', 'Filesize exceeds {size}', array('size' => File::format_size($config['maxFileSize'])));
     }
     // Validation: Number of files
     if ($allowedMaxFileNumber) {
         if ($allowedMaxFileNumber > 1) {
             $config['errorMessages']['maxNumberOfFiles'] = _t('UploadField.MAXNUMBEROFFILESSHORT', 'Can only upload {count} files', array('count' => $allowedMaxFileNumber));
         } else {
             $config['errorMessages']['maxNumberOfFiles'] = _t('UploadField.MAXNUMBEROFFILESONE', 'Can only upload one file');
         }
     }
     //get all the existing files in the current folder
     if ($this->getOverwriteWarning()) {
         //add overwrite warning error message to the config object sent to Javascript
         $config['errorMessages']['overwriteWarning'] = _t('UploadField.OVERWRITEWARNING', 'File with the same name already exists');
     }
     $mergedConfig = array_merge($config, $this->ufConfig);
     return $this->customise(array('configString' => str_replace('"', """, Convert::raw2json($mergedConfig)), 'config' => new ArrayData($mergedConfig), 'multiple' => $allowedMaxFileNumber !== 1))->renderWith($this->getTemplates());
 }
Example #4
0
 public function Field($properties = array())
 {
     $record = $this->getRecord();
     $name = $this->getName();
     // if there is a has_one relation with that name on the record and
     // allowedMaxFileNumber has not been set, it's wanted to be 1
     if ($record && $record->exists() && $record->has_one($name) && !$this->getConfig('allowedMaxFileNumber')) {
         $this->setConfig('allowedMaxFileNumber', 1);
     }
     Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
     Requirements::javascript(FRAMEWORK_DIR . '/javascript/i18n.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js');
     Requirements::combine_files('uploadfield.js', array(THIRDPARTY_DIR . '/javascript-templates/tmpl.js', THIRDPARTY_DIR . '/javascript-loadimage/load-image.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.iframe-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/cors/jquery.xdr-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload-ui.js', FRAMEWORK_DIR . '/javascript/UploadField_uploadtemplate.js', FRAMEWORK_DIR . '/javascript/UploadField_downloadtemplate.js', FRAMEWORK_DIR . '/javascript/UploadField.js'));
     Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
     // Requirements::javascript('gallery/javascript/GalleryUploadField.js');
     Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
     // TODO hmmm, remove it?
     Requirements::css(FRAMEWORK_DIR . '/css/UploadField.css');
     // Requirements::css('gallery/css/GalleryUploadField.css');
     $allowedMaxFileNumber = $this->getAllowedMaxFileNumber();
     $config = array('url' => $this->Link('upload'), 'urlSelectDialog' => $this->Link('select'), 'urlAttach' => $this->Link('attach'), 'urlSort' => $this->Link('sort'), 'urlFileExists' => $this->link('fileexists'), 'acceptFileTypes' => '.+$', 'maxNumberOfFiles' => $allowedMaxFileNumber ? $allowedMaxFileNumber - count($this->getItemIDs()) : null);
     if (count($this->getValidator()->getAllowedExtensions())) {
         $allowedExtensions = $this->getValidator()->getAllowedExtensions();
         $config['acceptFileTypes'] = '(\\.|\\/)(' . implode('|', $allowedExtensions) . ')$';
         $config['errorMessages']['acceptFileTypes'] = _t('File.INVALIDEXTENSIONSHORT', 'Extension is not allowed');
     }
     if ($this->getValidator()->getAllowedMaxFileSize()) {
         $config['maxFileSize'] = $this->getValidator()->getAllowedMaxFileSize();
         $config['errorMessages']['maxFileSize'] = _t('File.TOOLARGESHORT', 'Filesize exceeds {size}', array('size' => File::format_size($config['maxFileSize'])));
     }
     if ($config['maxNumberOfFiles'] > 1) {
         $config['errorMessages']['maxNumberOfFiles'] = _t('UploadField.MAXNUMBEROFFILESSHORT', 'Can only upload {count} files', array('count' => $config['maxNumberOfFiles']));
     }
     $configOverwrite = array();
     if (is_numeric($config['maxNumberOfFiles']) && $this->getItems()->count()) {
         $configOverwrite['maxNumberOfFiles'] = $config['maxNumberOfFiles'] - $this->getItems()->count();
     }
     $config = array_merge($config, $this->ufConfig, $configOverwrite);
     return $this->customise(array('configString' => str_replace('"', """, Convert::raw2json($config)), 'config' => new ArrayData($config), 'multiple' => $config['maxNumberOfFiles'] !== 1, 'displayInput' => !isset($configOverwrite['maxNumberOfFiles']) || $configOverwrite['maxNumberOfFiles']))->renderWith($this->getTemplates());
 }
 /**
  * optimize a single image and return a
  * json array
  * @return json
  */
 public function optimizeImage()
 {
     $krakenService = new KrakenService();
     $response = array();
     if ($this->owner->request->getVar('ID') >= 1) {
         $image = Image::get()->byID(intval($this->owner->request->getVar('ID')));
     }
     //check if a file path was supplied
     if ($image) {
         //optimize this image
         if (!$image->Kraked) {
             $data = $krakenService->optimizeImage($image->getFullPath());
             //check if optimization was success
             if ($data['success'] && $data['saved_bytes'] >= 0) {
                 //attempt to download the kraked file
                 $krakedFile = $krakenService->getOptimizedImage($data['kraked_url']);
                 //update the file
                 if ($krakedFile) {
                     file_put_contents($image, $krakedFile);
                     $image->Kraked = true;
                     $image->write();
                     $response['Name'] = $data['file_name'];
                     $response['UnoptimizedSize'] = File::format_size($data['original_size']);
                     $response['OptimizedSize'] = File::format_size($data['kraked_size']);
                 }
             }
         }
         $resizedImageCount = $this->optimizeFormattedImages($image);
         $response['FormattedImagesMessage'] = "Optimzed {$resizedImageCount} formatted images";
         if (Director::is_ajax()) {
             return json_encode($response);
         } else {
             $message = _t('Kraken.OPTIMIZED', '_Optimized');
             $this->owner->getResponse()->addHeader('X-Status', rawurlencode($message));
             return;
         }
     }
 }
Example #6
0
 /**
  * Generate a human friendly reprensetation of the size of this S3file
  * @return string
  */
 public function getSizeForHuman()
 {
     return File::format_size($this->Size);
 }
 /**
  * @return bool|string
  */
 public function getSize()
 {
     return $this->FileSize ? File::format_size($this->FileSize) : false;
 }
 /**
  * Returns the size of the file type in an appropriate format.
  *
  * @return string|false String value, or false if doesn't exist
  */
 public function getSize()
 {
     $size = $this->getAbsoluteSize();
     if ($size) {
         return \File::format_size($size);
     }
     return false;
 }
Example #9
0
	/**
	 * Container for all validation on the file
	 * (e.g. size and extension restrictions).
	 * Is NOT connected to the {Validator} classes,
	 * please have a look at {FileField->validate()}
	 * for an example implementation of external validation.
	 *
	 * @param array $tmpFile
	 * @return boolean
	 */
	public function validate($tmpFile) {
		// we don't validate for empty upload fields yet
		if(!isset($tmpFile['name']) || empty($tmpFile['name'])) return true;

		$pathInfo = pathinfo($tmpFile['name']);
		// filesize validation
		if(!$this->isValidSize($tmpFile)) {
			$this->errors[] = sprintf(
				_t(
					'File.TOOLARGE', 
					'Filesize is too large, maximum %s allowed.',
					PR_MEDIUM,
					'Argument 1: Filesize (e.g. 1MB)'
				),
				File::format_size($this->getAllowedMaxFileSize($pathInfo['extension']))
			);
			return false;
		}

		// extension validation
		if(!$this->isValidExtension($tmpFile)) {
			$this->errors[] = sprintf(
				_t(
					'File.INVALIDEXTENSION', 
					'Extension is not allowed (valid: %s)',
					PR_MEDIUM,
					'Argument 1: Comma-separated list of valid extensions'
				),
				implode(',',$this->allowedExtensions)
			);
			return false;
		}
		
		return true;
	}
Example #10
0
 /**
  * Return the upload limit for snapshot uploads
  * @return string
  */
 public function UploadLimit()
 {
     return File::format_size(min(File::ini2bytes(ini_get('upload_max_filesize')), File::ini2bytes(ini_get('post_max_size'))));
 }
Example #11
0
 function getSize()
 {
     $size = $this->getAbsoluteSize();
     return $size ? File::format_size($size) : false;
 }
 public function Size()
 {
     $size = $this->owner->FileSize;
     return $size ? File::format_size($size) : false;
 }
Example #13
0
 /**
  * Action
  * 
  * @return string - HTML
  */
 public function uploadsnapshot(SS_HTTPRequest $request)
 {
     // Performs canView permission check by limiting visible projects
     $project = $this->getCurrentProject();
     if (!$project) {
         return new SS_HTTPResponse("Project '" . Convert::raw2xml($request->latestParam('Project')) . "' not found.", 404);
     }
     if (!$project->canUploadArchive()) {
         return new SS_HTTPResponse("Not allowed to upload", 401);
     }
     return $this->customise(array('Project' => $project, 'CurrentProject' => $project, 'SnapshotsSection' => 1, 'UploadLimit' => $maxSize = File::format_size(min(File::ini2bytes(ini_get('upload_max_filesize')), File::ini2bytes(ini_get('post_max_size')))), 'UploadSnapshotForm' => $this->getUploadSnapshotForm($request), 'PostSnapshotForm' => $this->getPostSnapshotForm($request)))->renderWith(array('DNRoot_uploadsnapshot', 'DNRoot'));
 }
 /**
  * Run through the rules for this validator checking against
  * the temporary file set by {@link setTmpFile()} to see if
  * the file is deemed valid or not.
  *
  * @return boolean
  */
 public function validate()
 {
     // we don't validate for empty upload fields yet
     if (empty($this->tmpFile['name'])) {
         return true;
     }
     // Check file upload
     if (!$this->isValidUpload()) {
         $this->errors[] = _t('File.NOVALIDUPLOAD', 'File is not a valid upload');
         return false;
     }
     // Check file isn't empty
     if ($this->isFileEmpty()) {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
     // filesize validation
     if (!$this->isValidSize()) {
         $pathInfo = pathinfo($this->tmpFile['name']);
         $ext = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
         $arg = File::format_size($this->getAllowedMaxFileSize($ext));
         $this->errors[] = _t('File.TOOLARGE', 'Filesize is too large, maximum {size} allowed', 'Argument 1: Filesize (e.g. 1MB)', array('size' => $arg));
         return false;
     }
     // extension validation
     if (!$this->isValidExtension()) {
         $this->errors[] = _t('File.INVALIDEXTENSION_SHORT', 'Extension is not allowed');
         return false;
     }
     return true;
 }
 /**
  * Looser check validation that doesn't do is_upload_file()
  * checks as we're faking a POST request that PHP didn't generate
  * itself.
  *
  * @return boolean
  */
 public function validate()
 {
     $pathInfo = pathinfo($this->tmpFile['name']);
     // filesize validation
     if (!$this->isValidSize()) {
         $ext = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
         $arg = File::format_size($this->getAllowedMaxFileSize($ext));
         $this->errors[] = _t('File.TOOLARGE', 'Filesize is too large, maximum {size} allowed', 'Argument 1: Filesize (e.g. 1MB)', array('size' => $arg));
         return false;
     }
     // extension validation
     if (!$this->isValidExtension()) {
         $this->errors[] = _t('File.INVALIDEXTENSION', 'Extension is not allowed (valid: {extensions})', 'Argument 1: Comma-separated list of valid extensions', array('extensions' => implode(',', $this->allowedExtensions)));
         return false;
     }
     return true;
 }
 public function Field($properties = array())
 {
     Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js');
     Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/dist/ssui.core.js');
     Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/javascript/lang');
     Requirements::combine_files('uploadfield.js', array(THIRDPARTY_DIR . '/javascript-templates/tmpl.js', THIRDPARTY_DIR . '/javascript-loadimage/load-image.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.iframe-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/cors/jquery.xdr-transport.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload.js', THIRDPARTY_DIR . '/jquery-fileupload/jquery.fileupload-ui.js', FRAMEWORK_DIR . '/javascript/dist/UploadField_uploadtemplate.js', FRAMEWORK_DIR . '/javascript/dist/UploadField_downloadtemplate.js', FRAMEWORK_DIR . '/javascript/dist/UploadField.js'));
     Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
     // TODO hmmm, remove it?
     Requirements::css(FRAMEWORK_DIR . '/css/UploadField.css');
     // Calculated config as per jquery.fileupload-ui.js
     $config = array('allowedMaxFileNumber' => 1, 'url' => $this->Link('upload'), 'urlSelectDialog' => $this->Link('select'), 'urlAttach' => $this->Link('attach'), 'urlFileExists' => $this->link('fileexists'), 'acceptFileTypes' => '.+$', 'maxNumberOfFiles' => $this->Value() ? 0 : 1, 'replaceFile' => false);
     // Validation: File extensions
     if ($allowedExtensions = $this->getAllowedExtensions()) {
         $config['acceptFileTypes'] = '(\\.|\\/)(' . implode('|', $allowedExtensions) . ')$';
         $config['errorMessages']['acceptFileTypes'] = _t('File.INVALIDEXTENSIONSHORT', 'Extension is not allowed');
     }
     // Validation: File size
     if ($allowedMaxFileSize = $this->getValidator()->getAllowedMaxFileSize()) {
         $config['maxFileSize'] = $allowedMaxFileSize;
         $config['errorMessages']['maxFileSize'] = _t('File.TOOLARGESHORT', 'Filesize exceeds {size}', array('size' => File::format_size($config['maxFileSize'])));
     }
     $mergedConfig = array_merge($config, $this->ufConfig);
     return $this->customise(array('ConfigString' => Convert::raw2json($mergedConfig), 'UploadFieldFileButtons' => $this->renderWith($this->getTemplateFileButtons())))->renderWith($this->getTemplates());
 }
 /**
  * Run through the rules for this validator checking against
  * the temporary file set by {@link setTmpFile()} to see if
  * the file is deemed valid or not.
  *
  * @return boolean
  */
 public function validate()
 {
     // we don't validate for empty upload fields yet
     if (empty($this->tmpFile['name']) || empty($this->tmpFile['tmp_name'])) {
         return true;
     }
     $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
     if (isset($this->tmpFile['tmp_name']) && !is_uploaded_file($this->tmpFile['tmp_name']) && !$isRunningTests) {
         $this->errors[] = _t('File.NOVALIDUPLOAD', 'File is not a valid upload');
         return false;
     }
     // Check file isn't empty
     if (empty($this->tmpFile['size']) || !filesize($this->tmpFile['tmp_name'])) {
         $this->errors[] = _t('File.NOFILESIZE', 'Filesize is zero bytes.');
         return false;
     }
     $pathInfo = pathinfo($this->tmpFile['name']);
     // filesize validation
     if (!$this->isValidSize()) {
         $ext = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
         $arg = File::format_size($this->getAllowedMaxFileSize($ext));
         $this->errors[] = _t('File.TOOLARGE', 'Filesize is too large, maximum {size} allowed', 'Argument 1: Filesize (e.g. 1MB)', array('size' => $arg));
         return false;
     }
     // extension validation
     if (!$this->isValidExtension()) {
         $this->errors[] = _t('File.INVALIDEXTENSION', 'Extension is not allowed (valid: {extensions})', 'Argument 1: Comma-separated list of valid extensions', array('extensions' => wordwrap(implode(', ', $this->allowedExtensions))));
         return false;
     }
     return true;
 }
 public function getSize()
 {
     if ($this->size) {
         return File::format_size($this->size);
     }
     parent::getSize();
 }
 public function updateCMSFields(FieldList $fields)
 {
     if ($this->classHasAdvertisements($this->owner->ClassName)) {
         $tabName = $this->MyTabName();
         //advertisements shown...
         $where = '1 = 1';
         if ($this->owner->AdvertisementsFolderID) {
             $images = Image::get()->filter("ParentID", $this->owner->AdvertisementsFolderID);
             if ($images->count()) {
                 $where = "\"AdvertisementImageID\" IN (" . implode(",", $images->column("ID")) . ")";
             } else {
                 $where = " 1 = 2";
             }
         }
         //$advertisementsCount = DB::query("SELECT COUNT(ID) FROM \"Advertisement\" $whereDB ;")->value();
         $advertisements = $this->owner->Advertisements()->where($where);
         $txt = sprintf(_t("AdvertisementDecorator.ACTUAL", 'Current %1$s Shown'), Config::inst()->get("Advertisement", "plural_name"));
         $fields->addFieldToTab($tabName, $this->MyHeaderField($txt));
         $txt = sprintf(_t("AdvertisementDecorator.SELECT", 'Select %1$s to show ... '), Config::inst()->get("Advertisement", "plural_name"));
         $advertisementsGridField = new GridField('Advertisements', $txt, $this->owner->Advertisements(), GridFieldConfig_RelationEditor::create());
         $fields->addFieldToTab($tabName, $advertisementsGridField);
         if (Config::inst()->get("Advertisement", "resize_images") == 'no') {
             $totalSize = 0;
             foreach ($this->owner->Advertisements() as $advertisement) {
                 $totalSize += $advertisement->AdvertisementImage()->getAbsoluteSize();
             }
             $seconds = round(($totalSize + 1) / 524288);
             $fields->addFieldToTab($tabName, new LiteralField("TotalSize", '<p><em>Total download size: ' . File::format_size($totalSize) . ', good reception 3G network download time less than ~' . ($seconds + 1) . ' seconds.</em></p>'));
         }
         if (class_exists("DataObjectSorterController")) {
             $shownAdvertisements = $this->owner->getManyManyComponents('Advertisements');
             if ($shownAdvertisements) {
                 $array = $shownAdvertisements->column("ID");
                 $idString = implode(",", $array);
                 $link = DataObjectSorterController::popup_link("Advertisement", $filterField = "ID", $filterValue = $idString, $linkText = "sort " . Config::inst()->get("Advertisement", "plural_name"), $titleField = "FullTitle");
                 $fields->addFieldToTab($tabName, new LiteralField("AdvertisementsSorter", $link));
             }
         }
         if ($advertisements->count()) {
         } else {
             $txt = sprintf(_t("AdvertisementDecorator.CREATE", '<p>Please <a href="admin/%1$s/">create %2$s</a> on the <a href="admin/%1$s/">%3$s tab</a> first, or see below on how to create %2$s from a folder.</p>'), Config::inst()->get("AdvertisementAdmin", "url_segment"), Config::inst()->get("Advertisement", "plural_name"), Config::inst()->get("AdvertisementAdmin", "menu_title"));
             $fields->addFieldToTab($tabName, new LiteralField("AdvertisementsHowToCreate", $txt));
         }
         if ($parent = $this->advertisementParent()) {
             $txt = sprintf(_t("AdvertisementDecorator.ORUSE", 'OR  ... use %1$s from  <i>%2$s</i>.'), Config::inst()->get("Advertisement", "plural_name"), $parent->Title);
             $fields->addFieldToTab($tabName, new CheckboxField("UseParentAdvertisements", $txt));
         }
         //create new advertisements
         $txt = sprintf(_t("AdvertisementDecorator.CREATE", 'Create new %1$s'), Config::inst()->get("Advertisement", "plural_name"));
         $fields->addFieldToTab($tabName, $this->MyHeaderField($txt));
         $txt = sprintf(_t("AdvertisementDecorator.CREATENEWFROMFOLDER_EXPLANATION", 'Create New %1$s from images in the folder selected - each image in the folder will be used to create a %3$s. %2$s'), Config::inst()->get("Advertisement", "plural_name"), Advertisement::recommended_image_size_statement(), Config::inst()->get("Advertisement", "singular_name"));
         if (Folder::get()->count()) {
             $fields->addFieldToTab($tabName, $treeDropdownField = new TreeDropdownField('AdvertisementsFolderID', _t("AdvertisementDecorator.CREATENEWFROMFOLDER", "Create from folder"), 'Folder'));
             $treeDropdownField->setRightTitle($txt);
         }
         $styles = AdvertisementStyle::get();
         if ($styles->count()) {
             $fields->addFieldToTab($tabName, $this->MyHeaderField("Style"));
             $list = $styles->map("ID", "Title", $emptyString = _t("AdvertisementDecorator.SELECTSTYLE", "--select style--"), $sortByTitle = true);
             $fields->addFieldToTab($tabName, $selectStyleField = new DropdownField("AdvertisementStyleID", _t("AdvertisementDecorator.STYLECREATED", "Select style"), $list));
             $selectStyleField->setRightTitle(_t("AdvertisementDecorator.STYLECREATED_EXPLANATION", "Styles are created by your developer"));
         }
         $txt = sprintf(_t("AdvertisementDecorator.EDIT", 'Edit %1$s'), Config::inst()->get("Advertisement", "plural_name"));
         $fields->addFieldToTab($tabName, $this->MyHeaderField($txt));
         $txt = sprintf(_t("AdvertisementDecorator.PLEASEMANAGEEXISTING", '<p>Please manage existing %1$s on the <a href="admin/%2$s/">%3$s tab</a>.</p>'), Config::inst()->get("Advertisement", "plural_name"), Config::inst()->get("AdvertisementAdmin", "url_segment"), Config::inst()->get("AdvertisementAdmin", "menu_title"));
         $fields->addFieldToTab($tabName, new LiteralField("ManageAdvertisements", $txt));
         $txt = sprintf(_t("AdvertisementDecorator.DELETE", 'Delete %1$s'), Config::inst()->get("Advertisement", "plural_name"));
         $fields->addFieldToTab($tabName, $this->MyHeaderField($txt));
         $page = SiteTree::get()->byID($this->owner->ID);
         $txtRemove = sprintf(_t("AdvertisementDecorator.REMOVE", 'Remove all %1$s from this page (%1$s will not be deleted but are not longer associated with this page)'), Config::inst()->get("Advertisement", "plural_name"));
         $txtConfirmRemove = sprintf(_t("AdvertisementDecorator.CONFIRMREMOVE", 'Are you sure you want to remove all %1$s from this page?'), Config::inst()->get("Advertisement", "plural_name"));
         $removeallLink = 'advertisements/removealladvertisements/' . $this->owner->ID . '/';
         $jquery = 'if(confirm(\'' . $txtConfirmRemove . '\')) {jQuery(\'#removealladvertisements\').load(\'' . $removeallLink . '\');} return false;';
         $fields->addFieldToTab($tabName, new LiteralField("removealladvertisements", '<p class="message warning"><a href="' . $removeallLink . '" onclick="' . $jquery . '"  id="removealladvertisements"  class="ss-ui-button">' . $txtRemove . '</a></p>'));
         $txtDelete = sprintf(_t("AdvertisementDecorator.DELETE", 'Delete all %1$s from this website (but not the images associated with them)'), Config::inst()->get("Advertisement", "plural_name"));
         $txtConfirmDelete = sprintf(_t("AdvertisementDecorator.CONFIRMDELETE", 'Are you sure you want to delete all %1$s - there is no UNDO?'), Config::inst()->get("Advertisement", "plural_name"));
         $deleteallLink = 'advertisements/deletealladvertisements/' . $this->owner->ID . '/';
         $jquery = 'if(confirm(\'' . $txtConfirmDelete . '\')) {jQuery(\'#deletealladvertisements\').load(\'' . $deleteallLink . '\');} return false;';
         $fields->addFieldToTab($tabName, new LiteralField("deletealladvertisements", '<p class="message bad"><a href="' . $deleteallLink . '" onclick="' . $jquery . '"  id="deletealladvertisements" class="ss-ui-button">' . $txtDelete . '</a></p>'));
     }
     return $fields;
 }