Sfoglia il codice sorgente

N.474: Support for "file" attribute (AttributeBlob) in the portal. READONLY only for now.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@4512 a333f486-631f-4898-b8df-5754b55c2be0
glajarige 8 anni fa
parent
commit
7db44512c6

+ 39 - 0
application/utils.inc.php

@@ -438,6 +438,45 @@ class utils
     }
 
 	/**
+	 * Format a value into a more friendly format (KB, MB, GB, TB) instead a juste a Bytes amount.
+	 *
+	 * @param type $value
+	 * @return string
+	 */
+	public static function BytesToFriendlyFormat($value)
+	{
+		$sReturn = '';
+		// Kilobytes
+		if ($value >= 1024)
+		{
+			$sReturn = 'K';
+			$value = $value / 1024;
+		}
+		// Megabytes
+		if ($value >= 1024)
+		{
+			$sReturn = 'M';
+			$value = $value / 1024;
+		}
+		// Gigabytes
+		if ($value >= 1024)
+		{
+			$sReturn = 'G';
+			$value = $value / 1024;
+		}
+		// Terabytes
+		if ($value >= 1024)
+		{
+			$sReturn = 'T';
+			$value = $value / 1024;
+		}
+
+		$value = round($value, 1);
+
+		return $value . '' . $sReturn . 'B';
+	}
+
+	/**
 	 * Helper function to convert a string to a date, given a format specification. It replaces strtotime which does not allow for specifying a date in a french format (for instance)
 	 * Example: StringToTime('01/05/11 12:03:45', '%d/%m/%y %H:%i:%s')
 	 * @param string $sDate

+ 27 - 0
core/attributedef.class.inc.php

@@ -5113,6 +5113,33 @@ class AttributeBlob extends AttributeDefinition
 		}
 		return $sFingerprint;		
 	}
+
+	static public function GetFormFieldClass()
+	{
+		return '\\Combodo\\iTop\\Form\\Field\\BlobField';
+	}
+
+	public function MakeFormField(DBObject $oObject, $oFormField = null)
+	{
+		if ($oFormField === null)
+		{
+			$sFormFieldClass = static::GetFormFieldClass();
+			$oFormField = new $sFormFieldClass($this->GetCode());
+		}
+
+		// Note: As of today we want this field to always be read-only
+		$oFormField->SetReadOnly(true);
+
+		// Generating urls
+		$value = $oObject->Get($this->GetCode());
+		$oFormField->SetDownloadUrl($value->GetDownloadURL(get_class($oObject), $oObject->GetKey(), $this->GetCode()));
+		$oFormField->SetDisplayUrl($value->GetDisplayURL(get_class($oObject), $oObject->GetKey(), $this->GetCode()));
+
+		parent::MakeFormField($oObject, $oFormField);
+
+		return $oFormField;
+	}
+
 }
 
 /**

+ 11 - 3
core/ormdocument.class.inc.php

@@ -119,17 +119,25 @@ class ormDocument
 	}
 
 	/**
+	 * Returns an URL to display a document like an image
+	 * @return string
+	 */
+	public function GetDisplayURL($sClass, $Id, $sAttCode)
+	{
+		return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode";
+	}
+
+	/**
 	 * Returns an URL to download a document like an image (uses HTTP caching)
 	 * @return string
-	 */	 	 	
+	 */
 	public function GetDownloadURL($sClass, $Id, $sAttCode)
 	{
 		// Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files)
 		$sSignature = md5($this->GetData());
-		return utils::GetAbsoluteUrlAppRoot()."pages/ajax.document.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode&s=$sSignature&cache=86400";
+		return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.document.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode&s=$sSignature&cache=86400";
 	}
 
-	
 	public function IsPreviewAvailable()
 	{
 		$bRet = false;

+ 3 - 0
datamodels/2.x/itop-portal-base/cs.dict.itop-portal-base.php

@@ -61,6 +61,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
     'Portal:Datatables:Language:Sort:Descending' => 'řadit sestupně',
     'Portal:Autocomplete:NoResult' => 'Žádná data',
     'Portal:Attachments:DropZone:Message' => 'Přesuňte soubory myší pro vložení',
+	'Portal:File:None' => 'No file',
+	'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
+	'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
 ));
 
 // UserProfile brick

+ 3 - 0
datamodels/2.x/itop-portal-base/en.dict.itop-portal-base.php

@@ -57,6 +57,9 @@ Dict::Add('EN US', 'English', 'English', array(
 	'Portal:Datatables:Language:Sort:Descending' => 'enable for a descending sort',
 	'Portal:Autocomplete:NoResult' => 'No data',
 	'Portal:Attachments:DropZone:Message' => 'Drop your files to add them as attachments',
+	'Portal:File:None' => 'No file',
+	'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
+	'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
 ));
 
 // UserProfile brick

+ 3 - 0
datamodels/2.x/itop-portal-base/es_cr.dict.itop-portal-base.php

@@ -57,6 +57,9 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
 	'Portal:Datatables:Language:Sort:Descending' => 'Habilitar para un tipo descendente',
 	'Portal:Autocomplete:NoResult' => 'Sin datos',
 	'Portal:Attachments:DropZone:Message' => 'Agrega tus archivos para agregarlos como documentos adjuntos',
+	'Portal:File:None' => 'No file',
+	'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
+	'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
 ));
 
 // UserProfile brick

+ 3 - 0
datamodels/2.x/itop-portal-base/fr.dict.itop-portal-base.php

