mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
- First implementation of documents
- small cleanup to remove a global Config variable (and removed some deprecated utils:: functions) - removed the 'DocumentVersion' object since previous versions are now tracked as normal change objects. SVN:trunk[220]
This commit is contained in:
@@ -225,6 +225,21 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
}
|
||||
}
|
||||
$sHtml .= $oPage->GetDetails($aDetails);
|
||||
// Documents displayed inline (when possible: images, html...)
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$oAttDef = Metamodel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ( $oAttDef->GetEditClass() == 'Document')
|
||||
{
|
||||
$oDoc = $this->Get($sAttCode);
|
||||
if (is_object($oDoc) && !$oDoc->IsEmpty())
|
||||
{
|
||||
$sHtml .= "<p>Open in New Window: ".$oDoc->GetDisplayLink($sClass, $this->GetKey(), $sAttCode).", \n";
|
||||
$sHtml .= "Download: ".$oDoc->GetDownloadLink($sClass, $this->GetKey(), $sAttCode)."</p>\n";
|
||||
$sHtml .= "<div>".$oDoc->GetDisplayInline($sClass, $this->GetKey(), $sAttCode)."</div>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
@@ -269,8 +284,6 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
//public static function GetDisplaySet(web_page $oPage, CMDBObjectSet $oSet, $sLinkageAttribute = '', $bDisplayMenu = true, $bSelectMode = false)
|
||||
public static function GetDisplaySet(web_page $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
global $g_oConfig;
|
||||
|
||||
static $iListId = 0;
|
||||
$iListId++;
|
||||
|
||||
@@ -347,9 +360,9 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
$iMaxObjects = -1;
|
||||
if ($bDisplayLimit)
|
||||
{
|
||||
if ($oSet->Count() > $g_oConfig->GetMaxDisplayLimit())
|
||||
if ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit())
|
||||
{
|
||||
$iMaxObjects = $g_oConfig->GetMinDisplayLimit();
|
||||
$iMaxObjects = utils::GetConfig()->GetMinDisplayLimit();
|
||||
}
|
||||
}
|
||||
while (($oObj = $oSet->Fetch()) && ($iMaxObjects != 0))
|
||||
@@ -379,14 +392,14 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
//$aMenuExtraParams['linkage'] = $sLinkageAttribute;
|
||||
$aMenuExtraParams = $aExtraParams;
|
||||
}
|
||||
if ($bDisplayLimit && ($oSet->Count() > $g_oConfig->GetMaxDisplayLimit()))
|
||||
if ($bDisplayLimit && ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit()))
|
||||
{
|
||||
// list truncated
|
||||
$divId = $aExtraParams['block_id'];
|
||||
$sFilter = $oSet->GetFilter()->serialize();
|
||||
$aExtraParams['display_limit'] = false; // To expand the full list
|
||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
||||
$sHtml .= '<tr class="containerHeader"><td>'.$g_oConfig->GetMinDisplayLimit().' object(s) displayed out of '.$oSet->Count().' <a href="Javascript:ReloadTruncatedList(\''.$divId.'\', \''.$sFilter.'\', \''.$sExtraParams.'\');">Display All</a></td><td>';
|
||||
$sHtml .= '<tr class="containerHeader"><td>'.utils::GetConfig()->GetMinDisplayLimit().' object(s) displayed out of '.$oSet->Count().' <a href="Javascript:ReloadTruncatedList(\''.$divId.'\', \''.$sFilter.'\', \''.$sExtraParams.'\');">Display All</a></td><td>';
|
||||
$oPage->add_ready_script("$('#{$divId} table.listResults').addClass('truncated');");
|
||||
$oPage->add_ready_script("$('#{$divId} table.listResults tr:last td').addClass('truncated');");
|
||||
}
|
||||
@@ -434,14 +447,7 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
$aRow[] = $oObj->GetKey();
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
if (strstr($oObj->Get($sAttCode), $sSeparator)) // Escape the text only when it contains the separator
|
||||
{
|
||||
$aRow[] = $sTextQualifier.$oObj->Get($sAttCode).$sTextQualifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow[] = $oObj->Get($sAttCode);
|
||||
}
|
||||
$aRow[] = $oObj->GetAsCSV($sAttCode, $sSeparator, '\\');
|
||||
}
|
||||
$sHtml .= implode($sSeparator, $aRow)."\n";
|
||||
}
|
||||
@@ -674,6 +680,20 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
$sHTMLValue = $oWidget->Display($oPage, $value);
|
||||
break;
|
||||
|
||||
case 'Document':
|
||||
$oDocument = $value; // Value is an ormDocument object
|
||||
$sFileName = '';
|
||||
if (is_object($oDocument))
|
||||
{
|
||||
$sFileName = $oDocument->GetFileName();
|
||||
}
|
||||
$iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize'));
|
||||
$sHTMLValue = "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"$iMaxFileSize\" />\n";
|
||||
$sHTMLValue .= "<input name=\"attr_{$sAttCode}{$sNameSuffix}\" type=\"hidden\" id=\"$iInputId\" \" value=\"$sFileName\"/>\n";
|
||||
$sHTMLValue .= "<span id=\"name_$iInputId\">$sFileName</span><br/>\n";
|
||||
$sHTMLValue .= "<input name=\"file_{$sAttCode}{$sNameSuffix}\" type=\"file\" id=\"file_$iInputId\" onChange=\"UpdateFileName('$iInputId', this.value);\"/>\n";
|
||||
break;
|
||||
|
||||
case 'String':
|
||||
default:
|
||||
// #@# todo - add context information (depending on dimensions)
|
||||
@@ -728,7 +748,7 @@ abstract class cmdbAbstractObject extends CMDBObject
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
||||
$iKey = $this->GetKey();
|
||||
$aDetails = array();
|
||||
$oPage->add("<form id=\"form_{$iFormId}\" method=\"post\" onSubmit=\"return CheckMandatoryFields('form_{$iFormId}')\">\n");
|
||||
$oPage->add("<form id=\"form_{$iFormId}\" enctype=\"multipart/form-data\" method=\"post\" onSubmit=\"return CheckMandatoryFields('form_{$iFormId}')\">\n");
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ('finalclass' == $sAttCode) // finalclass is a reserved word, hardcoded !
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
require_once('../application/utils.inc.php');
|
||||
|
||||
$g_oConfig = new Config('../config-itop.php');
|
||||
|
||||
MetaModel::Startup('../config-itop.php');
|
||||
MetaModel::Startup(ITOP_CONFIG_FILE);
|
||||
|
||||
?>
|
||||
|
||||
@@ -27,6 +27,10 @@ class UIWizard
|
||||
*/
|
||||
public function DisplayWizardStep($aStep, $iStepIndex, &$iMaxInputId, &$aFieldsMap, $bFinishEnabled = false)
|
||||
{
|
||||
if ($iStepIndex == 1) // one big form that contains everything, to make sure that the uploaded files are posted too
|
||||
{
|
||||
$this->m_oPage->add("<form method=\"post\" enctype=\"multipart/form-data\" action=\"../pages/UI.php\">\n");
|
||||
}
|
||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||
$aStates = MetaModel::EnumStates($this->m_sClass);
|
||||
@@ -34,7 +38,7 @@ class UIWizard
|
||||
$sJSHandlerCode = ''; // Javascript code to be executed each time this step of the wizard is entered
|
||||
foreach($aStep as $sAttCode)
|
||||
{
|
||||
if ($sAttCode != 'finalclass') // Do not displa the attribute that stores the actual class name
|
||||
if ($sAttCode != 'finalclass') // Do not display the attribute that stores the actual class name
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
@@ -107,7 +111,6 @@ $sJSHandlerCode
|
||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||
$this->m_oPage->P("Final step: confirmation");
|
||||
$this->m_oPage->add("<form method=\"post\" action=\"../pages/UI.php\">\n");
|
||||
$this->m_oPage->add("<input type=\"hidden\" name=\"operation\" value=\"wizard_apply_new\" />\n");
|
||||
$this->m_oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\" />\n");
|
||||
$this->m_oPage->add("<input type=\"hidden\" id=\"wizard_json_obj\" name=\"json_obj\" value=\"\" />\n");
|
||||
@@ -124,8 +127,8 @@ $sJSHandlerCode
|
||||
$this->m_oPage->add("<div id=\"object_preview\">\n");
|
||||
$this->m_oPage->add("</div>\n");
|
||||
$this->m_oPage->add("<input type=\"submit\" value=\"Create ".MetaModel::GetName($this->m_sClass)."\" />\n");
|
||||
$this->m_oPage->add("</form>\n");
|
||||
$this->m_oPage->add("</div>\n");
|
||||
$this->m_oPage->add("</form>\n");
|
||||
}
|
||||
/**
|
||||
* Compute the order of the fields & pages in the wizard
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
<?php
|
||||
require_once('../core/config.class.inc.php');
|
||||
|
||||
define('CONFIGFILE', '../config.txt');
|
||||
define('ITOP_CONFIG_FILE', '../config-itop.php');
|
||||
|
||||
class FileUploadException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
class utils
|
||||
{
|
||||
private static $m_aConfig = null;
|
||||
private static $m_oConfig = null;
|
||||
|
||||
public static function ReadParam($sName, $defaultValue = "")
|
||||
{
|
||||
@@ -16,6 +21,75 @@ class utils
|
||||
return isset($_POST[$sName]) ? $_POST[$sName] : $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an uploaded file and turns it into an ormDocument object - Triggers an exception in case of error
|
||||
* @param string $sName Name of the input used from uploading the file
|
||||
* @return ormDocument The uploaded file (can be 'empty' if nothing was uploaded)
|
||||
*/
|
||||
public static function ReadPostedDocument($sName)
|
||||
{
|
||||
$oDocument = new ormDocument(); // an empty document
|
||||
if(isset($_FILES[$sName]))
|
||||
{
|
||||
switch($_FILES[$sName]['error'])
|
||||
{
|
||||
case UPLOAD_ERR_OK:
|
||||
$doc_content = file_get_contents($_FILES[$sName]['tmp_name']);
|
||||
$sMimeType = $_FILES[$sName]['type'];
|
||||
if (function_exists('finfo_file'))
|
||||
{
|
||||
// as of PHP 5.3 the fileinfo extension is bundled within PHP
|
||||
// in which case we don't trust the mime type provided by the browser
|
||||
$rInfo = @finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
|
||||
if ($rInfo !== false)
|
||||
{
|
||||
$sType = @finfo_file($rInfo, $file);
|
||||
if ( ($sType !== false)
|
||||
&& is_string($sType)
|
||||
&& (strlen($sType)>0))
|
||||
{
|
||||
$sMimeType = $sType;
|
||||
}
|
||||
}
|
||||
@finfo_close($finfo);
|
||||
}
|
||||
$oDocument = new ormDocument($doc_content, $sMimeType, $_FILES[$sName]['name']);
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
// no file to load, it's a normal case, just return an empty document
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
throw new FileUploadException("Uploaded file is too big. (Max allowed size is ".ini_get('upload_max_filesize').". Check you PHP configuration for upload_max_filesize.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
throw new FileUploadException("File upload failed, file has been truncated.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
throw new FileUploadException("Missing a temporary folder.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
throw new FileUploadException("Unable to write the temporary file to the disk (upload_tmp_dir = ".ini_get('upload_tmp_dir').")");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
throw new FileUploadException("File upload stopped by extension. (Original file name: ".$_FILES[$sName]['name'].")");
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new FileUploadException("File upload failed, unknown cause (Error code = ".$_FILES[$sName]['error'].")");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return $oDocument;
|
||||
}
|
||||
|
||||
public static function GetNewTransactionId()
|
||||
{
|
||||
// TO DO implement the real mechanism here
|
||||
@@ -34,47 +108,44 @@ class utils
|
||||
return file_get_contents($sFileName);
|
||||
}
|
||||
|
||||
public static function ReadConfig()
|
||||
/**
|
||||
* Get access to the application config file
|
||||
* @param none
|
||||
* @return Config The Config object initialized from the application config file
|
||||
*/
|
||||
public static function GetConfig()
|
||||
{
|
||||
self::$m_aConfig = array();
|
||||
|
||||
$sConfigContents = self::ReadFromFile(CONFIGFILE);
|
||||
if (!$sConfigContents) throw new Exception("Could not load file ".CONFIGFILE);
|
||||
|
||||
foreach (explode("\n", $sConfigContents) as $sLine)
|
||||
if (self::$m_oConfig == null)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (($iPos = strpos($sLine, '#')) !== false)
|
||||
{
|
||||
// strip out the end of the line right after the #
|
||||
$sLine = substr($sLine, 0, $iPos);
|
||||
}
|
||||
|
||||
$aMatches = array();
|
||||
if (preg_match("@(\\S+.*)=\s*(\S+.*)@", $sLine, $aMatches))
|
||||
{
|
||||
$sParamName = trim($aMatches[1]);
|
||||
$sParamValue = trim($aMatches[2]);
|
||||
self::$m_aConfig[$sParamName] = $sParamValue;
|
||||
}
|
||||
self::$m_oConfig = new Config(ITOP_CONFIG_FILE);
|
||||
}
|
||||
return self::$m_oConfig;
|
||||
}
|
||||
|
||||
public static function GetConfig($sParamName, $defaultValue = "")
|
||||
/**
|
||||
* Helper function to convert a value expressed in a 'user friendly format'
|
||||
* as in php.ini, e.g. 256k, 2M, 1G etc. Into a number of bytes
|
||||
* @param mixed $value The value as read from php.ini
|
||||
* @return number
|
||||
*/
|
||||
public static function ConvertToBytes( $value )
|
||||
{
|
||||
if (is_null(self::$m_aConfig))
|
||||
$iReturn = $value;
|
||||
if ( !is_numeric( $value ) )
|
||||
{
|
||||
self::ReadConfig();
|
||||
}
|
||||
|
||||
if (array_key_exists($sParamName, self::$m_aConfig))
|
||||
{
|
||||
return self::$m_aConfig[$sParamName];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $defaultValue;
|
||||
}
|
||||
}
|
||||
$iLength = strlen( $value );
|
||||
$iReturn = substr( $value, 0, $iLength - 1 );
|
||||
$sUnit = strtoupper( substr( $value, $iLength - 1 ) );
|
||||
switch ( $sUnit )
|
||||
{
|
||||
case 'G':
|
||||
$iReturn *= 1024;
|
||||
case 'M':
|
||||
$iReturn *= 1024;
|
||||
case 'K':
|
||||
$iReturn *= 1024;
|
||||
}
|
||||
}
|
||||
return $iReturn;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -8,8 +8,12 @@ class WizardHelper
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function GetTargetObject()
|
||||
/**
|
||||
* Constructs the PHP target object from the parameters sent to the web page by the wizard
|
||||
* @param boolean $bReadUploadedFiles True to also ready any uploaded file (for blob/document fields)
|
||||
* @return object
|
||||
*/
|
||||
public function GetTargetObject($bReadUploadedFiles = false)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
||||
foreach($this->m_aData['m_aCurrentValues'] as $iIndex => $value)
|
||||
@@ -60,6 +64,20 @@ class WizardHelper
|
||||
$oSet = DBObjectSet::FromArray($sLinkedClass, $aLinkedObjectsArray);
|
||||
$oObj->Set($sAttCode, $oSet);
|
||||
}
|
||||
else if ( $oAttDef->GetEditClass() == 'Document' )
|
||||
{
|
||||
if ($bReadUploadedFiles)
|
||||
{
|
||||
$oDocument = utils::ReadPostedDocument('file_'.$sAttCode);
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new empty document, just for displaying the file name
|
||||
$oDocument = new ormDocument(null, '', $value);
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
}
|
||||
}
|
||||
else if (($oAttDef->IsExternalKey()) && (!empty($value)) )
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
|
||||
@@ -406,7 +406,7 @@ class bizDocument extends logRealObject
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id', 'scope', 'description', 'contents')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id', 'scope')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id', 'scope', 'contents')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status', 'scope')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status', 'scope')); // Criteria of the advanced search form
|
||||
@@ -415,55 +415,6 @@ class bizDocument extends logRealObject
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A version of an electronic document
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizDocVersion extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
global $oAllowedStatuses;
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "DocumentVersion",
|
||||
"description" => "A version of a document",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "version_number",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("document", "version_number"),
|
||||
"db_table" => "document_versions",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("document", array("targetclass"=>"bizDocument", "label"=>"Document", "description"=>"The main document", "allowed_values"=>null, "sql"=>"document_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("docname", array("label"=>"Document Name", "description"=>"name of the document", "allowed_values"=>null, "extkey_attcode"=> 'document', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("version_number", array("label"=>"Version", "description"=>"Version identifier", "allowed_values"=>null, "sql"=>"version_number", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status", "allowed_values"=>$oAllowedStatuses, "sql"=>"status", "default_value"=>"implementation", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type", "allowed_values"=>new ValueSetEnum("local,draft"), "sql"=>"type", "default_value"=>"local", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeURL("url", array("label"=>"URL", "description"=>"Hyperlink to the version", "allowed_values"=>null, "target"=>"_blank", "sql"=>"url", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Description", "description"=>"Service Description", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("document");
|
||||
MetaModel::Init_AddFilterFromAttribute("docname");
|
||||
MetaModel::Init_AddFilterFromAttribute("version_number");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('document', 'status', 'version_number', 'type','url','description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('version_number', 'status', 'type', 'url')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('docname', 'type')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('docname', 'type')); // Criteria o
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Object and a Document
|
||||
|
||||
@@ -5,9 +5,3 @@
|
||||
</div>
|
||||
<img src="../images/folder_documents.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="true" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Versions">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizDocVersion WHERE document = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
|
||||
@@ -1233,7 +1233,20 @@ class AttributeBlob extends AttributeDefinition
|
||||
|
||||
public function GetAsHTML($value)
|
||||
{
|
||||
return $value->GetAsHTML();
|
||||
if (is_object($value))
|
||||
{
|
||||
return $value->GetAsHTML();
|
||||
}
|
||||
}
|
||||
|
||||
public function GetAsCSV($sValue, $sSeparator = ';', $sSepEscape = ',')
|
||||
{
|
||||
return ''; // Not exportable in CSV !
|
||||
}
|
||||
|
||||
public function GetAsXML($value)
|
||||
{
|
||||
return ''; // Not exportable in XML, or as CDATA + some subtags ??
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -347,7 +347,11 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$oPrevDoc = $this->Get('prevdata');
|
||||
$sDocView = $oPrevDoc->GetAsHtml();
|
||||
$sResult = "$sAttName changed (previous value: $sDocView)";
|
||||
$sDocView .= "<br/>Open in New Window: ".$oPrevDoc->GetDisplayLink(get_class($this), $this->GetKey(), 'prevdata').", \n";
|
||||
$sDocView .= "Download: ".$oPrevDoc->GetDownloadLink(get_class($this), $this->GetKey(), 'prevdata')."\n";
|
||||
|
||||
//$sDocView = $oPrevDoc->GetDisplayInline(get_class($this), $this->GetKey(), 'prevdata');
|
||||
$sResult = "$sAttName changed, previous value: $sDocView";
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
@@ -428,6 +428,23 @@ class CMDBSource
|
||||
mysql_free_result($result);
|
||||
return $aRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified server variable
|
||||
* @param string $sVarName Name of the server variable
|
||||
* @return mixed Current value of the variable
|
||||
*/
|
||||
public static function GetServerVariable($sVarName)
|
||||
{
|
||||
$result = '';
|
||||
$sSql = "SELECT @@$sVarName as theVar";
|
||||
$aRows = self::QueryToArray($sSql);
|
||||
if (count($aRows) > 0)
|
||||
{
|
||||
$result = $aRows[0]['theVar'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ class ormDocument
|
||||
return MyHelpers::beautifulstr($this->m_data, 100, true);
|
||||
}
|
||||
|
||||
public function IsEmpty()
|
||||
{
|
||||
return ($this->m_data == null);
|
||||
}
|
||||
|
||||
public function GetMimeType()
|
||||
{
|
||||
return $this->m_sMimeType;
|
||||
@@ -59,20 +64,72 @@ class ormDocument
|
||||
|
||||
public function GetAsHTML()
|
||||
{
|
||||
$data = $this->GetData();
|
||||
|
||||
$sResult = '';
|
||||
if ($this->IsEmpty())
|
||||
{
|
||||
// If the filename is not empty, display it, this is used
|
||||
// by the creation wizard while the file has not yet been uploaded
|
||||
$sResult = $this->GetFileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = $this->GetData();
|
||||
$sResult = $this->GetFileName().' [ '.$this->GetMimeType().', size: '.strlen($data).' byte(s) ]';
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML fragment that will display the document *inline* (if possible)
|
||||
* @return string
|
||||
*/
|
||||
public function GetDisplayInline($sClass, $Id, $sAttCode)
|
||||
{
|
||||
switch ($this->GetMainMimeType())
|
||||
{
|
||||
case 'text':
|
||||
return "<pre>".htmlentities(MyHelpers::beautifulstr($data, 1000, true))."</pre>\n";
|
||||
case 'text':
|
||||
case 'html':
|
||||
$data = $this->GetData();
|
||||
switch($this->GetMimeType())
|
||||
{
|
||||
case 'text/html':
|
||||
case 'text/xml':
|
||||
return "<iframe src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" width=\"100%\" height=\"400\">Loading...</iframe>\n";
|
||||
|
||||
default:
|
||||
return "<pre>".htmlentities(MyHelpers::beautifulstr($data, 1000, true))."</pre>\n";
|
||||
}
|
||||
break; // Not really needed, but...
|
||||
|
||||
case 'application':
|
||||
return "binary data for ".$this->GetMimeType().', size: '.strlen($data).' byte(s).';
|
||||
|
||||
case 'html':
|
||||
default:
|
||||
return "<div>".htmlentities(MyHelpers::beautifulstr($data, 1000, true))."</div>\n";
|
||||
case 'application':
|
||||
switch($this->GetMimeType())
|
||||
{
|
||||
case 'application/pdf':
|
||||
return "<iframe src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" width=\"100%\" height=\"400\">Loading...</iframe>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'image':
|
||||
return "<img src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an hyperlink to display the document *inline*
|
||||
* @return string
|
||||
*/
|
||||
public function GetDisplayLink($sClass, $Id, $sAttCode)
|
||||
{
|
||||
return "<a href=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" target=\"_blank\" >".$this->GetFileName()."</a>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an hyperlink to download the document (content-disposition: attachment)
|
||||
* @return string
|
||||
*/
|
||||
public function GetDownloadLink($sClass, $Id, $sAttCode)
|
||||
{
|
||||
return "<a href=\"../pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".$this->GetFileName()."</a>\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
12
js/utils.js
12
js/utils.js
@@ -17,3 +17,15 @@ function ReloadTruncatedList(divId, sSerializedFilter, sExtraParams)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the display and value of a file input widget when the user picks a new file
|
||||
*/
|
||||
function UpdateFileName(id, sNewFileName)
|
||||
{
|
||||
var aPath = sNewFileName.split('\\');
|
||||
var sNewFileName = aPath[aPath.length-1];
|
||||
|
||||
$('#'+id).val(sNewFileName);
|
||||
$('#name_'+id).text(sNewFileName);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ function WizardHelper(sClass)
|
||||
this.m_oData.m_oFieldsMap = oFieldsMap;
|
||||
|
||||
}
|
||||
|
||||
this.SetFieldsCount = function (count)
|
||||
{
|
||||
this.m_oData.m_iFieldsCount = count;
|
||||
|
||||
13
pages/UI.php
13
pages/UI.php
@@ -459,6 +459,17 @@ switch($operation)
|
||||
$bObjectModified = true;
|
||||
}
|
||||
}
|
||||
else if ($oAttDef->GetEditClass() == 'Document')
|
||||
{
|
||||
// There should be an uploaded file with the named attr_<attCode>
|
||||
$oDocument = utils::ReadPostedDocument('file_'.$sAttCode);
|
||||
if (!$oDocument->IsEmpty())
|
||||
{
|
||||
// A new file has been uploaded
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
$bObjectModified = true;
|
||||
}
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField())
|
||||
{
|
||||
$rawValue = utils::ReadPostedParam("attr_$sAttCode", null);
|
||||
@@ -826,7 +837,7 @@ switch($operation)
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj = $oWizardHelper->GetTargetObject();
|
||||
$oObj = $oWizardHelper->GetTargetObject(true /* read uploaded files */);
|
||||
if (is_object($oObj))
|
||||
{
|
||||
$sClass = get_class($oObj);
|
||||
|
||||
@@ -269,9 +269,60 @@ switch($operation)
|
||||
$oPage->add('<option title="Here is more information..." value="'.$oObj->GetKey().'">'.$oObj->GetDisplayName().'</option>');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'display_document':
|
||||
$id = utils::ReadParam('id', '');
|
||||
$sField = utils::ReadParam('field', '');
|
||||
if (!empty($sClass) && !empty($id) && !empty($sField))
|
||||
{
|
||||
DownloadDocument($oPage, $oContext, $sClass, $id, $sField, 'inline');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'download_document':
|
||||
$id = utils::ReadParam('id', '');
|
||||
$sField = utils::ReadParam('field', '');
|
||||
if (!empty($sClass) && !empty($id) && !empty($sField))
|
||||
{
|
||||
DownloadDocument($oPage, $oContext, $sClass, $id, $sField, 'attachement');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$oPage->p("Invalid query.");
|
||||
}
|
||||
$oPage->output();
|
||||
|
||||
/**
|
||||
* Downloads a document to the browser, either as 'inline' or 'attachment'
|
||||
*
|
||||
* @param web_page $oPage The web page for the output
|
||||
* @param UserContext $oContext The current User/security context to retreive the objects
|
||||
* @param string $sClass Class name of the object
|
||||
* @param mixed $id Identifier of the object
|
||||
* @param string $sAttCode Name of the attribute containing the document to download
|
||||
* @param string $sContentDisposition Either 'inline' or 'attachment'
|
||||
* @return none
|
||||
*/
|
||||
function DownloadDocument(web_page $oPage, UserContext $oContext, $sClass, $id, $sAttCode, $sContentDisposition = 'attachement')
|
||||
{
|
||||
try
|
||||
{
|
||||
$oObj = $oContext->GetObject($sClass, $id);
|
||||
if (is_object($oObj))
|
||||
{
|
||||
$oDocument = $oObj->Get($sAttCode);
|
||||
if (is_object($oDocument))
|
||||
{
|
||||
$oPage->add_header('Content-type: '.$oDocument->GetMimeType());
|
||||
$oPage->add_header('Content-Disposition: '.$sContentDisposition.'; filename="'.$oDocument->GetFileName().'"');
|
||||
$oPage->add($oDocument->GetData());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$oPage->p($e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -23,6 +23,7 @@ $oP = new setup_web_page('iTop configuration wizard');
|
||||
*/
|
||||
function CheckPHPVersion(setup_web_page $oP)
|
||||
{
|
||||
$bResult = true;
|
||||
$oP->log('Info - CheckPHPVersion');
|
||||
if (version_compare(phpversion(), PHP_MIN_VERSION, '>='))
|
||||
{
|
||||
@@ -57,9 +58,38 @@ function CheckPHPVersion(setup_web_page $oP)
|
||||
if (count($aMissingExtensions) > 0)
|
||||
{
|
||||
$oP->error("Missing PHP extension(s): ".implode(', ', $aMissingExtensionsLinks).".");
|
||||
return false;
|
||||
$bResult = false;
|
||||
}
|
||||
return true;
|
||||
// Check some ini settings here
|
||||
if (!ini_get('file_uploads'))
|
||||
{
|
||||
$oP->error("Files upload is not allowed on this server (file_uploads = ".ini_get('file_uploads').").");
|
||||
$bResult = false;
|
||||
}
|
||||
|
||||
$sUploadTmpDir = ini_get('upload_tmp_dir');
|
||||
if (empty($sUploadTmpDir))
|
||||
{
|
||||
$oP->error("Temporary directory for files upload is not defined (upload_tmp_dir)");
|
||||
$bResult = false;
|
||||
}
|
||||
|
||||
if (!ini_get('upload_max_filesize'))
|
||||
{
|
||||
$oP->error("File upload is not allowed on this server (file_uploads = ".ini_get('file_uploads').").");
|
||||
}
|
||||
|
||||
$iMaxFileUploads = ini_get('max_file_uploads');
|
||||
if (!empty($iMaxFileUploads) && ($iMaxFileUploads < 1))
|
||||
{
|
||||
$oP->error("File upload is not allowed on this server (max_file_uploads = ".ini_get('max_file_uploads').").");
|
||||
$bResult = false;
|
||||
}
|
||||
$oP->log("Info - upload_max_filesize: ".ini_get('upload_max_filesize'));
|
||||
$oP->log("Info - upload_tmp_dir: $sUploadTmpDir");
|
||||
$oP->log("Info - max_file_uploads: ".ini_get('max_file_uploads'));
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +110,26 @@ function CheckServerConnection(setup_web_page $oP, $sDBServer, $sDBUser, $sDBPwd
|
||||
if (version_compare($sDBVersion, MYSQL_MIN_VERSION, '>='))
|
||||
{
|
||||
$oP->ok("Current MySQL version ($sDBVersion), greater than minimum required version (".MYSQL_MIN_VERSION.")");
|
||||
// Check some server variables
|
||||
$iMaxAllowedPacket = $oDBSource->GetServerVariable('max_allowed_packet');
|
||||
$iMaxUploadSize = utils::ConvertToBytes(ini_get('upload_max_filesize'));
|
||||
if ($iMaxAllowedPacket >= (500 + $iMaxUploadSize)) // Allow some space for the query + the file to upload
|
||||
{
|
||||
$oP->ok("MySQL server's max_allowed_packet is big enough.");
|
||||
}
|
||||
else if($iMaxAllowedPacket < $iMaxUploadSize)
|
||||
{
|
||||
$oP->warning("MySQL server's max_allowed_packet ($iMaxAllowedPacket) is not big enough.");
|
||||
$oP->warning("Consider setting it to at least ".(500 + $iMaxUploadSize).".");
|
||||
}
|
||||
$oP->log("Info - MySQL max_allowed_packet: $iMaxAllowedPacket");
|
||||
$iMaxConnections = $oDBSource->GetServerVariable('max_connections');
|
||||
if ($iMaxConnections < 5)
|
||||
{
|
||||
$oP->warning("MySQL server's max_connections ($iMaxConnections) is not enough.");
|
||||
$oP->warning("Consider setting it to at least 5.");
|
||||
}
|
||||
$oP->log("Info - MySQL max_connections: ".($oDBSource->GetServerVariable('max_connections')));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user