Commit 210e7977c1136596942b3da4c886e5b96e9bd33a

Authored by Kevin Fourie
1 parent 17d5d7b9

KTS-3532

"AJAX info box to be added to Community Edition"
Updated. Added to OSS code with ktstandard path updates.

Committed By: Kevin Fourie
Reviewed By: Megan Watson


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@8880 c91229c3-7414-0410-bfa2-8a42b809f60b
plugins/ktstandard/documentpreview/documentPreview.php 0 โ†’ 100644
  1 +<?php
  2 +/*
  3 + * $Id: $
  4 + *
  5 + * The contents of this file are subject to the KnowledgeTree
  6 + * Commercial Editions On-Premise License ("License");
  7 + * You may not use this file except in compliance with the License.
  8 + * You may obtain a copy of the License at
  9 + * http://www.knowledgetree.com/about/legal/
  10 + * The terms of this license may change from time to time and the latest
  11 + * license will be published from time to time at the above Internet address.
  12 + *
  13 + * This edition of the KnowledgeTree software
  14 + * is NOT licensed to you under Open Source terms.
  15 + * You may not redistribute this source code.
  16 + * For more information please see the License above.
  17 + *
  18 + * (c) 2008 KnowledgeTree Inc.
  19 + * Portions copyright The Jam Warehouse Software (Pty) Ltd;
  20 + * All Rights Reserved.
  21 + *
  22 + */
  23 +
  24 +$kt_dir = $_REQUEST['kt_dir'];
  25 +require_once($kt_dir.'/config/dmsDefaults.php');
  26 +
  27 +class DocumentPreview {
  28 + var $_oDocument;
  29 + var $_IDocId;
  30 + var $_iMimeId;
  31 + var $_oFolder;
  32 + var $_iFolderId;
  33 +
  34 + /**
  35 + * Constructer - creates the document object
  36 + *
  37 + * @param int $iDocumentId The document Id
  38 + * @return
  39 + */
  40 + function DocumentPreview($iId, $type = 'document'){
  41 + if($type == 'folder'){
  42 + // $type should never be a folder.
  43 + $this->_oDocument = false;
  44 + return;
  45 + }
  46 + $oDocument = Document::get($iId);
  47 +
  48 + if(PEAR::isError($oDocument)){
  49 + $this->_oDocument = false;
  50 + return;
  51 + }
  52 +
  53 + $this->_oDocument = $oDocument;
  54 + $this->_IDocId = $iId;
  55 + $this->_iMimeId = $oDocument->getMimeTypeID();
  56 + $this->imageMimeTypes = array(10, 27, 37, 38, 39, 71);
  57 + }
  58 +
  59 + /**
  60 + * Get the document title for the preview
  61 + *
  62 + * @return string The document title and mime icon
  63 + */
  64 + function getTitle(){
  65 + if($this->_oDocument === false){
  66 + return '<b>'._kt('Error').'</b>';
  67 + }
  68 + GLOBAL $default;
  69 + $sIcon = '';
  70 +
  71 + $sTitle = htmlentities($this->_oDocument->getName(), ENT_NOQUOTES, 'utf-8');
  72 + $iLen = strlen($sTitle);
  73 +
  74 + if($iLen > 60){
  75 + $sFull = $sTitle;
  76 + if($iLen >= 99){
  77 + $sTitle = substr($sTitle, 0, 97).'...';
  78 + }
  79 + $sTitle = '<h4 title="'.$sFull.'">'.$sTitle.'</h4>';
  80 + }else{
  81 + $sTitle = '<h2>'.$sTitle.'</h2>';
  82 + }
  83 +
  84 + // Get the icon
  85 + $sIcon = $this->getMimeIcon();
  86 +
  87 + $sTitle = '<div class="previewhd">
  88 + <div style="float:left">'.$sIcon.'</div>
  89 + <div style="float:left; width: 375px;">'.$sTitle.'</div>
  90 + </div>';
  91 + return $sTitle;
  92 + }
  93 +
  94 + /**
  95 + * Display the mime type icon.
  96 + *
  97 + * @param unknown_type $iMimeId
  98 + * @return unknown
  99 + */
  100 + function getMimeIcon() {
  101 + global $default;
  102 + $iMimeId = $this->_iMimeId;
  103 +
  104 + $sIconPath = $this->getIconPath();
  105 + $sIconPath = $default->rootUrl.$sIconPath;
  106 + return "<img src='$sIconPath' title='$sTitle' />&nbsp;&nbsp;";
  107 + }
  108 +
  109 + /**
  110 + * If there isn't an icon for the given extension, find a generic icon for the type else return the default icon.
  111 + *
  112 + * @param string $ext
  113 + * @return string
  114 + */
  115 + function checkForGeneric($ext) {
  116 + if(in_array($ext, array('py','php'))){
  117 + return 'generic/source';
  118 + }
  119 + if(in_array($ext, array('odt','sxw', 'ott', 'sxt'))){
  120 + return 'generic/wordprocessing';
  121 + }
  122 + if(in_array($ext, array('ods','ots', 'sxc', 'stc'))){
  123 + return 'spreadsheet';
  124 + }
  125 + if(in_array($ext, array('odp','otp', 'sxi', 'sti'))){
  126 + return 'generic/pres';
  127 + }
  128 + if(in_array($ext, array('mp3','m4a'))){
  129 + return 'generic/sound';
  130 + }
  131 + if(in_array($ext, array('m4v'))){
  132 + return 'generic/video';
  133 + }
  134 + return 'default';
  135 + }
  136 +
  137 + /**
  138 + * Get the path to the correct icon for the mime type
  139 + *
  140 + * @return string
  141 + */
  142 + function getIconPath() {
  143 +
  144 + $sIconPath = KTMime::getIconPath($this->_iMimeId);
  145 +
  146 + // Get mime type icon
  147 + $sIconPath = '/resources/mimetypes/big/'.$sIconPath.'.png';
  148 +
  149 + if(!file_exists(KT_DIR.$sIconPath)){
  150 + // See if there is an icon for the extension
  151 + $sMimeType = KTMime::getMimeTypeName($this->_iMimeId);
  152 + $aMimeInfo = KTMime::getFriendlyNameAndExtension($sMimeType);
  153 + if(!PEAR::isError($aMimeInfo) && !empty($aMimeInfo)){
  154 + $sExt = $aMimeInfo[0]['filetypes'];
  155 + $sIconPath = '/resources/mimetypes/big/'.$sExt.'.png';
  156 +
  157 + if(!file_exists(KT_DIR.$sIconPath)){
  158 + $generic = $this->checkForGeneric($sExt);
  159 + // if all else fails, use the default icon
  160 + $sIconPath = '/resources/mimetypes/big/'.$generic.'.png';
  161 + }
  162 + }
  163 + }
  164 + return $sIconPath;
  165 + }
  166 +
  167 + /**
  168 + * Render the info box content
  169 + *
  170 + * @return string
  171 + */
  172 + function renderPreview(){
  173 + if($this->_oDocument === false){
  174 + return '<p>'._kt('A problem occured while loading the document preview.').'</p>';
  175 + }
  176 +
  177 + $sInfo = $this->getMetadata();
  178 +
  179 + return '<div id="preview" class="preview" onclick="javascript: destroyPanel();">'.$sInfo.'</div>';
  180 + }
  181 +
  182 + /**
  183 + * Create a table of the document metadata.
  184 + * Hard coded for the moment
  185 + *
  186 + * @return unknown
  187 + */
  188 + function getMetadata(){
  189 + /* Get document info */
  190 +
  191 + // Filename
  192 + $sFilenameLb = _kt('Document Filename: ');
  193 + $sFilename = $this->_oDocument->getFileName();
  194 +
  195 + // Mime type
  196 + $sMimeTypeLb = _kt('File is a: ');
  197 + $iMimeId = $this->_oDocument->getMimeTypeID();
  198 + $sMimeType = KTMime::getMimeTypeName($iMimeId);
  199 + $sMimeType = KTMime::getFriendlyNameForString($sMimeType);
  200 +
  201 + // Version
  202 + $sVersionLb = _kt('Document Version: ');
  203 + $iVersion = $this->_oDocument->getVersion();
  204 +
  205 + // Created by
  206 + $sCreatedByLb = _kt('Created by: ');
  207 + $iCreatorId = $this->_oDocument->getCreatorID();
  208 + $sCreated = $this->_oDocument->getCreatedDateTime();
  209 + $oCreator = User::get($iCreatorId);
  210 + $sCreatedBy = $oCreator->getName().' ('.$sCreated.')';
  211 +
  212 + // Owned by
  213 + $sOwnedByLb = _kt('Owned by: ');
  214 + $iOwnedId = $this->_oDocument->getOwnerID();
  215 + $oOwner = User::get($iOwnedId);
  216 + $sOwnedBy = $oOwner->getName();
  217 +
  218 + // Last update by
  219 + $iModifiedId = $this->_oDocument->getModifiedUserId();
  220 + $sLastUpdatedByLb = ''; $sLastUpdatedBy = '';
  221 + if(!empty($iModifiedId)){
  222 + $sLastUpdatedByLb = _kt('Last updated by: ');
  223 + $sModified = $this->_oDocument->getLastModifiedDate();
  224 + $oModifier = User::get($iModifiedId);
  225 + $sLastUpdatedBy = $oModifier->getName().' ('.$sModified.')';
  226 + }
  227 +
  228 + // Document type
  229 + $sDocTypeLb = _kt('Document Type: ');
  230 + $iDocTypeId = $this->_oDocument->getDocumentTypeID();
  231 + $oDocType = DocumentType::get($iDocTypeId);
  232 + $sDocType = $oDocType->getName();
  233 +
  234 + // Workflow
  235 + $iWFId = $this->_oDocument->getWorkflowId();
  236 + $sWF = ''; $sWFLb = '';
  237 + if(!empty($iWFId)){
  238 + $sWFLb = _kt('Workflow: ');
  239 + $iWFStateId = $this->_oDocument->getWorkflowStateId();
  240 + $oWF = KTWorkflow::get($iWFId);
  241 + $sWF = $oWF->getHumanName();
  242 + $oWFState = KTWorkflowState::get($iWFStateId);
  243 + $sWF .= ' ('.$oWFState->getHumanName().')';
  244 + }
  245 +
  246 + // Checked out by
  247 + $sCheckedLb = ''; $sCheckedOutBy = '';
  248 + if($this->_oDocument->getIsCheckedOut()){
  249 + $sCheckedLb = _kt('Checked out by: ');
  250 + $iCheckedID = $this->_oDocument->getCheckedOutUserID();
  251 + $oCheckedUser = User::get($iCheckedID);
  252 + $sCheckedOutBy = $oCheckedUser->getName();
  253 + }
  254 +
  255 + // Id
  256 + $sIdLb = _kt('Document ID: ');
  257 + $sId = $this->_IDocId;
  258 +
  259 + /* Create table */
  260 +
  261 + $sInfo = "<table cellspacing='3px' cellpadding='3px'>
  262 + <tr><td>{$sFilenameLb}</td><td><b>{$sFilename}</b></td></tr>
  263 + <tr><td>{$sMimeTypeLb}</td><td><b>{$sMimeType}</b></td></tr>
  264 + <tr><td>{$sVersionLb}</td><td><b>{$iVersion}</b></td></tr>
  265 + <tr><td>{$sCreatedByLb}</td><td><b>{$sCreatedBy}</b></td></tr>
  266 + <tr><td>{$sOwnedByLb}</td><td><b>{$sOwnedBy}</b></td></tr>";
  267 +
  268 + if(!empty($sLastUpdatedBy)){
  269 + $sInfo .= "<tr><td>{$sLastUpdatedByLb}</td><td><b>{$sLastUpdatedBy}</b></td></tr>";
  270 + }
  271 + $sInfo .= "<tr><td>{$sDocTypeLb}</td><td><b>{$sDocType}</b></td></tr>";
  272 + if(!empty($sWF)){
  273 + $sInfo .= "<tr><td>{$sWFLb}</td><td><b>{$sWF}</b></td></tr>";
  274 + }
  275 + if(!empty($sCheckedOutBy)){
  276 + $sInfo .= "<tr><td>{$sCheckedLb}</td><td><b>{$sCheckedOutBy}</b></td></tr>";
  277 + }
  278 +
  279 + $sInfo .= "<tr><td>{$sIdLb}</td><td><b>{$sId}</b></td></tr>
  280 + </table>";
  281 +
  282 + return $sInfo;
  283 + }
  284 +}
  285 +
  286 +/**
  287 + * Get the document id and render the preview / info box
  288 + */
  289 +
  290 +$iDocumentId = $_REQUEST['fDocumentId'];
  291 +
  292 +$oPreview = new DocumentPreview($iDocumentId);
  293 +
  294 +$sTitle = $oPreview->getTitle();
  295 +$sContent = $oPreview->renderPreview();
  296 +
  297 +echo $sTitle.'<br />'.$sContent;
  298 +exit;
  299 +?>