@@ -57,6 +57,9 @@ Dict::Add('FR FR', 'French', 'Français', array(
 	'Portal:Datatables:Language:Sort:Descending' => 'activer pour trier la colonne par ordre décroissant',
 	'Portal:Autocomplete:NoResult' => 'Aucun résultat',
 	'Portal:Attachments:DropZone:Message' => 'Déposez vos fichiers pour les ajouter en pièces jointes',
+	'Portal:File:None' => 'Aucun fichier',
+	'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
+	'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Ouvrir</a> / <a href="%4$s" class="file_download_link">Télécharger</a>',
 ));
 
 // UserProfile brick

+ 4 - 0
datamodels/2.x/itop-portal-base/portal/web/css/portal.css

@@ -810,6 +810,10 @@ table .group-actions {
     }
   }
 }
+/* BlobField */
+.form_fields .file_open_link {
+  margin-left: 10px;
+}
 .form_field .form-control-static img {
   max-width: 100% !important;
   height: initial !important;

+ 4 - 0
datamodels/2.x/itop-portal-base/portal/web/css/portal.scss

@@ -850,6 +850,10 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{
 		}
 	}
 }
+/* BlobField */
+.form_fields .file_open_link{
+	margin-left: 10px;
+}
 
 .form_field .form-control-static img{
 	max-width: 100% !important;

+ 1 - 0
sources/autoload.php

@@ -24,6 +24,7 @@ require_once APPROOT . 'sources/form/form.class.inc.php';
 require_once APPROOT . 'sources/form/formmanager.class.inc.php';
 require_once APPROOT . 'sources/form/field/field.class.inc.php';
 require_once APPROOT . 'sources/form/field/fileuploadfield.class.inc.php';
+require_once APPROOT . 'sources/form/field/blobfield.class.inc.php';
 require_once APPROOT . 'sources/form/field/subformfield.class.inc.php';
 require_once APPROOT . 'sources/form/field/textfield.class.inc.php';
 require_once APPROOT . 'sources/form/field/hiddenfield.class.inc.php';

+ 83 - 0
sources/form/field/blobfield.class.inc.php

@@ -0,0 +1,83 @@
+<?php
+
+// Copyright (C) 2010-2016 Combodo SARL
+//
+//   This file is part of iTop.
+//
+//   iTop is free software; you can redistribute it and/or modify	
+//   it under the terms of the GNU Affero General Public License as published by
+//   the Free Software Foundation, either version 3 of the License, or
+//   (at your option) any later version.
+//
+//   iTop is distributed in the hope that it will be useful,
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//   GNU Affero General Public License for more details.
+//
+//   You should have received a copy of the GNU Affero General Public License
+//   along with iTop. If not, see <http://www.gnu.org/licenses/>
+
+namespace Combodo\iTop\Form\Field;
+
+use \utils;
+use \Dict;
+use \ormDocument;
+use \Combodo\iTop\Form\Field\Field;
+
+/**
+ * Description of BlobField
+ *
+ * @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
+ */
+class BlobField extends Field
+{
+	protected $sDownloadUrl;
+	protected $sDisplayUrl;
+
+	public function GetDownloadUrl()
+	{
+		return $this->sDownloadUrl;
+	}
+
+	public function GetDisplayUrl()
+	{
+		return $this->sDisplayUrl;
+	}
+
+	public function SetDownloadUrl($sDownloadUrl)
+	{
+		$this->sDownloadUrl = $sDownloadUrl;
+		return $this;
+	}
+
+	public function SetDisplayUrl($sDisplayUrl)
+	{
+		$this->sDisplayUrl = $sDisplayUrl;
+		return $this;
+	}
+
+	public function GetCurrentValue()
+	{
+		return $this->currentValue->GetFileName();
+	}
+
+	public function GetDisplayValue()
+	{
+		if ($this->currentValue->IsEmpty())
+		{
+			$sValue = Dict::S('Portal:File:None');
+		}
+		else
+		{
+			$sFilename = $this->currentValue->GetFileName();
+			$iSize = utils::BytesToFriendlyFormat(strlen($this->currentValue->GetData()));
+			$sOpenLink = $this->GetDisplayUrl();
+			$sDownloadLink = $this->GetDownloadUrl();
+
+			$sValue = Dict::Format('Portal:File:DisplayInfo+', $sFilename, $iSize, $sOpenLink, $sDownloadLink);
+		}
+
+		return $sValue;
+	}
+
+}

+ 1 - 0
sources/renderer/bootstrap/bsformrenderer.class.inc.php

@@ -56,6 +56,7 @@ class BsFormRenderer extends FormRenderer
 		$this->AddSupportedField('DateTimeField', 'BsSimpleFieldRenderer');
 		$this->AddSupportedField('DurationField', 'BsSimpleFieldRenderer');
 		$this->AddSupportedField('FileUploadField', 'BsFileUploadFieldRenderer');
+		$this->AddSupportedField('BlobField', 'BsSimpleFieldRenderer');
 	}
 
 }

+ 15 - 0
sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php

@@ -284,6 +284,21 @@ EOF
 						$oOutput->AddHtml('</div>');
 						break;
 
+					case 'Combodo\\iTop\\Form\\Field\\BlobField':
+						$oOutput->AddHtml('<div class="form-group">');
+						// Showing label / value only if read-only but not hidden
+						if (!$this->oField->GetHidden())
+						{
+							if ($this->oField->GetLabel() !== '')
+							{
+								$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
+							}
+							$oOutput->AddHtml('<div class="form-control-static">')->AddHtml($this->oField->GetDisplayValue(), false)->AddHtml('</div>');
+						}
+						$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" />');
+						$oOutput->AddHtml('</div>');
+						break;
+
 					case 'Combodo\\iTop\\Form\\Field\\RadioField':
 					case 'Combodo\\iTop\\Form\\Field\\SelectField':
 					case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':