namespace Combodo\iTop\Renderer\Bootstrap\FieldRenderer; use \utils; use \Dict; use \UserRights; use \InlineImage; use \DBObjectSet; use \DBObjectSearch; use \MetaModel; use \Combodo\iTop\Renderer\FieldRenderer; use \Combodo\iTop\Renderer\RenderingOutput; use \Combodo\iTop\Form\Field\LinkedSetField; /** * Description of BsFileUploadFieldRenderer * * @author Guillaume Lajarige */ class BsFileUploadFieldRenderer extends FieldRenderer { /** * Returns a RenderingOutput for the FieldRenderer's Field * * @return \Combodo\iTop\Renderer\RenderingOutput */ public function Render() { $oOutput = new RenderingOutput(); $oOutput->AddCssClass('form_field_' . $this->oField->GetDisplayMode()); $sObjectClass = get_class($this->oField->GetObject()); $sIsDeleteAllowed = ($this->oField->GetAllowDelete() && !$this->oField->GetReadOnly()) ? 'true' : 'false'; $sDeleteBtn = Dict::S('Portal:Button:Delete'); $sTempId = session_id() . '_' . $this->oField->GetTransactionId(); $sUploadDropZoneLabel = Dict::S('Portal:Attachments:DropZone:Message'); // Starting field container $oOutput->AddHtml('
'); // Label $oOutput->AddHtml('
'); if ($this->oField->GetLabel() !== '') { $oOutput->AddHtml(''); } $oOutput->AddHtml('
'); // Value $oOutput->AddHtml('
'); // - Field feedback $oOutput->AddHtml('
'); // Starting files container $oOutput->AddHtml('
'); // Files list $oOutput->AddHtml('
'); $this->PrepareExistingFiles($oOutput); $oOutput->Addhtml('
'); // Removing upload input if in read only // TODO : Add max upload size when itop attachment has been refactored if (!$this->oField->GetReadOnly()) { $oOutput->AddHtml('
' . Dict::S('Attachments:AddAttachment') . '
'); } // Ending files container $oOutput->AddHtml('
'); $oOutput->AddHtml('
'); // Ending field container $oOutput->AddHtml('
'); // JS for file upload // Note : This is based on itop-attachement/main.attachments.php $oOutput->AddJs( <<oField->GetGlobalId()}').fileupload({ url: '{$this->oField->GetUploadEndpoint()}', formData: { operation: 'add', temp_id: '{$sTempId}', object_class: '{$sObjectClass}', 'field_name': '{$this->oField->GetId()}' }, dataType: 'json', pasteZone: null, // Don't accept files via Chrome's copy/paste done: function (e, data) { if((data.result.error !== undefined) && window.console) { console.log(data.result.error); } else { var sDownloadLink = '{$this->oField->GetDownloadEndpoint()}'.replace(/-sAttachmentId-/, data.result.att_id); $(this).closest('.fileupload_field_content').find('.attachments_container').append( '' ); // Preview tooltip if(data.result.preview){ $('#display_attachment_'+data.result.att_id).tooltip({ html: true, title: function(){ return ''; } }); } // Showing remove button on hover $('#display_attachment_'+data.result.att_id).hover( function(){ $(this).children(':button').toggleClass('hidden'); }); // Remove button handler $('#display_attachment_'+data.result.att_id+' :button').click(function(oEvent){ oEvent.preventDefault(); RemoveAttachment(data.result.att_id); }); } }, start: function() { // Scrolling to dropzone so the user can see that attachments are uploaded $(this)[0].scrollIntoView(); // Showing loader $(this).closest('.upload_container').find('.loader').css('visibility', 'visible'); }, stop: function() { // Hiding the loader $(this).closest('.upload_container').find('.loader').css('visibility', 'hidden'); // Adding this field to the touched fields of the field set so the cancel event is called if necessary $(this).closest(".field_set").trigger("field_change", { id: '{$this->oField->GetGlobalId()}', name: '{$this->oField->GetId()}' }); } }); // Preview tooltip $('.attachment [data-preview="true"]').each(function(iIndex, oElem){ $(oElem).parent().tooltip({ html: true, title: function(){ return ''; } }); }); // Remove button handler $('.attachments_container .attachment :button').click(function(oEvent){ oEvent.preventDefault(); RemoveAttachment($(this).closest('.attachment').find(':input[name="attachments[]"]').val()); }); // Remove button showing if($sIsDeleteAllowed) { $('.attachment').hover( function(){ $(this).find(':button').toggleClass('hidden'); }); } // Handles a drag / drop overlay if($('#drag_overlay').length === 0) { $('body').append( $('
{$sUploadDropZoneLabel}
') ); } // Handles highlighting of the drop zone // Note : This is inspired by itop-attachments/main.attachments.php $(document).on('dragover', function(oEvent){ var bFiles = false; if (oEvent.dataTransfer && oEvent.dataTransfer.types) { for (var i = 0; i < oEvent.dataTransfer.types.length; i++) { if (oEvent.dataTransfer.types[i] == "application/x-moz-nativeimage") { bFiles = false; // mozilla contains "Files" in the types list when dragging images inside the page, but it also contains "application/x-moz-nativeimage" before break; } if (oEvent.dataTransfer.types[i] == "Files") { bFiles = true; break; } } } if (!bFiles) return; // Not dragging files var oDropZone = $('#drag_overlay'); var oTimeout = window.dropZoneTimeout; // This is to detect when there is no drag over because there is no "drag out" event if (!oTimeout) { oDropZone.removeClass('drag_out').addClass('drag_in'); } else { clearTimeout(oTimeout); } window.dropZoneTimeout = setTimeout(function () { window.dropZoneTimeout = null; oDropZone.removeClass('drag_in').addClass('drag_out'); }, 200); }); EOF ); return $oOutput; } /** * * @param RenderingOutput $oOutput */ protected function PrepareExistingFiles(RenderingOutput &$oOutput) { $sObjectClass = get_class($this->oField->GetObject()); $sDeleteBtn = Dict::S('Portal:Button:Delete'); $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id"); // Note : AllowAllData set to true here instead of checking scope's flag because we are displaying a value that has been set and validated $oSearch->AllowAllData(); $oSet = new DBObjectSet($oSearch, array(), array('class' => $sObjectClass, 'item_id' => $this->oField->GetObject()->GetKey())); // If in read only and no attachments, we display a short message if ($this->oField->GetReadOnly() && ($oSet->Count() === 0)) { $oOutput->AddHtml(Dict::S('Attachments:NoAttachment')); } else { while ($oAttachment = $oSet->Fetch()) { $iAttId = $oAttachment->GetKey(); $oDoc = $oAttachment->Get('contents'); $sFileName = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8'); $sIcon = utils::GetAbsoluteUrlAppRoot() . 'env-' . utils::GetCurrentEnvironment() . '/itop-attachments/icons/image.png'; $sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false'; $sDownloadLink = str_replace('-sAttachmentId-', $iAttId, $this->oField->GetDownloadEndpoint()); $oOutput->Addhtml( <<
{$sFileName}
EOF ); } } } }