0 300 \ No newline at end of file
... ...
plugins/ktstandard/documentpreview/documentPreviewPlugin.php 0 โ†’ 100644
  1 +<?php
  2 +/*
  3 + * $Id: $
  4 + *
  5 + * The contents of this file are subject to the KnowledgeTree
  6 + * Commercial Editions On-Premise License ("License");
  7 + * You may not use this file except in compliance with the License.
  8 + * You may obtain a copy of the License at
  9 + * http://www.knowledgetree.com/about/legal/
  10 + * The terms of this license may change from time to time and the latest
  11 + * license will be published from time to time at the above Internet address.
  12 + *
  13 + * This edition of the KnowledgeTree software
  14 + * is NOT licensed to you under Open Source terms.
  15 + * You may not redistribute this source code.
  16 + * For more information please see the License above.
  17 + *
  18 + * (c) 2008 KnowledgeTree Inc.
  19 + * Portions copyright The Jam Warehouse Software (Pty) Ltd;
  20 + * All Rights Reserved.
  21 + *
  22 + */
  23 +
  24 +require_once(KT_LIB_DIR . '/plugins/plugin.inc.php');
  25 +require_once(KT_LIB_DIR . '/plugins/pluginregistry.inc.php');
  26 +require_once(KT_LIB_DIR . '/browse/advancedcolumns.inc.php');
  27 +
  28 +class PreviewColumn extends AdvancedColumn {
  29 +
  30 + var $namespace = 'ktcore.columns.preview';
  31 + var $sActivation = 'onclick';
  32 + var $sPluginPath = '';
  33 +
  34 + function PreviewColumn() {
  35 + $this->label = null;
  36 +
  37 + $oConfig = KTConfig::getSingleton();
  38 + $this->sActivation = $oConfig->get('browse/previewActivation', 'onclick');
  39 +
  40 + // Get file path
  41 + $this->sPluginPath = 'plugins/ktstandard/documentpreview';
  42 + }
  43 +
  44 + function renderHeader($sReturnURL) {
  45 + // Get the yui libraries required
  46 + global $main;
  47 +
  48 + // Get the CSS to render the pop-up
  49 + $main->requireCSSResource($this->sPluginPath.'/resources/container.css');
  50 +
  51 + // Get the javascript to render the document preview
  52 + $main->requireJSResource($this->sPluginPath.'/resources/preview.js');
  53 +
  54 + return '&nbsp;';
  55 + }
  56 +
  57 + function renderData($aDataRow) {
  58 + // only _ever_ show this for documents.
  59 + if ($aDataRow["type"] === "folder") {
  60 + return '&nbsp;';
  61 + }
  62 +
  63 + $sUrl = KTUtil::kt_url().'/'.$this->sPluginPath.'/documentPreview.php';
  64 + $sDir = KT_DIR;
  65 + $iDelay = 1000; // milliseconds
  66 +
  67 + $iDocumentId = $aDataRow['document']->getId();
  68 + $sTitle = _kt('Preview Document');
  69 + $sLoading = _kt('Loading...');
  70 +
  71 +
  72 + $link = '<a href = "#" class="ktAction ktPreview" id = "box_'.$iDocumentId.'" ';
  73 +
  74 + if($this->sActivation == 'mouse-over'){
  75 + $sJs = "javascript: this.t = setTimeout('showInfo(\'$iDocumentId\', \'$sUrl\', \'$sDir\', \'$sLoading\')', $iDelay);";
  76 + $link .= 'onmouseover = "'.$sJs.'" onmouseout = "clearTimeout(this.t);">';
  77 + }else{
  78 + $sJs = "javascript: showInfo('$iDocumentId', '$sUrl', '$sDir', '$sLoading');";
  79 + $link .= 'onclick = "'.$sJs.'" title="'.$sTitle.'">';
  80 + }
  81 +
  82 + return $link.$sTitle.'</a>';
  83 + }
  84 +
  85 + function getName() { return _kt('Preview'); }
  86 +}
  87 +
  88 +class DocumentPreviewPlugin extends KTPlugin {
  89 + var $sNamespace = 'document.preview.plugin';
  90 +
  91 + function DocumentPreviewPlugin($sFilename = null) {
  92 + $res = parent::KTPlugin($sFilename);
  93 + $this->sFriendlyName = _kt('Document Preview Plugin');
  94 + return $res;
  95 + }
  96 +
  97 + function setup() {
  98 + $this->registerColumn(_kt('Preview File'), 'ktcore.columns.preview', 'PreviewColumn', 'documentPreviewPlugin.php');
  99 +
  100 + require_once(KT_LIB_DIR . '/templating/templating.inc.php');
  101 + $oTemplating =& KTTemplating::getSingleton();
  102 + $oTemplating->addLocation('documentpreview', '/plugins/ktstandard/documentpreview/templates', 'document.preview.plugin');
  103 + }
  104 +}
  105 +
  106 +$oPluginRegistry =& KTPluginRegistry::getSingleton();
  107 +$oPluginRegistry->registerPlugin('DocumentPreviewPlugin', 'document.preview.plugin', __FILE__);
  108 +?>
... ...
plugins/ktstandard/documentpreview/resources/container.css 0 โ†’ 100644
  1 +
  2 +/* The containing div's, in which the dialog window is created */
  3 +
  4 +.panel {
  5 + visibility:hidden;
  6 + position:relative;
  7 + left:0px;top:0px;
  8 + font:1em Arial;
  9 + background-color:transparent;
  10 + overflow:hidden;
  11 + line-height: 1.6em;
  12 +}
  13 +
  14 +#info-preview {
  15 + padding: 10px;
  16 +}
  17 +
  18 +#info-dlg {
  19 + visibility: hidden;
  20 + position: absolute;
  21 + top: 0px;
  22 +}
  23 +
  24 +/* Styling for the dialog content */
  25 +
  26 +.preview {
  27 + padding-right: 10px;
  28 + padding-bottom: 0px;
  29 + cursor: pointer;
  30 + height: 250px;
  31 + overflow: hidden;
  32 + clear: both;
  33 +}
  34 +
  35 +.previewhd {
  36 + padding-left: 10px;
  37 + padding-right: 10px;
  38 + overflow: hidden;
  39 + visibility: visible;
  40 +}
  41 +
  42 +.previewhd h4 {
  43 + padding-top: 0;
  44 + margin-top: 0;
  45 + line-height: 110%;
  46 +}
  47 +
  48 +.previewhd h2 {
  49 + padding-top: 0;
  50 + margin-top: 0;
  51 + font-family: "Lucida Grande", "Bitstream Vera Sans", Tahoma, sans-serif;
  52 + border-width: 0 0 0 0;
  53 + border-style: solid;
  54 + border-color: #eee;
  55 + font-size: large;
  56 + color: #333;
  57 +}
  58 +
  59 +.previewhd img {
  60 + height: 40px;
  61 + width: 40px;
  62 +}
  63 +
  64 +/* Override ExtJS CSS */
  65 +
  66 +.x-window-tc {
  67 + background: url(../../../resources/graphics/portlet_bg.png) repeat-x 0 0;
  68 + overflow:hidden;
  69 + zoom:1;
  70 +}
  71 +
  72 +.x-window-tl {
  73 + background: url(../../../resources/graphics/portlet_corner_topleft.png) no-repeat 0 0;
  74 + padding-left:6px;
  75 + zoom:1;
  76 + z-index:1;
  77 + position:relative;
  78 +}
  79 +
  80 +.x-window-tr {
  81 + background: url(graphics/portlet_corner_topright.png) no-repeat right 0;
  82 + padding-right:6px;
  83 +}
  84 +
  85 +.x-window-bc {
  86 + background: #FFF;
  87 + zoom:1;
  88 +}
  89 +.x-window-bl {
  90 + border-left:1px solid #AFAFAF;
  91 + border-bottom:1px solid #AFAFAF;
  92 + background: #FFF;
  93 + padding-left:6px;
  94 + zoom:1;
  95 +}
  96 +.x-window-br {
  97 + border-right:1px solid #AFAFAF;
  98 + background: #FFF;
  99 + padding-right:6px;
  100 + zoom:1;
  101 +}
  102 +
  103 +.x-window-ml {
  104 + border-left:1px solid #AFAFAF;
  105 + background: #FFF;
  106 + padding-left:6px;
  107 + zoom:1;
  108 +}
  109 +.x-window-mr {
  110 + border-right:1px solid #AFAFAF;
  111 + background: #FFF;
  112 + padding-right:6px;
  113 + zoom:1;
  114 +}
  115 +
  116 +.x-window-mc {
  117 + border:1px solid #FFF;
  118 + border-top:1px solid #FFF;
  119 + padding:0;
  120 + margin:0;
  121 + font: normal 11px tahoma,arial,helvetica,sans-serif;
  122 + background:#FFF;
  123 +}
  124 +
  125 +.x-window-body {
  126 + border-left:1px solid #FFF;
  127 + border-top:1px solid #FFF;
  128 + border-bottom:1px solid #FFF;
  129 + border-right:1px solid #FFF;
  130 + background: transparent;
  131 +}
... ...
plugins/ktstandard/documentpreview/resources/graphics/portlet_corner_topright.png 0 โ†’ 100644

975 Bytes

plugins/ktstandard/documentpreview/resources/preview.js 0 โ†’ 100644
  1 +/*
  2 + Create the preview / info box using an ExtJS Dialog window
  3 +*/
  4 +var showInfo = function(iDocId, sUrl, sDir, loading){
  5 +
  6 + // Create the info box container div
  7 + createPanel();
  8 +
  9 + showIcon = Ext.get('box_'+iDocId);
  10 + dialog = new Ext.Window({
  11 + el: 'info-dlg',
  12 + closeAction: 'destroy',
  13 + layout: 'fit',
  14 + shadow: false,
  15 + modal: true,
  16 + plain: false,
  17 + width: 500,
  18 + height: 300,
  19 + minWidth: 300,
  20 + minHeight: 250
  21 + });
  22 + dialog.show(showIcon.dom);
  23 +
  24 + var info = document.getElementById('info-preview');
  25 + info.innerHTML = loading;
  26 +
  27 + Ext.Ajax.request({
  28 + url: sUrl,
  29 + success: function(response) {
  30 + info.innerHTML = response.responseText;
  31 + },
  32 + failure: function(response) {
  33 + alert('Error. Couldn\'t create info box.');
  34 + },
  35 + params: {
  36 + fDocumentId: iDocId,
  37 + kt_dir: sDir
  38 + }
  39 + });
  40 +}
  41 +
  42 +/*
  43 + Create the container div's in which the info box will be created.
  44 + Add the div's required by the ExtJS dialog box.
  45 +*/
  46 +var createPanel = function() {
  47 +
  48 + if(document.getElementById('info-panel')){
  49 + destroyPanel();
  50 + p = document.getElementById('info-panel');
  51 + p.style.display = 'block';
  52 + }else{
  53 + p = document.getElementById('pageBody').appendChild(document.createElement('div'));
  54 + p.id = 'info-panel';
  55 + }
  56 +
  57 + b = p.appendChild(document.createElement('div'));
  58 + b.id = 'info-dlg';
  59 + b.innerHTML = '<div class="x-window-header">Info Panel</div><div class="x-window-body"><div id="info-preview"></div></div>';
  60 +}
  61 +
  62 +/*
  63 + Set the container div to empty.
  64 + The display must be set to none for IE, otherwise the icons under the div aren't clickable.
  65 +*/
  66 +var destroyPanel = function() {
  67 + if(dialog){
  68 + dialog.destroy();
  69 + }
  70 + p = document.getElementById('info-panel');
  71 + p.innerHTML = '';
  72 + p.style.display = 'none';
  73 +}
0 74 \ No newline at end of file
... ...