mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 15:34:12 +01:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b9bca0922 | ||
|
|
21d44c664f | ||
|
|
b318cbe211 | ||
|
|
7106501812 | ||
|
|
567dd39270 | ||
|
|
b292621f82 | ||
|
|
46f0b48add | ||
|
|
9a5f16bd3e | ||
|
|
6224ec7a37 | ||
|
|
c460edcd5e | ||
|
|
b839b42cd4 | ||
|
|
fabc8b91d7 | ||
|
|
4c38cd570c | ||
|
|
c4fd15ae90 | ||
|
|
bbca491118 | ||
|
|
0d04bd8b0e | ||
|
|
3bcb3a2154 | ||
|
|
aa863c40d3 | ||
|
|
5d7ad9f6dd | ||
|
|
72cb41dd7e | ||
|
|
6ef39c9f5b | ||
|
|
614b948c82 | ||
|
|
7c0715ad59 | ||
|
|
31819497ae | ||
|
|
c86e2c6c79 | ||
|
|
1d54b66de9 | ||
|
|
f932765e19 | ||
|
|
11b4085566 | ||
|
|
12afcd7cce | ||
|
|
666c95a656 | ||
|
|
fde9c28263 | ||
|
|
52c3ff0406 | ||
|
|
9f4d07aaa5 | ||
|
|
70561d6331 | ||
|
|
ae8311e224 | ||
|
|
e09fa0ffc1 | ||
|
|
5b6a20048f | ||
|
|
d86c211b73 | ||
|
|
8499babcb3 | ||
|
|
2d44cbbb60 | ||
|
|
3d89ef9076 | ||
|
|
e896f8af3d | ||
|
|
23268e8969 | ||
|
|
421e12debd | ||
|
|
389848cef4 | ||
|
|
7da4423346 | ||
|
|
2a770b9dc4 | ||
|
|
8df12e64f2 | ||
|
|
341261c14e | ||
|
|
bfc7c73e18 | ||
|
|
9a6c4ba7bb | ||
|
|
dc47c34981 | ||
|
|
3ac5131a19 | ||
|
|
134a9aa684 | ||
|
|
a98c0d32ae | ||
|
|
38af2b85c4 | ||
|
|
c9c84735c4 | ||
|
|
646972838a | ||
|
|
ce92241593 | ||
|
|
715eeff627 | ||
|
|
651de821df | ||
|
|
2233ea5f54 | ||
|
|
39e6915e05 | ||
|
|
6279f4ac70 | ||
|
|
badf10e74e | ||
|
|
2e9cd6a342 | ||
|
|
cef70ee9a2 | ||
|
|
37e15706b2 | ||
|
|
4b210273d2 | ||
|
|
951e8e03b0 | ||
|
|
c016ca364d | ||
|
|
4611442665 | ||
|
|
c7e7976607 | ||
|
|
0ca9fac04b | ||
|
|
7edc79f398 | ||
|
|
c110206264 | ||
|
|
b3ad2030cb | ||
|
|
0938ba939c | ||
|
|
bca393def3 | ||
|
|
796ac55ff4 | ||
|
|
66ae89e91d | ||
|
|
361cca465a | ||
|
|
7462d66643 | ||
|
|
a177b9b1d4 |
@@ -409,26 +409,8 @@ EOF
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
|
||||
// Filter out links pointing to obsolete objects (if relevant)
|
||||
$oLinkSearch = $this->Get($sAttCode)->GetFilter();
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sExtKeyToRemote);
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
if (!utils::ShowObsoleteData() && MetaModel::IsObsoletable($sTargetClass))
|
||||
{
|
||||
$oNotObsolete = new BinaryExpression(
|
||||
new FieldExpression('obsolescence_flag', $sTargetClass),
|
||||
'=',
|
||||
new ScalarExpression(0)
|
||||
);
|
||||
$oNotObsoleteRemote = new DBObjectSearch($sTargetClass);
|
||||
$oNotObsoleteRemote->AddConditionExpression($oNotObsolete);
|
||||
$oLinkSearch->AddCondition_PointingTo($oNotObsoleteRemote, $sExtKeyToRemote);
|
||||
}
|
||||
}
|
||||
$oLinkSet = new DBObjectSet($oLinkSearch);
|
||||
$oLinkSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
$oOrmLinkSet = $this->Get($sAttCode);
|
||||
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
|
||||
|
||||
$iCount = $oLinkSet->Count();
|
||||
$sCount = '';
|
||||
@@ -643,17 +625,22 @@ EOF
|
||||
{
|
||||
$aDetails[$sTab] = array();
|
||||
$aTableStyles[] = 'vertical-align:top';
|
||||
$aTableClasses = array();
|
||||
|
||||
ksort($aCols);
|
||||
$iColCount = count($aCols);
|
||||
if($iColCount > 1)
|
||||
{
|
||||
$aTableStyles[] = 'width: 100%';
|
||||
$aTableClasses[] = 'n-cols-details';
|
||||
$aTableClasses[] = $iColCount.'-cols-details';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aTableClasses[] = 'one-col-details';
|
||||
}
|
||||
// Else, will size regarding the largest field of the column
|
||||
|
||||
$oPage->SetCurrentTab(Dict::S($sTab));
|
||||
$oPage->add('<table style="'.implode('; ', $aTableStyles).'" data-mode="'.$sEditMode.'"><tr>');
|
||||
$oPage->add('<table style="'.implode('; ', $aTableStyles).'" class="'.implode(' ', $aTableClasses).'" data-mode="'.$sEditMode.'"><tr>');
|
||||
foreach($aCols as $sColIndex => $aFieldsets)
|
||||
{
|
||||
$oPage->add('<td style="vertical-align:top">');
|
||||
@@ -2346,7 +2333,7 @@ EOF
|
||||
{
|
||||
$sSelected = ' selected';
|
||||
}
|
||||
$sStatesSelection .= '<option value="'.$sStateCode.'"'.$sSelected.'>'.MetaModel::GetStateLabel($sClass, $sStateCode).'</option>';
|
||||
$sStatesSelection .= '<option value="'.$sStateCode.'" '.$sSelected.'>'.MetaModel::GetStateLabel($sClass, $sStateCode).'</option>';
|
||||
}
|
||||
$sStatesSelection .= '</select>';
|
||||
$oPage->add_ready_script("$('.state_select_{$this->m_iFormId}').change( function() { oWizardHelper$sPrefix.ReloadObjectCreationForm('form_{$this->m_iFormId}', $(this).val()); } );");
|
||||
@@ -3536,14 +3523,34 @@ EOF
|
||||
|
||||
public function DBUpdate()
|
||||
{
|
||||
$res = parent::DBUpdate();
|
||||
$res = parent::DBUpdate();
|
||||
|
||||
// Invoke extensions after the update (could be before)
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
}
|
||||
return $res;
|
||||
// Protection against reentrance (e.g. cascading the update of ticket logs)
|
||||
// Note: This is based on the fix made on r 3190 in DBObject::DBUpdate()
|
||||
static $aUpdateReentrance = array();
|
||||
$sKey = get_class($this).'::'.$this->GetKey();
|
||||
if(array_key_exists($sKey, $aUpdateReentrance))
|
||||
{
|
||||
return $res;
|
||||
}
|
||||
$aUpdateReentrance[$sKey] = true;
|
||||
|
||||
try
|
||||
{
|
||||
// Invoke extensions after the update (could be before)
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected static function BulkUpdateTracked_Internal(DBSearch $oFilter, array $aValues)
|
||||
@@ -3744,7 +3751,15 @@ EOF
|
||||
$oPage->add('</fieldset>');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $sCurrentState
|
||||
* @param $sStimulus
|
||||
* @param $bOnlyNewOnes
|
||||
* @return array
|
||||
* @throws ApplicationException
|
||||
* @deprecated Since iTop 2.4, use DBObject::GetTransitionAttributes() instead.
|
||||
*/
|
||||
public function GetExpectedAttributes($sCurrentState, $sStimulus, $bOnlyNewOnes)
|
||||
{
|
||||
$aTransitions = $this->EnumTransitions();
|
||||
|
||||
@@ -360,6 +360,7 @@ EOF
|
||||
<<<EOF
|
||||
$('#$sDialogId').dialog({
|
||||
height: 'auto',
|
||||
maxHeight: $(window).height() - 8,
|
||||
width: $iDialogWidth,
|
||||
modal: true,
|
||||
autoOpen: $sAutoOpen,
|
||||
|
||||
@@ -331,31 +331,6 @@ EOF
|
||||
// This selector will be reused when selecting actual tab widget A elements.
|
||||
var tab_a_selector = 'ul.ui-tabs-nav a';
|
||||
|
||||
// This helper will be used to resize tab width
|
||||
var resizeTab = function(oElem){
|
||||
var iTableWidth = (oElem.children('table:first').length > 0) ? oElem.children('table:first').outerWidth() : 0;
|
||||
var oLayoutContentElem = oElem.closest('.ui-layout-content');
|
||||
var bEditMode = (oLayoutContentElem.find('.wizContainer').length > 0);
|
||||
var oContainerElem = (bEditMode) ? oLayoutContentElem.find('.wizContainer:first') : oLayoutContentElem.find('.ui-tabs:first');
|
||||
|
||||
// Resizing wizard container
|
||||
oContainerElem.css('min-width',
|
||||
parseInt(iTableWidth) +
|
||||
parseInt(oElem.css('margin-left'))*2 +
|
||||
parseInt(oElem.css('padding-left'))*2 +
|
||||
parseInt(tabs.css('margin-left'))*2 +
|
||||
parseInt(tabs.css('padding-left'))*2
|
||||
)
|
||||
|
||||
// Resizing header according to content container
|
||||
var iLayoutContentWidth = parseInt(oContainerElem.width());
|
||||
if(bEditMode)
|
||||
{
|
||||
iLayoutContentWidth += parseInt(oContainerElem.css('margin-left'))*2 + parseInt(oContainerElem.css('padding-left'))*2
|
||||
}
|
||||
oLayoutContentElem.find('.page_header').css('min-width', iLayoutContentWidth);
|
||||
};
|
||||
|
||||
// Ugly patch for a change in the behavior of jQuery UI:
|
||||
// Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax)
|
||||
// when their href was beginning by #. Starting with 1.9, a <base> tag in the page
|
||||
@@ -379,9 +354,6 @@ EOF
|
||||
event: 'change', 'show': function(event, ui) {
|
||||
$('.resizable', ui.panel).resizable(); // Make resizable everything that claims to be resizable !
|
||||
},
|
||||
create: function( event, ui ) {
|
||||
resizeTab(ui.panel);
|
||||
},
|
||||
beforeLoad: function( event, ui ) {
|
||||
if ( ui.tab.data('loaded') && (ui.tab.attr('data-cache') == 'true')) {
|
||||
event.preventDefault();
|
||||
@@ -391,9 +363,6 @@ EOF
|
||||
ui.jqXHR.success(function() {
|
||||
ui.tab.data( "loaded", true );
|
||||
});
|
||||
},
|
||||
activate: function( event, ui ) {
|
||||
resizeTab(ui.newPanel);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ class ApplicationMenu
|
||||
{
|
||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||
if (!$oMenuNode->IsEnabled()) continue; // Don't display a non-enabled menu
|
||||
$oPage->AddToMenu('<h3 id="Menu_'.$oMenuNode->GetMenuID().'">'.$oMenuNode->GetTitle().'</h3>');
|
||||
$oPage->AddToMenu('<h3 id="'.utils::GetSafeId('AccordionMenu_'.$oMenuNode->GetMenuID()).'">'.$oMenuNode->GetTitle().'</h3>');
|
||||
$oPage->AddToMenu('<div>');
|
||||
$aChildren = self::GetChildren($aMenu['index']);
|
||||
if (count($aChildren) > 0)
|
||||
@@ -217,11 +217,11 @@ EOF
|
||||
$sHyperlink = $oMenu->GetHyperlink($aExtraParams);
|
||||
if ($sHyperlink != '')
|
||||
{
|
||||
$oPage->AddToMenu('<li id="Menu_'.$oMenu->GetMenuID().'"'.$sCSSClass.'><a href="'.$oMenu->GetHyperlink($aExtraParams).'">'.$oMenu->GetTitle().'</a></li>');
|
||||
$oPage->AddToMenu('<li id="'.utils::GetSafeId('AccordionMenu_'.$oMenu->GetMenuID()).'"'.$sCSSClass.'><a href="'.$oMenu->GetHyperlink($aExtraParams).'">'.$oMenu->GetTitle().'</a></li>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->AddToMenu('<li id="Menu_'.$oMenu->GetMenuID().'"'.$sCSSClass.'>'.$oMenu->GetTitle().'</li>');
|
||||
$oPage->AddToMenu('<li id="'.utils::GetSafeId('AccordionMenu_'.$oMenu->GetMenuID()).'"'.$sCSSClass.'>'.$oMenu->GetTitle().'</li>');
|
||||
}
|
||||
$aCurrentMenu = self::$aMenusIndex[$index];
|
||||
if ($iActiveMenu == $index)
|
||||
|
||||
@@ -138,7 +138,9 @@ class UILinksWidget
|
||||
$sValue = $linkObjOrId->Get($sFieldCode);
|
||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId, $sNameSuffix, 0, $aArgs);
|
||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId, $sNameSuffix, 0, $aArgs).
|
||||
'</div></div></div>';
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +168,7 @@ class UILinksWidget
|
||||
$sPrefix .= "[-$iUniqueId][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".$iUniqueId;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".($iUniqueId < 0 ? -$iUniqueId : $iUniqueId);
|
||||
$aArgs['this'] = $oNewLinkObj;
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"-$iUniqueId\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
@@ -176,17 +178,24 @@ class UILinksWidget
|
||||
$sValue = $oNewLinkObj->Get($sFieldCode);
|
||||
$sDisplayValue = $oNewLinkObj->GetEditValue($sFieldCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs);
|
||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs).
|
||||
'</div></div></div>';
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
}
|
||||
$sState = '';
|
||||
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
// Rows created with ajax call need OnLinkAdded call.
|
||||
// Rows added before loading the form cannot call OnLinkAdded.
|
||||
if ($iUniqueId > 0)
|
||||
{
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
PrepareWidgets();
|
||||
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
||||
EOF
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(!$bReadOnly)
|
||||
|
||||
@@ -141,6 +141,9 @@ class utils
|
||||
}
|
||||
|
||||
protected static $bPageMode = null;
|
||||
/**
|
||||
* @var boolean[]
|
||||
*/
|
||||
protected static $aModes = array();
|
||||
|
||||
public static function InitArchiveMode()
|
||||
@@ -164,6 +167,10 @@ class utils
|
||||
self::$bPageMode = ($iCurrent == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $bMode if true then activate archive mode (archived objects are visible), otherwise archived objects are
|
||||
* hidden (archive = "soft deletion")
|
||||
*/
|
||||
public static function PushArchiveMode($bMode)
|
||||
{
|
||||
array_push(self::$aModes, $bMode);
|
||||
@@ -174,6 +181,9 @@ class utils
|
||||
array_pop(self::$aModes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean true if archive mode is enabled
|
||||
*/
|
||||
public static function IsArchiveMode()
|
||||
{
|
||||
if (count(self::$aModes) > 0)
|
||||
@@ -917,7 +927,7 @@ class utils
|
||||
*/
|
||||
public static function GetCachePath()
|
||||
{
|
||||
return APPROOT.'data/cache-'.self::GetCurrentEnvironment().'/';
|
||||
return APPROOT.'data/cache-'.MetaModel::GetEnvironment().'/';
|
||||
}
|
||||
/**
|
||||
* Merge standard menu items with plugin provided menus items
|
||||
@@ -1590,4 +1600,207 @@ class utils
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given path/url is an http(s) URL
|
||||
* @param string $sPath
|
||||
* @return boolean
|
||||
*/
|
||||
public static function IsURL($sPath)
|
||||
{
|
||||
$bRet = false;
|
||||
if ((substr($sPath, 0, 7) == 'http://') || (substr($sPath, 0, 8) == 'https://') || (substr($sPath, 0, 8) == 'ftp://'))
|
||||
{
|
||||
$bRet = true;
|
||||
}
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given URL is a link to download a document/image on the CURRENT iTop
|
||||
* In such a case we can read the content of the file directly in the database (if the users rights allow) and return the ormDocument
|
||||
* @param string $sPath
|
||||
* @return false|ormDocument
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function IsSelfURL($sPath)
|
||||
{
|
||||
$result = false;
|
||||
$sPageUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.document.php';
|
||||
if (substr($sPath, 0, strlen($sPageUrl)) == $sPageUrl)
|
||||
{
|
||||
// If the URL is an URL pointing to this instance of iTop, then
|
||||
// extract the "query" part of the URL and analyze it
|
||||
$sQuery = parse_url($sPath, PHP_URL_QUERY);
|
||||
if ($sQuery !== null)
|
||||
{
|
||||
$aParams = array();
|
||||
foreach(explode('&', $sQuery) as $sChunk)
|
||||
{
|
||||
$aParts = explode('=', $sChunk);
|
||||
if (count($aParts) != 2) continue;
|
||||
$aParams[$aParts[0]] = urldecode($aParts[1]);
|
||||
}
|
||||
$result = array_key_exists('operation', $aParams) && array_key_exists('class', $aParams) && array_key_exists('id', $aParams) && array_key_exists('field', $aParams) && ($aParams['operation'] == 'download_document');
|
||||
if ($result)
|
||||
{
|
||||
// This is a 'download_document' operation, let's retrieve the document directly from the database
|
||||
$sClass = $aParams['class'];
|
||||
$iKey = $aParams['id'];
|
||||
$sAttCode = $aParams['field'];
|
||||
|
||||
$oObj = MetaModel::GetObject($sClass, $iKey, false /* must exist */); // Users rights apply here !!
|
||||
if ($oObj)
|
||||
{
|
||||
/**
|
||||
* @var ormDocument $result
|
||||
*/
|
||||
$result = clone $oObj->Get($sAttCode);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception('Invalid URL. This iTop URL is not pointing to a valid Document/Image.');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the content of a file (and retrieve its MIME type) from either:
|
||||
* - an URL pointing to a blob (image/document) on the current iTop server
|
||||
* - an http(s) URL
|
||||
* - the local file system (but only if you are an administrator)
|
||||
* @param string $sPath
|
||||
* @return ormDocument|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function FileGetContentsAndMIMEType($sPath)
|
||||
{
|
||||
$oUploadedDoc = null;
|
||||
$aKnownExtensions = array(
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'pdf' => 'application/pdf',
|
||||
'doc' => 'application/msword',
|
||||
'dot' => 'application/msword',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'vsd' => 'application/x-visio',
|
||||
'vdx' => 'application/visio.drawing',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'zip' => 'application/zip',
|
||||
'txt' => 'text/plain',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'exe' => 'application/octet-stream'
|
||||
);
|
||||
|
||||
$sData = null;
|
||||
$sMimeType = 'text/plain'; // Default MIME Type: treat the file as a bunch a characters...
|
||||
$sFileName = 'uploaded-file'; // Default name for downloaded-files
|
||||
$sExtension = '.txt'; // Default file extension in case we don't know the MIME Type
|
||||
|
||||
if(empty($sPath))
|
||||
{
|
||||
// Empty path (NULL or '') means that there is no input, making an empty document.
|
||||
$oUploadedDoc = new ormDocument('', '', '');
|
||||
}
|
||||
elseif (static::IsURL($sPath))
|
||||
{
|
||||
if ($oUploadedDoc = static::IsSelfURL($sPath))
|
||||
{
|
||||
// Nothing more to do, we've got it !!
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remote file, let's use the HTTP headers to find the MIME Type
|
||||
$sData = @file_get_contents($sPath);
|
||||
if ($sData === false)
|
||||
{
|
||||
throw new Exception("Failed to load the file from the URL '$sPath'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($http_response_header))
|
||||
{
|
||||
$aHeaders = static::ParseHeaders($http_response_header);
|
||||
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
|
||||
// Compute the file extension from the MIME Type
|
||||
foreach($aKnownExtensions as $sExtValue => $sMime)
|
||||
{
|
||||
if ($sMime === $sMimeType)
|
||||
{
|
||||
$sExtension = '.'.$sExtValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sFileName .= $sExtension;
|
||||
}
|
||||
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
|
||||
}
|
||||
}
|
||||
else if (UserRights::IsAdministrator())
|
||||
{
|
||||
// Only administrators are allowed to read local files
|
||||
$sData = @file_get_contents($sPath);
|
||||
if ($sData === false)
|
||||
{
|
||||
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
|
||||
}
|
||||
$sExtension = strtolower(pathinfo($sPath, PATHINFO_EXTENSION));
|
||||
$sFileName = basename($sPath);
|
||||
|
||||
if (array_key_exists($sExtension, $aKnownExtensions))
|
||||
{
|
||||
$sMimeType = $aKnownExtensions[$sExtension];
|
||||
}
|
||||
else if (extension_loaded('fileinfo'))
|
||||
{
|
||||
$finfo = new finfo(FILEINFO_MIME);
|
||||
$sMimeType = $finfo->file($sPath);
|
||||
}
|
||||
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
|
||||
}
|
||||
return $oUploadedDoc;
|
||||
}
|
||||
|
||||
protected static function ParseHeaders($aHeaders)
|
||||
{
|
||||
$aCleanHeaders = array();
|
||||
foreach( $aHeaders as $sKey => $sValue )
|
||||
{
|
||||
$aTokens = explode(':', $sValue, 2);
|
||||
if(isset($aTokens[1]))
|
||||
{
|
||||
$aCleanHeaders[trim($aTokens[0])] = trim($aTokens[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The header is not in the form Header-Code: Value
|
||||
$aCleanHeaders[] = $sValue; // Store the value as-is
|
||||
$aMatches = array();
|
||||
// Check if it's not the HTTP response code
|
||||
if( preg_match("|HTTP/[0-9\.]+\s+([0-9]+)|", $sValue, $aMatches) )
|
||||
{
|
||||
$aCleanHeaders['reponse_code'] = intval($aMatches[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aCleanHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2016 Combodo SARL
|
||||
// Copyright (C) 2016-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -67,3 +67,32 @@ if (!function_exists('apc_store') && function_exists('apcu_store'))
|
||||
return apcu_store($key, $var, $ttl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user cache info... beware of the format of the returned structure that may vary (See usages)
|
||||
* @return array
|
||||
*/
|
||||
function apc_cache_info_compat()
|
||||
{
|
||||
if (!function_exists('apc_cache_info')) return array();
|
||||
|
||||
$oFunction = new ReflectionFunction('apc_cache_info');
|
||||
if ($oFunction->getNumberOfParameters() != 2)
|
||||
{
|
||||
// Beware: APCu behaves slightly differently from APC !!
|
||||
// Worse: the compatibility layer integrated into APC differs from apcu-bc (testing the number of parameters is a must)
|
||||
// In CLI mode (PHP > 7) apc_cache_info returns null and outputs an error message.
|
||||
$aCacheUserData = @apc_cache_info();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCacheUserData = @apc_cache_info('user');
|
||||
}
|
||||
return $aCacheUserData;
|
||||
}
|
||||
|
||||
// Cache emulation
|
||||
if (!function_exists('apc_store'))
|
||||
{
|
||||
require_once(APPROOT.'core/apc-emulation.php');
|
||||
}
|
||||
301
core/apc-emulation.php
Normal file
301
core/apc-emulation.php
Normal file
@@ -0,0 +1,301 @@
|
||||
<?php
|
||||
// Copyright (c) 2010-2017 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/>
|
||||
//
|
||||
|
||||
/**
|
||||
* Date: 27/09/2017
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param string $cache_type
|
||||
* @param bool $limited
|
||||
* @return array|bool
|
||||
*/
|
||||
function apc_cache_info($cache_type = '', $limited = false)
|
||||
{
|
||||
$aInfo = array();
|
||||
$sRootCacheDir = apc_emul_get_cache_filename('');
|
||||
$aInfo['cache_list'] = apc_emul_get_cache_entries($sRootCacheDir);
|
||||
return $aInfo;
|
||||
}
|
||||
|
||||
function apc_emul_get_cache_entries($sEntry)
|
||||
{
|
||||
$aResult = array();
|
||||
if (is_dir($sEntry))
|
||||
{
|
||||
$aFiles = array_diff(scandir($sEntry), array('.', '..'));
|
||||
foreach($aFiles as $sFile)
|
||||
{
|
||||
$sSubFile = $sEntry.'/'.$sFile;
|
||||
$aResult = array_merge($aResult, apc_emul_get_cache_entries($sSubFile));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sKey = basename($sEntry);
|
||||
if (strpos($sKey, '-') === 0)
|
||||
{
|
||||
$sKey = substr($sKey, 1);
|
||||
}
|
||||
$aResult[] = array('info' => $sKey);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $key
|
||||
* @param $var
|
||||
* @param int $ttl
|
||||
* @return array|bool
|
||||
*/
|
||||
function apc_store($key, $var = NULL, $ttl = 0)
|
||||
{
|
||||
if (is_array($key))
|
||||
{
|
||||
$aResult = array();
|
||||
foreach($key as $sKey => $value)
|
||||
{
|
||||
$aResult[] = apc_emul_store_unit($sKey, $value, $ttl);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
return apc_emul_store_unit($key, $var, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param $value
|
||||
* @param int $iTTL time to live
|
||||
* @return bool
|
||||
*/
|
||||
function apc_emul_store_unit($sKey, $value, $iTTL)
|
||||
{
|
||||
if ($iTTL > 0)
|
||||
{
|
||||
// hint for ttl management
|
||||
$sKey = '-'.$sKey;
|
||||
}
|
||||
|
||||
$sFilename = apc_emul_get_cache_filename($sKey);
|
||||
// try to create the folder
|
||||
$sDirname = dirname($sFilename);
|
||||
if (!file_exists($sDirname))
|
||||
{
|
||||
if (!@mkdir($sDirname, 0755, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$bRes = !(@file_put_contents($sFilename, serialize($value), LOCK_EX) === false);
|
||||
apc_emul_manage_new_entry($sFilename);
|
||||
return $bRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key string|array
|
||||
* @return mixed
|
||||
*/
|
||||
function apc_fetch($key)
|
||||
{
|
||||
if (is_array($key))
|
||||
{
|
||||
$aResult = array();
|
||||
foreach($key as $sKey)
|
||||
{
|
||||
$aResult[$sKey] = apc_emul_fetch_unit($sKey);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
return apc_emul_fetch_unit($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sKey
|
||||
* @return bool|mixed
|
||||
*/
|
||||
function apc_emul_fetch_unit($sKey)
|
||||
{
|
||||
// Try the 'TTLed' version
|
||||
$sValue = apc_emul_readcache_locked(apc_emul_get_cache_filename('-'.$sKey));
|
||||
if ($sValue === false)
|
||||
{
|
||||
$sValue = apc_emul_readcache_locked(apc_emul_get_cache_filename($sKey));
|
||||
if ($sValue === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$oRes = @unserialize($sValue);
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
function apc_emul_readcache_locked($sFilename)
|
||||
{
|
||||
$file = @fopen($sFilename, 'r');
|
||||
if ($file === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
flock($file, LOCK_SH);
|
||||
$sContent = @fread($file, @filesize($sFilename));
|
||||
flock($file, LOCK_UN);
|
||||
fclose($file);
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cache_type
|
||||
* @return bool
|
||||
*/
|
||||
function apc_clear_cache($cache_type = '')
|
||||
{
|
||||
$sRootCacheDir = apc_emul_get_cache_filename('');
|
||||
apc_emul_delete_entry($sRootCacheDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
function apc_emul_delete_entry($sCache)
|
||||
{
|
||||
if (is_dir($sCache))
|
||||
{
|
||||
$aFiles = array_diff(scandir($sCache), array('.', '..'));
|
||||
foreach($aFiles as $sFile)
|
||||
{
|
||||
$sSubFile = $sCache.'/'.$sFile;
|
||||
if (!apc_emul_delete_entry($sSubFile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!@rmdir($sCache))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!@unlink($sCache))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return bool|string[]
|
||||
*/
|
||||
function apc_delete($key)
|
||||
{
|
||||
return apc_emul_delete_entry(apc_emul_get_cache_filename($key));
|
||||
}
|
||||
|
||||
|
||||
function apc_emul_get_cache_filename($sKey)
|
||||
{
|
||||
$sPath = str_replace(array(' ', '/', '\\', '.'), '-', $sKey);
|
||||
return utils::GetCachePath().'apc-emul/'.$sPath;
|
||||
}
|
||||
|
||||
|
||||
/** Manage the cache files when a new cache entry is added
|
||||
* @param string $sNewFilename new cache file added
|
||||
*/
|
||||
function apc_emul_manage_new_entry($sNewFilename)
|
||||
{
|
||||
// Check only once per request
|
||||
static $aFilesByTime = null;
|
||||
static $iFileCount = 0;
|
||||
$iMaxFiles = MetaModel::GetConfig()->Get('apc_cache_emulation.max_entries');
|
||||
if ($iMaxFiles == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$aFilesByTime)
|
||||
{
|
||||
$sRootCacheDir = apc_emul_get_cache_filename('');
|
||||
$aFilesByTime = apc_emul_list_files_time($sRootCacheDir);
|
||||
$iFileCount = count($aFilesByTime);
|
||||
if ($iMaxFiles !== 0)
|
||||
{
|
||||
asort($aFilesByTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aFilesByTime[$sNewFilename] = time();
|
||||
$iFileCount++;
|
||||
}
|
||||
if ($iFileCount > $iMaxFiles)
|
||||
{
|
||||
$iFileNbToRemove = $iFileCount - $iMaxFiles;
|
||||
foreach($aFilesByTime as $sFileToRemove => $iTime)
|
||||
{
|
||||
@unlink($sFileToRemove);
|
||||
if ($iFileNbToRemove-- === 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
$aFilesByTime = array_slice($aFilesByTime, $iFileCount - $iMaxFiles, null, true);
|
||||
$iFileCount = $iMaxFiles;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the list of files with their associated access time
|
||||
* @param string $sCheck Directory to scan
|
||||
* @param array $aFilesByTime used by recursion
|
||||
* @return array
|
||||
*/
|
||||
function apc_emul_list_files_time($sCheck, &$aFilesByTime = array())
|
||||
{
|
||||
// Garbage collection
|
||||
$aFiles = array_diff(@scandir($sCheck), array('.', '..'));
|
||||
foreach($aFiles as $sFile)
|
||||
{
|
||||
$sSubFile = $sCheck.'/'.$sFile;
|
||||
if (is_dir($sSubFile))
|
||||
{
|
||||
apc_emul_list_files_time($sSubFile, $aFilesByTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTime = apc_emul_get_file_time($sSubFile);
|
||||
if ($iTime !== false)
|
||||
{
|
||||
$aFilesByTime[$sSubFile] = $iTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aFilesByTime;
|
||||
}
|
||||
|
||||
/** Get the file access time if TTL is managed
|
||||
* @param string $sFilename
|
||||
* @return bool|int returns the file atime or false if not relevant
|
||||
*/
|
||||
function apc_emul_get_file_time($sFilename)
|
||||
{
|
||||
if (strpos(basename($sFilename), '-') === 0)
|
||||
{
|
||||
return @fileatime($sFilename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -702,7 +702,7 @@ abstract class AttributeDefinition
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Unknown verb '$sVerb' for attribute ".$this->GetCode().' in class '.get_class($oHostObj));
|
||||
throw new Exception("Unknown verb '$sVerb' for attribute ".$this->GetCode().' in class '.get_class($oHostObject));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1355,7 +1355,7 @@ class AttributeLinkedSet extends AttributeDefinition
|
||||
}
|
||||
else
|
||||
{
|
||||
$bAreEquivalent = $val1->Equals($val2);
|
||||
$bAreEquivalent = ($val2->HasDelta() === false);
|
||||
}
|
||||
return $bAreEquivalent;
|
||||
}
|
||||
@@ -3963,6 +3963,42 @@ class AttributeDateTime extends AttributeDBField
|
||||
return $oFormField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function EnumTemplateVerbs()
|
||||
{
|
||||
return array(
|
||||
'' => 'Formatted representation',
|
||||
'raw' => 'Not formatted representation',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function GetForTemplate($value, $sVerb, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
switch ($sVerb)
|
||||
{
|
||||
case '':
|
||||
case 'text':
|
||||
return static::GetFormat()->format($value);
|
||||
break;
|
||||
case 'html':
|
||||
// Note: Not passing formatted value as the method will format it.
|
||||
return $this->GetAsHTML($value);
|
||||
break;
|
||||
case 'raw':
|
||||
return $value;
|
||||
break;
|
||||
default:
|
||||
return parent::GetForTemplate($value, $sVerb, $oHostObject, $bLocalize);
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function ListExpectedParams()
|
||||
{
|
||||
return parent::ListExpectedParams();
|
||||
@@ -5207,75 +5243,34 @@ class AttributeBlob extends AttributeDefinition
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
// Facilitate things: allow administrators to upload a document
|
||||
// from a CSV by specifying its path/URL
|
||||
|
||||
/**
|
||||
* Users can provide the document from an URL (including an URL on iTop itself)
|
||||
* for CSV import. Administrators can even provide the path to a local file
|
||||
* {@inheritDoc}
|
||||
* @see AttributeDefinition::MakeRealValue()
|
||||
*/
|
||||
public function MakeRealValue($proposedValue, $oHostObj)
|
||||
{
|
||||
if ($proposedValue === null) return null;
|
||||
|
||||
if (is_object($proposedValue))
|
||||
{
|
||||
$proposedValue = clone $proposedValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file_exists($proposedValue) && UserRights::IsAdministrator())
|
||||
try
|
||||
{
|
||||
$sContent = file_get_contents($proposedValue);
|
||||
$sExtension = strtolower(pathinfo($proposedValue, PATHINFO_EXTENSION));
|
||||
$sMimeType = "application/x-octet-stream";
|
||||
$aKnownExtensions = array(
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12.xlsx',
|
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'pdf' => 'application/pdf',
|
||||
'doc' => 'application/msword',
|
||||
'dot' => 'application/msword',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'vsd' => 'application/x-visio',
|
||||
'vdx' => 'application/visio.drawing',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'zip' => 'application/zip',
|
||||
'txt' => 'text/plain',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'exe' => 'application/octet-stream'
|
||||
);
|
||||
|
||||
if (!array_key_exists($sExtension, $aKnownExtensions) && extension_loaded('fileinfo'))
|
||||
{
|
||||
$finfo = new finfo(FILEINFO_MIME);
|
||||
$sMimeType = $finfo->file($proposedValue);
|
||||
}
|
||||
return new ormDocument($sContent, $sMimeType);
|
||||
// Read the file from iTop, an URL (or the local file system - for admins only)
|
||||
$proposedValue = Utils::FileGetContentsAndMIMEType($proposedValue);
|
||||
}
|
||||
else
|
||||
catch(Exception $e)
|
||||
{
|
||||
return new ormDocument($proposedValue, 'text/plain');
|
||||
}
|
||||
IssueLog::Warning(get_class($this)."::MakeRealValue - ".$e->getMessage());
|
||||
// Not a real document !! store is as text !!! (This was the default behavior before)
|
||||
$proposedValue = new ormDocument($e->getMessage()." \n".$proposedValue, 'text/plain');
|
||||
}
|
||||
}
|
||||
return $proposedValue;
|
||||
}
|
||||
@@ -5390,6 +5385,11 @@ class AttributeBlob extends AttributeDefinition
|
||||
|
||||
public function GetAsCSV($sValue, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true, $bConvertToPlainText = false)
|
||||
{
|
||||
$sAttCode = $this->GetCode();
|
||||
if ($sValue instanceof ormDocument && !$sValue->IsEmpty())
|
||||
{
|
||||
return $sValue->GetDownloadURL(get_class($oHostObject), $oHostObject->GetKey(), $sAttCode);
|
||||
}
|
||||
return ''; // Not exportable in CSV !
|
||||
}
|
||||
|
||||
@@ -5493,48 +5493,49 @@ class AttributeImage extends AttributeBlob
|
||||
{
|
||||
public function GetEditClass() {return "Image";}
|
||||
|
||||
// Facilitate things: allow administrators to upload a document
|
||||
// from a CSV by specifying its path/URL
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see AttributeBlob::MakeRealValue()
|
||||
*/
|
||||
public function MakeRealValue($proposedValue, $oHostObj)
|
||||
{
|
||||
if (is_object($proposedValue))
|
||||
{
|
||||
$proposedValue = clone $proposedValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file_exists($proposedValue) && UserRights::IsAdministrator())
|
||||
{
|
||||
$sContent = file_get_contents($proposedValue);
|
||||
$sExtension = strtolower(pathinfo($proposedValue, PATHINFO_EXTENSION));
|
||||
$sMimeType = "application/x-octet-stream";
|
||||
$aKnownExtensions = array(
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png'
|
||||
);
|
||||
|
||||
if (!array_key_exists($sExtension, $aKnownExtensions) && extension_loaded('fileinfo'))
|
||||
{
|
||||
$finfo = new finfo(FILEINFO_MIME);
|
||||
$sMimeType = $finfo->file($proposedValue);
|
||||
}
|
||||
return new ormDocument($sContent, $sMimeType);
|
||||
}
|
||||
}
|
||||
return $proposedValue;
|
||||
$oDoc = parent::MakeRealValue($proposedValue, $oHostObj);
|
||||
// The validation of the MIME Type is done by CheckFormat below
|
||||
return $oDoc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that the supplied ormDocument actually contains an image
|
||||
* {@inheritDoc}
|
||||
* @see AttributeDefinition::CheckFormat()
|
||||
*/
|
||||
public function CheckFormat($value)
|
||||
{
|
||||
if ($value instanceof ormDocument && !$value->IsEmpty())
|
||||
{
|
||||
return ($value->GetMainMimeType() == 'image');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetAsHTML($value, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
$iMaxWidthPx = $this->Get('display_max_width');
|
||||
$iMaxHeightPx = $this->Get('display_max_height');
|
||||
$sUrl = $this->Get('default_image');
|
||||
$sRet = '<img src="'.$sUrl.'" style="max-width: '.$iMaxWidthPx.'px; max-height: '.$iMaxHeightPx.'px">';
|
||||
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="max-width: '.$iMaxWidthPx.'px; max-height: '.$iMaxHeightPx.'px">' : '';
|
||||
if (is_object($value) && !$value->IsEmpty())
|
||||
{
|
||||
$sUrl = $value->GetDownloadURL(get_class($oHostObject), $oHostObject->GetKey(), $this->GetCode());
|
||||
if ($oHostObject->IsNew() || ($oHostObject->IsModified() && (array_key_exists($this->GetCode(), $oHostObject->ListChanges()))))
|
||||
{
|
||||
// If the object is modified (or not yet stored in the database) we must serve the content of the image directly inline
|
||||
// otherwise (if we just give an URL) the browser will be given the wrong content... and may cache it
|
||||
$sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData());
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUrl = $value->GetDownloadURL(get_class($oHostObject), $oHostObject->GetKey(), $this->GetCode());
|
||||
}
|
||||
$sRet = '<img src="'.$sUrl.'" style="max-width: '.$iMaxWidthPx.'px; max-height: '.$iMaxHeightPx.'px">';
|
||||
}
|
||||
return '<div class="view-image" style="width: '.$iMaxWidthPx.'px; height: '.$iMaxHeightPx.'px;"><span class="helper-middle"></span>'.$sRet.'</div>';
|
||||
@@ -7370,7 +7371,7 @@ class AttributeCustomFields extends AttributeDefinition
|
||||
|
||||
public function GetEditValue($sValue, $oHostObj = null)
|
||||
{
|
||||
return 'GetEditValueNotImplemented for '.get_class($this);
|
||||
return $this->GetForTemplate($sValue, '', $oHostObj, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7773,3 +7774,16 @@ class AttributeObsolescenceFlag extends AttributeBoolean
|
||||
}
|
||||
}
|
||||
|
||||
class AttributeObsolescenceDate extends AttributeDate
|
||||
{
|
||||
public function GetLabel($sDefault = null)
|
||||
{
|
||||
$sDefault = Dict::S('Core:AttributeObsolescenceDate/Label', $sDefault);
|
||||
return parent::GetLabel($sDefault);
|
||||
}
|
||||
public function GetDescription($sDefault = null)
|
||||
{
|
||||
$sDefault = Dict::S('Core:AttributeObsolescenceDate/Label+', $sDefault);
|
||||
return parent::GetDescription($sDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,10 +468,11 @@ class BulkChange
|
||||
//
|
||||
foreach ($this->m_aAttList as $sAttCode => $iCol)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
|
||||
// skip the private key, if any
|
||||
if ($sAttCode == 'id') continue;
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
|
||||
// skip reconciliation keys
|
||||
if (!$oAttDef->IsWritable() && in_array($sAttCode, $this->m_aReconcilKeys)){ continue; }
|
||||
|
||||
|
||||
@@ -33,13 +33,15 @@ class MySQLException extends CoreException
|
||||
{
|
||||
if ($oException != null)
|
||||
{
|
||||
$aContext['mysql_error'] = $oException->getCode();
|
||||
$aContext['mysql_errno'] = $oException->getMessage();
|
||||
$aContext['mysql_errno'] = $oException->getCode();
|
||||
$this->code = $oException->getCode();
|
||||
$aContext['mysql_error'] = $oException->getMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||
$aContext['mysql_errno'] = CMDBSource::GetErrNo();
|
||||
$this->code = CMDBSource::GetErrNo();
|
||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||
}
|
||||
parent::__construct($sIssue, $aContext);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
|
||||
define('ITOP_APPLICATION', 'iTop');
|
||||
define('ITOP_VERSION', '2.4.x');
|
||||
define('ITOP_APPLICATION_SHORT', 'iTop');
|
||||
define('ITOP_VERSION', '2.4.0');
|
||||
define('ITOP_REVISION', 'svn');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
|
||||
@@ -435,6 +436,14 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
),
|
||||
'apc_cache_emulation.max_entries' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Maximum number of cache entries (0 means no limit)',
|
||||
'default' => 1000,
|
||||
'value' => 1000,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'timezone' => array(
|
||||
'type' => 'string',
|
||||
'description' => 'Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitely configured in PHP',
|
||||
|
||||
@@ -112,4 +112,13 @@ class SecurityException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Throwned when querying on an object that exists in the database but is archived
|
||||
*
|
||||
* @see N.1108
|
||||
*/
|
||||
class ArchivedObjectException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1731,6 +1731,14 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
$this->m_bIsInDB = true;
|
||||
$this->m_bDirty = false;
|
||||
foreach ($this->m_aCurrValues as $sAttCode => $value)
|
||||
{
|
||||
if (is_object($value))
|
||||
{
|
||||
$value = clone $value;
|
||||
}
|
||||
$this->m_aOrigValues[$sAttCode] = $value;
|
||||
}
|
||||
|
||||
$this->AfterInsert();
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
// Copyright (c) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// 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.
|
||||
@@ -15,14 +15,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Define filters for a given class of objects (formerly named "filter")
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
//
|
||||
|
||||
// Dev hack for disabling the some query build optimizations (Folding/Merging)
|
||||
define('ENABLE_OPT', true);
|
||||
@@ -33,7 +26,6 @@ class DBObjectSearch extends DBSearch
|
||||
private $m_aSelectedClasses; // selected for the output (alias => class name)
|
||||
private $m_oSearchCondition;
|
||||
private $m_aParams;
|
||||
private $m_aFullText;
|
||||
private $m_aPointingTo;
|
||||
private $m_aReferencedBy;
|
||||
|
||||
@@ -54,7 +46,6 @@ class DBObjectSearch extends DBSearch
|
||||
$this->m_aClasses = array($sClassAlias => $sClass);
|
||||
$this->m_oSearchCondition = new TrueExpression;
|
||||
$this->m_aParams = array();
|
||||
$this->m_aFullText = array();
|
||||
$this->m_aPointingTo = array();
|
||||
$this->m_aReferencedBy = array();
|
||||
}
|
||||
@@ -285,7 +276,6 @@ class DBObjectSearch extends DBSearch
|
||||
public function IsAny()
|
||||
{
|
||||
if (!$this->m_oSearchCondition->IsTrue()) return false;
|
||||
if (count($this->m_aFullText) > 0) return false;
|
||||
if (count($this->m_aPointingTo) > 0) return false;
|
||||
if (count($this->m_aReferencedBy) > 0) return false;
|
||||
return true;
|
||||
@@ -390,7 +380,7 @@ class DBObjectSearch extends DBSearch
|
||||
// Parse search strings if needed and if the filter code corresponds to a valid attcode
|
||||
if($bParseSeachString && MetaModel::IsValidAttCode($this->GetClass(), $sFilterCode))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->GetClass(), $sFilterCode);
|
||||
$value = $oAttDef->ParseSearchString($value);
|
||||
}
|
||||
|
||||
@@ -549,9 +539,24 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
public function AddCondition_FullText($sFullText)
|
||||
public function AddCondition_FullText($sNeedle)
|
||||
{
|
||||
$this->m_aFullText[] = $sFullText;
|
||||
// Transform the full text condition into additional condition expression
|
||||
$aFullTextFields = array();
|
||||
foreach (MetaModel::ListAttributeDefs($this->GetClass()) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (!$oAttDef->IsScalar()) continue;
|
||||
if ($oAttDef->IsExternalKey()) continue;
|
||||
$aFullTextFields[] = new FieldExpression($sAttCode, $this->GetClassAlias());
|
||||
}
|
||||
$oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
|
||||
|
||||
$sQueryParam = 'needle';
|
||||
$oFlexNeedle = new CharConcatExpression(array(new ScalarExpression('%'), new VariableExpression($sQueryParam), new ScalarExpression('%')));
|
||||
|
||||
$oNewCond = new BinaryExpression($oTextFields, 'LIKE', $oFlexNeedle);
|
||||
$this->AddConditionExpression($oNewCond);
|
||||
$this->m_aParams[$sQueryParam] = $sNeedle;
|
||||
}
|
||||
|
||||
protected function AddToNameSpace(&$aClassAliases, &$aAliasTranslation, $bTranslateMainAlias = true)
|
||||
@@ -973,8 +978,6 @@ class DBObjectSearch extends DBSearch
|
||||
// Translate search condition into our aliasing scheme
|
||||
$aAliasTranslation[$oFilter->GetClassAlias()]['*'] = $this->GetClassAlias();
|
||||
|
||||
$this->m_aFullText = array_merge($this->m_aFullText, $oFilter->m_aFullText);
|
||||
|
||||
foreach($oFilter->m_aPointingTo as $sExtKeyAttCode=>$aPointingTo)
|
||||
{
|
||||
foreach($aPointingTo as $iOperatorCode => $aFilter)
|
||||
@@ -1001,7 +1004,7 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
|
||||
public function GetCriteria() {return $this->m_oSearchCondition;}
|
||||
public function GetCriteria_FullText() {return $this->m_aFullText;}
|
||||
public function GetCriteria_FullText() {throw new Exception("Removed GetCriteria_FullText");}
|
||||
protected function GetCriteria_PointingTo($sKeyAttCode = "")
|
||||
{
|
||||
if (empty($sKeyAttCode))
|
||||
@@ -1119,11 +1122,6 @@ class DBObjectSearch extends DBSearch
|
||||
$sRes .= $this->ToOQL_Joins();
|
||||
$sRes .= " WHERE ".$this->m_oSearchCondition->Render($aParams, $bRetrofitParams);
|
||||
|
||||
// Temporary: add more info about other conditions, necessary to avoid strange behaviors with the cache
|
||||
foreach($this->m_aFullText as $sFullText)
|
||||
{
|
||||
$sRes .= " AND MATCHES '$sFullText'";
|
||||
}
|
||||
if ($bWithAllowAllFlag && $this->m_bAllowAllData)
|
||||
{
|
||||
$sRes .= " ALLOW ALL DATA";
|
||||
@@ -1468,10 +1466,32 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
// Create a unique cache id
|
||||
//
|
||||
$aContextData = array();
|
||||
$bCanCache = true;
|
||||
if (self::$m_bQueryCacheEnabled || self::$m_bTraceQueries)
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_URI']))
|
||||
{
|
||||
$aContextData['sRequestUri'] = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
else if (isset($_SERVER['SCRIPT_NAME']))
|
||||
{
|
||||
$aContextData['sRequestUri'] = $_SERVER['SCRIPT_NAME'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aContextData['sRequestUri'] = '';
|
||||
}
|
||||
|
||||
// Need to identify the query
|
||||
$sOqlQuery = $oSearch->ToOql(false, null, true);
|
||||
if ((strpos($sOqlQuery, '`id` IN (') !== false) || (strpos($sOqlQuery, '`id` NOT IN (') !== false))
|
||||
{
|
||||
// Requests containing "id IN" are not worth caching
|
||||
$bCanCache = false;
|
||||
}
|
||||
|
||||
$aContextData['sOqlQuery'] = $sOqlQuery;
|
||||
|
||||
if (count($aModifierProperties))
|
||||
{
|
||||
@@ -1482,12 +1502,14 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
$sModifierProperties = '';
|
||||
}
|
||||
$aContextData['sModifierProperties'] = $sModifierProperties;
|
||||
|
||||
$sRawId = $sOqlQuery.$sModifierProperties;
|
||||
if (!is_null($aAttToLoad))
|
||||
{
|
||||
$sRawId .= json_encode($aAttToLoad);
|
||||
}
|
||||
$aContextData['aAttToLoad'] = $aAttToLoad;
|
||||
if (!is_null($aGroupByExpr))
|
||||
{
|
||||
foreach($aGroupByExpr as $sAlias => $oExpr)
|
||||
@@ -1495,13 +1517,20 @@ class DBObjectSearch extends DBSearch
|
||||
$sRawId .= 'g:'.$sAlias.'!'.$oExpr->Render();
|
||||
}
|
||||
}
|
||||
$aContextData['aGroupByExpr'] = $aGroupByExpr;
|
||||
$sRawId .= $bGetCount;
|
||||
$aContextData['bGetCount'] = $bGetCount;
|
||||
if (is_array($aSelectedClasses))
|
||||
{
|
||||
$sRawId .= implode(',', $aSelectedClasses); // Unions may alter the list of selected columns
|
||||
}
|
||||
$sRawId .= $oSearch->GetArchiveMode() ? '--arch' : '';
|
||||
$sRawId .= $oSearch->GetShowObsoleteData() ? '--obso' : '';
|
||||
$aContextData['aSelectedClasses'] = $aSelectedClasses;
|
||||
$bIsArchiveMode = $oSearch->GetArchiveMode();
|
||||
$sRawId .= $bIsArchiveMode ? '--arch' : '';
|
||||
$bShowObsoleteData = $oSearch->GetShowObsoleteData();
|
||||
$sRawId .= $bShowObsoleteData ? '--obso' : '';
|
||||
$aContextData['bIsArchiveMode'] = $bIsArchiveMode;
|
||||
$aContextData['bShowObsoleteData'] = $bShowObsoleteData;
|
||||
$sOqlId = md5($sRawId);
|
||||
}
|
||||
else
|
||||
@@ -1557,8 +1586,9 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
if (self::$m_bQueryCacheEnabled)
|
||||
{
|
||||
if (self::$m_bUseAPCCache)
|
||||
if ($bCanCache && self::$m_bUseAPCCache)
|
||||
{
|
||||
$oSQLQuery->m_aContextData = $aContextData;
|
||||
$oKPI = new ExecutionKPI();
|
||||
apc_store($sOqlAPCCacheId, $oSQLQuery, self::$m_iQueryCacheTTL);
|
||||
$oKPI->ComputeStats('Query APC (store)', $sOqlQuery);
|
||||
@@ -1570,6 +1600,14 @@ class DBObjectSearch extends DBSearch
|
||||
return $oSQLQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aAttToLoad
|
||||
* @param $bGetCount
|
||||
* @param $aModifierProperties
|
||||
* @param null $aGroupByExpr
|
||||
* @param null $aSelectedClasses
|
||||
* @return null|SQLObjectQuery
|
||||
*/
|
||||
protected function BuildSQLQueryStruct($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr = null, $aSelectedClasses = null)
|
||||
{
|
||||
$oBuild = new QueryBuilderContext($this, $aModifierProperties, $aGroupByExpr, $aSelectedClasses);
|
||||
@@ -1614,6 +1652,12 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $oBuild
|
||||
* @param null $aAttToLoad
|
||||
* @param array $aValues
|
||||
* @return null|SQLObjectQuery
|
||||
*/
|
||||
protected function MakeSQLObjectQuery(&$oBuild, $aAttToLoad = null, $aValues = array())
|
||||
{
|
||||
// Note: query class might be different than the class of the filter
|
||||
@@ -1623,9 +1667,9 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
$bIsOnQueriedClass = array_key_exists($sClassAlias, $oBuild->GetRootFilter()->GetSelectedClasses());
|
||||
|
||||
self::DbgTrace("Entering: ".$this->ToOQL().", ".($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
|
||||
//self::DbgTrace("Entering: ".$this->ToOQL().", ".($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
|
||||
|
||||
$sRootClass = MetaModel::GetRootClass($sClass);
|
||||
//$sRootClass = MetaModel::GetRootClass($sClass);
|
||||
$sKeyField = MetaModel::DBGetKey($sClass);
|
||||
|
||||
if ($bIsOnQueriedClass)
|
||||
@@ -1658,30 +1702,10 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the full text condition into additional condition expression
|
||||
$aFullText = $this->GetCriteria_FullText();
|
||||
if (count($aFullText) > 0)
|
||||
{
|
||||
$aFullTextFields = array();
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (!$oAttDef->IsScalar()) continue;
|
||||
if ($oAttDef->IsExternalKey()) continue;
|
||||
$aFullTextFields[] = new FieldExpression($sAttCode, $sClassAlias);
|
||||
}
|
||||
$oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
|
||||
|
||||
foreach($aFullText as $sFTNeedle)
|
||||
{
|
||||
$oNewCond = new BinaryExpression($oTextFields, 'LIKE', new ScalarExpression("%$sFTNeedle%"));
|
||||
$oBuild->m_oQBExpressions->AddCondition($oNewCond);
|
||||
}
|
||||
}
|
||||
}
|
||||
//echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
|
||||
//echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
|
||||
$aExpectedAtts = array(); // array of (attcode => fieldexpression)
|
||||
//echo "<p>".__LINE__.": GetUnresolvedFields($sClassAlias, ...)</p>\n";
|
||||
//echo "<p>".__LINE__.": GetUnresolvedFields($sClassAlias, ...)</p>\n";
|
||||
$oBuild->m_oQBExpressions->GetUnresolvedFields($sClassAlias, $aExpectedAtts);
|
||||
|
||||
// Compute a clear view of required joins (from the current class)
|
||||
@@ -1798,37 +1822,46 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
// First query built upon on the leaf (ie current) class
|
||||
// First query built from the root, adding all tables including the leaf
|
||||
// Before N.1065 we were joining from the leaf first, but this wasn't a good choice :
|
||||
// most of the time (obsolescence, friendlyname, ...) we want to get a root attribute !
|
||||
//
|
||||
self::DbgTrace("Main (=leaf) class, call MakeSQLObjectQuerySingleTable()");
|
||||
if (MetaModel::HasTable($sClass))
|
||||
$oSelectBase = null;
|
||||
$aClassHierarchy = MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, true);
|
||||
$bIsClassStandaloneClass = (count($aClassHierarchy) == 1);
|
||||
foreach($aClassHierarchy as $sSomeClass)
|
||||
{
|
||||
$oSelectBase = $this->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sClass, $aExtKeys, $aValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSelectBase = null;
|
||||
if (!MetaModel::HasTable($sSomeClass))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// As the join will not filter on the expected classes, we have to specify it explicitely
|
||||
$sExpectedClasses = implode("', '", MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL));
|
||||
$oFinalClassRestriction = Expression::FromOQL("`$sClassAlias`.finalclass IN ('$sExpectedClasses')");
|
||||
$oBuild->m_oQBExpressions->AddCondition($oFinalClassRestriction);
|
||||
}
|
||||
|
||||
// Then we join the queries of the eventual parent classes (compound model)
|
||||
foreach(MetaModel::EnumParentClasses($sClass) as $sParentClass)
|
||||
{
|
||||
if (!MetaModel::HasTable($sParentClass)) continue;
|
||||
|
||||
self::DbgTrace("Parent class: $sParentClass... let's call MakeSQLObjectQuerySingleTable()");
|
||||
$oSelectParentTable = $this->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sParentClass, $aExtKeys, $aValues);
|
||||
self::DbgTrace("Adding join from root to leaf: $sSomeClass... let's call MakeSQLObjectQuerySingleTable()");
|
||||
$oSelectParentTable = $this->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sSomeClass, $aExtKeys, $aValues);
|
||||
if (is_null($oSelectBase))
|
||||
{
|
||||
$oSelectBase = $oSelectParentTable;
|
||||
if (!$bIsClassStandaloneClass && (MetaModel::IsRootClass($sSomeClass)))
|
||||
{
|
||||
// As we're linking to root class first, we're adding a where clause on the finalClass attribute :
|
||||
// COALESCE($sRootClassFinalClass IN ('$sExpectedClasses'), 1)
|
||||
// If we don't, the child classes can be removed in the query optimisation phase, including the leaf that was queried
|
||||
// So we still need to filter records to only those corresponding to the child classes !
|
||||
// The coalesce is mandatory if we have a polymorphic query (left join)
|
||||
$oClassListExpr = ListExpression::FromScalars(MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL));
|
||||
$sFinalClassSqlColumnName = MetaModel::DBGetClassField($sSomeClass);
|
||||
$oClassExpr = new FieldExpression($sFinalClassSqlColumnName, $oSelectBase->GetTableAlias());
|
||||
$oInExpression = new BinaryExpression($oClassExpr, 'IN', $oClassListExpr);
|
||||
$oTrueExpression = new TrueExpression();
|
||||
$aCoalesceAttr = array($oInExpression, $oTrueExpression);
|
||||
$oFinalClassRestriction = new FunctionExpression("COALESCE", $aCoalesceAttr);
|
||||
|
||||
$oBuild->m_oQBExpressions->AddCondition($oFinalClassRestriction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSelectBase->AddInnerJoin($oSelectParentTable, $sKeyField, MetaModel::DBGetKey($sParentClass));
|
||||
$oSelectBase->AddInnerJoin($oSelectParentTable, $sKeyField, MetaModel::DBGetKey($sSomeClass));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2159,8 +2192,14 @@ class DBObjectSearch extends DBSearch
|
||||
* Get the expression for the class and its subclasses (if finalclass = 'subclass' ...)
|
||||
* Simplifies the final expression by grouping classes having the same expression
|
||||
*/
|
||||
static protected function GetPolymorphicExpression($sClass, $sAttCode)
|
||||
static public function GetPolymorphicExpression($sClass, $sAttCode)
|
||||
{
|
||||
$oExpression = ExpressionCache::GetCachedExpression($sClass, $sAttCode);
|
||||
if (!empty($oExpression))
|
||||
{
|
||||
return $oExpression;
|
||||
}
|
||||
|
||||
// 1st step - get all of the required expressions (instantiable classes)
|
||||
// and group them using their OQL representation
|
||||
//
|
||||
|
||||
@@ -69,7 +69,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
* @var int
|
||||
*/
|
||||
protected $m_iCurrRow;
|
||||
/*
|
||||
/**
|
||||
* @var DBSearch
|
||||
*/
|
||||
protected $m_oFilter;
|
||||
@@ -195,11 +195,25 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad);
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad] = $oAttDef;
|
||||
if ($oAttDef->IsExternalKey())
|
||||
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
||||
{
|
||||
// Add the external key friendly name anytime
|
||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad.'_friendlyname');
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad.'_friendlyname'] = $oFriendlyNameAttDef;
|
||||
|
||||
if (MetaModel::IsArchivable($oAttDef->GetTargetClass(EXTKEY_ABSOLUTE)))
|
||||
{
|
||||
// Add the archive flag if necessary
|
||||
$oArchiveFlagAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad.'_archive_flag');
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad.'_archive_flag'] = $oArchiveFlagAttDef;
|
||||
}
|
||||
|
||||
if (MetaModel::IsObsoletable($oAttDef->GetTargetClass(EXTKEY_ABSOLUTE)))
|
||||
{
|
||||
// Add the obsolescence flag if necessary
|
||||
$oObsoleteFlagAttDef = MetaModel::GetAttributeDef($sClass, $sAttToLoad.'_obsolescence_flag');
|
||||
$aAttToLoadWithAttDef[$sClassAlias][$sAttToLoad.'_obsolescence_flag'] = $oObsoleteFlagAttDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,6 +221,20 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, 'friendlyname');
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['friendlyname'] = $oFriendlyNameAttDef;
|
||||
|
||||
if (MetaModel::IsArchivable($sClass))
|
||||
{
|
||||
// Add the archive flag if necessary
|
||||
$oArchiveFlagAttDef = MetaModel::GetAttributeDef($sClass, 'archive_flag');
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['archive_flag'] = $oArchiveFlagAttDef;
|
||||
}
|
||||
|
||||
if (MetaModel::IsObsoletable($sClass))
|
||||
{
|
||||
// Add the obsolescence flag if necessary
|
||||
$oObsoleteFlagAttDef = MetaModel::GetAttributeDef($sClass, 'obsolescence_flag');
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['obsolescence_flag'] = $oObsoleteFlagAttDef;
|
||||
}
|
||||
|
||||
// Make sure that the final class is requested anytime, whatever the specification (needed for object construction!)
|
||||
if (!MetaModel::IsStandaloneClass($sClass) && !array_key_exists('finalclass', $aAttToLoadWithAttDef[$sClassAlias]))
|
||||
{
|
||||
@@ -312,7 +340,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might to rewind it.
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might want to rewind it.
|
||||
*
|
||||
* @param bool $bWithId
|
||||
* @return array
|
||||
@@ -386,7 +414,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might to rewind it.
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might want to rewind it.
|
||||
*
|
||||
* @param string $sAttCode
|
||||
* @param bool $bWithId
|
||||
@@ -598,14 +626,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
// Note: it is mandatory to set this value now, to protect against reentrance
|
||||
$this->m_bLoaded = true;
|
||||
|
||||
if ($this->m_iLimitCount > 0)
|
||||
{
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec, $this->m_iLimitCount, $this->m_iLimitStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
$sSQL = $this->_makeSelectQuery($this->m_aAttToLoad);
|
||||
|
||||
if (is_object($this->m_oSQLResult))
|
||||
{
|
||||
@@ -614,8 +635,36 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
$this->m_iNumTotalDBRows = null;
|
||||
|
||||
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
||||
|
||||
try
|
||||
{
|
||||
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
||||
} catch (MySQLException $e)
|
||||
{
|
||||
// 1116 = ER_TOO_MANY_TABLES
|
||||
// https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_too_many_tables
|
||||
if ($e->getCode() != 1116)
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// N.689 Workaround for the 61 max joins in MySQL : full lazy load !
|
||||
$aAttToLoad = array();
|
||||
foreach($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||
{
|
||||
$aAttToLoad[$sClassAlias] = array();
|
||||
$bIsAbstractClass = MetaModel::IsAbstract($sClass);
|
||||
$bIsClassWithChildren = MetaModel::HasChildrenClasses($sClass);
|
||||
if ($bIsAbstractClass || $bIsClassWithChildren)
|
||||
{
|
||||
// we need finalClass field at least to be able to instantiate the real corresponding object !
|
||||
$aAttToLoad[$sClassAlias]['finalclass'] = MetaModel::GetAttributeDef($sClass, 'finalclass');
|
||||
}
|
||||
}
|
||||
$sSQL = $this->_makeSelectQuery($aAttToLoad);
|
||||
$this->m_oSQLResult = CMDBSource::Query($sSQL); // may fail again
|
||||
}
|
||||
|
||||
if ($this->m_oSQLResult === false) return;
|
||||
|
||||
if (($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
||||
@@ -626,10 +675,33 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of rows in this set. Independently of the SetLimit used for loading the set and taking into account the rows added in-memory.
|
||||
*
|
||||
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a SetLimit
|
||||
*
|
||||
* @param string[] $aAttToLoad
|
||||
*
|
||||
* @return string SQL query
|
||||
*/
|
||||
private function _makeSelectQuery($aAttToLoad)
|
||||
{
|
||||
if ($this->m_iLimitCount > 0)
|
||||
{
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $aAttToLoad,
|
||||
$this->m_aExtendedDataSpec, $this->m_iLimitCount, $this->m_iLimitStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $aAttToLoad,
|
||||
$this->m_aExtendedDataSpec);
|
||||
}
|
||||
|
||||
return $sSQL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of rows in this set. Independently of the SetLimit used for loading the set and taking into
|
||||
* account the rows added in-memory.
|
||||
*
|
||||
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a
|
||||
* SetLimit
|
||||
*
|
||||
* @return int The total number of rows for this set.
|
||||
*/
|
||||
public function Count()
|
||||
@@ -639,11 +711,12 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return 0;
|
||||
|
||||
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
$this->m_iNumTotalDBRows = $aRow['COUNT'];
|
||||
}
|
||||
|
||||
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
||||
}
|
||||
|
||||
|
||||
@@ -835,4 +835,9 @@ abstract class DBSearch
|
||||
CMDBSource::Query($sUpdateQuery);
|
||||
}
|
||||
}
|
||||
|
||||
public function UpdateContextFromUser()
|
||||
{
|
||||
$this->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -408,4 +408,30 @@ class EventLoginUsage extends Event
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
class EventOnObject extends Event
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
"order_by_default" => array('date' => false)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>"obj_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>"obj_key", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,10 +188,10 @@ EOF
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
|
||||
}
|
||||
else if ($value instanceOf ormCustomFieldsValue)
|
||||
else if ($value instanceOf ormDocument)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
|
||||
$sRet = $oAttDef->GetAsCSV($value, "\n", '', $oObj);
|
||||
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
110
core/expressioncache.class.inc.php
Normal file
110
core/expressioncache.class.inc.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
// Copyright (c) 2010-2017 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/>
|
||||
//
|
||||
|
||||
class ExpressionCache
|
||||
{
|
||||
static private $aCache = array();
|
||||
|
||||
static public function GetCachedExpression($sClass, $sAttCode)
|
||||
{
|
||||
// read current cache
|
||||
@include_once (static::GetCacheFileName());
|
||||
|
||||
$oExpr = null;
|
||||
$sKey = static::GetKey($sClass, $sAttCode);
|
||||
if (array_key_exists($sKey, static::$aCache))
|
||||
{
|
||||
$oExpr = static::$aCache[$sKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (class_exists('ExpressionCacheData'))
|
||||
{
|
||||
if (array_key_exists($sKey, ExpressionCacheData::$aCache))
|
||||
{
|
||||
$sVal = ExpressionCacheData::$aCache[$sKey];
|
||||
$oExpr = unserialize($sVal);
|
||||
static::$aCache[$sKey] = $oExpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oExpr;
|
||||
}
|
||||
|
||||
|
||||
static public function Warmup()
|
||||
{
|
||||
$sFilePath = static::GetCacheFileName();
|
||||
|
||||
if (!is_file($sFilePath))
|
||||
{
|
||||
$content = <<<EOF
|
||||
<?php
|
||||
// Copyright (c) 2010-2017 Combodo SARL
|
||||
// Generated Expression Cache file
|
||||
|
||||
class ExpressionCacheData
|
||||
{
|
||||
static \$aCache = array(
|
||||
EOF;
|
||||
|
||||
foreach(MetaModel::GetClasses() as $sClass)
|
||||
{
|
||||
$content .= static::GetSerializedExpression($sClass, 'friendlyname');
|
||||
if (MetaModel::IsObsoletable($sClass))
|
||||
{
|
||||
$content .= static::GetSerializedExpression($sClass, 'obsolescence_flag');
|
||||
}
|
||||
}
|
||||
|
||||
$content .= <<<EOF
|
||||
);
|
||||
}
|
||||
EOF;
|
||||
|
||||
file_put_contents($sFilePath, $content);
|
||||
}
|
||||
}
|
||||
|
||||
static private function GetSerializedExpression($sClass, $sAttCode)
|
||||
{
|
||||
$sKey = static::GetKey($sClass, $sAttCode);
|
||||
$oExpr = DBObjectSearch::GetPolymorphicExpression($sClass, $sAttCode);
|
||||
return "'".$sKey."' => '".serialize($oExpr)."',\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sClass
|
||||
* @param $sAttCode
|
||||
* @return string
|
||||
*/
|
||||
static private function GetKey($sClass, $sAttCode)
|
||||
{
|
||||
return $sClass.'::'.$sAttCode;
|
||||
}
|
||||
|
||||
public static function GetCacheFileName()
|
||||
{
|
||||
return utils::GetCachePath().'expressioncache.php';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
// Copyright (c) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
//
|
||||
|
||||
require_once(APPROOT.'core/modulehandler.class.inc.php');
|
||||
require_once(APPROOT.'core/querybuildercontext.class.inc.php');
|
||||
@@ -23,6 +24,7 @@ require_once(APPROOT.'core/metamodelmodifier.inc.php');
|
||||
require_once(APPROOT.'core/computing.inc.php');
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
require_once(APPROOT.'core/apc-compat.php');
|
||||
require_once(APPROOT.'core/expressioncache.class.inc.php');
|
||||
|
||||
/**
|
||||
* Metamodel
|
||||
@@ -331,9 +333,16 @@ abstract class MetaModel
|
||||
}
|
||||
final static public function GetObsolescenceExpression($sClass)
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
$sOql = self::$m_aClassParams[$sClass]['obsolescence_expression'];
|
||||
$oRet = Expression::FromOQL("COALESCE($sOql, 0)");
|
||||
if (self::IsObsoletable($sClass))
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
$sOql = self::$m_aClassParams[$sClass]['obsolescence_expression'];
|
||||
$oRet = Expression::FromOQL("COALESCE($sOql, 0)");
|
||||
}
|
||||
else
|
||||
{
|
||||
$oRet = Expression::FromOQL("0");
|
||||
}
|
||||
return $oRet;
|
||||
}
|
||||
final static public function GetNameSpec($sClass)
|
||||
@@ -1857,15 +1866,13 @@ abstract class MetaModel
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare external fields and filters
|
||||
// Add final class to external keys
|
||||
//
|
||||
// Add magic attributes to the classes
|
||||
foreach (self::GetClasses() as $sClass)
|
||||
{
|
||||
$sRootClass = self::$m_aRootClasses[$sClass];
|
||||
|
||||
// Create the friendly name attribute
|
||||
$sFriendlyNameAttCode = 'friendlyname';
|
||||
$sFriendlyNameAttCode = 'friendlyname';
|
||||
$oFriendlyName = new AttributeFriendlyName($sFriendlyNameAttCode);
|
||||
self::AddMagicAttribute($oFriendlyName, $sClass);
|
||||
|
||||
@@ -1875,7 +1882,7 @@ abstract class MetaModel
|
||||
$oArchiveFlag = new AttributeArchiveFlag('archive_flag');
|
||||
self::AddMagicAttribute($oArchiveFlag, $sClass);
|
||||
|
||||
$oArchiveDate = new AttributeDate('archive_date', array('magic' => true, "allowed_values"=>null, "sql"=>'archive_date', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array()));
|
||||
$oArchiveDate = new AttributeArchiveDate('archive_date', array('magic' => true, "allowed_values" => null, "sql" => 'archive_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
||||
self::AddMagicAttribute($oArchiveDate, $sClass);
|
||||
}
|
||||
elseif (self::$m_aClassParams[$sClass]["archive"])
|
||||
@@ -1898,7 +1905,7 @@ abstract class MetaModel
|
||||
|
||||
if (self::$m_aRootClasses[$sClass] == $sClass)
|
||||
{
|
||||
$oObsolescenceDate = new AttributeDate('obsolescence_date', array('magic' => true, "allowed_values" => null, "sql" => 'obsolescence_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
||||
$oObsolescenceDate = new AttributeObsolescenceDate('obsolescence_date', array('magic' => true, "allowed_values" => null, "sql" => 'obsolescence_date', "default_value" => '', "is_null_allowed" => true, "depends_on" => array()));
|
||||
self::AddMagicAttribute($oObsolescenceDate, $sClass);
|
||||
}
|
||||
else
|
||||
@@ -1909,6 +1916,13 @@ abstract class MetaModel
|
||||
self::$m_aAttribOrigins[$sClass]['obsolescence_date'] = $sRootClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare external fields and filters
|
||||
// Add final class to external keys
|
||||
// Add magic attributes to external keys (finalclass, friendlyname, archive_flag, obsolescence_flag)
|
||||
foreach (self::GetClasses() as $sClass)
|
||||
{
|
||||
foreach (self::$m_aAttribDefs[$sClass] as $sAttCode => $oAttDef)
|
||||
{
|
||||
// Compute the filter codes
|
||||
@@ -4394,6 +4408,8 @@ abstract class MetaModel
|
||||
echo "Debug<br/>\n";
|
||||
self::static_var_dump();
|
||||
}
|
||||
|
||||
ExpressionCache::Warmup();
|
||||
}
|
||||
|
||||
public static function LoadConfig($oConfiguration, $bAllowCache = false)
|
||||
@@ -4590,6 +4606,14 @@ abstract class MetaModel
|
||||
return self::$m_oConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The environment in which the model has been loaded (e.g. 'production')
|
||||
*/
|
||||
public static function GetEnvironment()
|
||||
{
|
||||
return self::$m_sEnvironment;
|
||||
}
|
||||
|
||||
public static function GetEnvironmentId()
|
||||
{
|
||||
return md5(APPROOT).'-'.self::$m_sEnvironment;
|
||||
@@ -4675,6 +4699,18 @@ abstract class MetaModel
|
||||
return $iTotalHits.' ('.implode(', ', $aRes).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param int $iKey
|
||||
* @param bool $bMustBeFound
|
||||
* @param bool $bAllowAllData if true then no rights filtering
|
||||
* @param array $aModifierProperties
|
||||
*
|
||||
* @return string[] column name / value array
|
||||
* @throws CoreException if no result found and $bMustBeFound=true
|
||||
*
|
||||
* @see utils::PushArchiveMode() to enable search on archived objects
|
||||
*/
|
||||
public static function MakeSingleRow($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
|
||||
{
|
||||
// Build the query cache signature
|
||||
@@ -4731,13 +4767,27 @@ abstract class MetaModel
|
||||
|
||||
$aRow = CMDBSource::FetchArray($res);
|
||||
CMDBSource::FreeResult($res);
|
||||
|
||||
if ($bMustBeFound && empty($aRow))
|
||||
{
|
||||
throw new CoreException("No result for the single row query: '$sSQL'");
|
||||
}
|
||||
|
||||
return $aRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a column name / value array to a {@link DBObject}
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param string[] $aRow column name / value array
|
||||
* @param string $sClassAlias
|
||||
* @param string[] $aAttToLoad
|
||||
* @param array $aExtendedDataSpec
|
||||
*
|
||||
* @return DBObject
|
||||
* @throws CoreException if finalClass cannot be found
|
||||
*/
|
||||
public static function GetObjectByRow($sClass, $aRow, $sClassAlias = '', $aAttToLoad = null, $aExtendedDataSpec = null)
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
@@ -4771,30 +4821,75 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sClass
|
||||
* Search for the specified class and id.
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param $iKey
|
||||
* @param bool $bMustBeFound
|
||||
* @param bool $bAllowAllData
|
||||
* @param null $aModifierProperties
|
||||
* @return DBObject|null
|
||||
* @return DBObject|null null if : (the object is not found) or (archive mode disabled and object is archived and $bMustBeFound=false)
|
||||
* @throws CoreException if no result found and $bMustBeFound=true
|
||||
* @throws ArchivedObjectException if archive mode disabled and result is archived and $bMustBeFound=true
|
||||
*
|
||||
* @see MetaModel::GetObjectWithArchive to get object even if it's archived
|
||||
* @see utils::PushArchiveMode() to enable search on archived objects
|
||||
*/
|
||||
public static function GetObject($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
$oObject = self::GetObjectWithArchive($sClass, $iKey, $bMustBeFound, $bAllowAllData, $aModifierProperties);
|
||||
|
||||
if (empty($oObject))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!utils::IsArchiveMode() && $oObject->IsArchived())
|
||||
{
|
||||
if ($bMustBeFound)
|
||||
{
|
||||
throw new ArchivedObjectException("The object $sClass::$iKey is archived");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the specified class and id. If the object is archived it will be returned anyway (this is for pre-2.4
|
||||
* module compatibility, see N.1108)
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param int $iKey
|
||||
* @param bool $bMustBeFound
|
||||
* @param bool $bAllowAllData
|
||||
* @param array $aModifierProperties
|
||||
*
|
||||
* @return DBObject|null
|
||||
* @throws CoreException if no result found and $bMustBeFound=true
|
||||
*
|
||||
* @since 2.4 introduction of the archive functionalities
|
||||
*
|
||||
* @see MetaModel::GetObject() same but returns null or ArchivedObjectFoundException if object exists but is archived
|
||||
*/
|
||||
public static function GetObjectWithArchive($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
|
||||
utils::PushArchiveMode(true);
|
||||
$aRow = self::MakeSingleRow($sClass, $iKey, $bMustBeFound, $bAllowAllData, $aModifierProperties);
|
||||
utils::PopArchiveMode();
|
||||
|
||||
if (empty($aRow))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return self::GetObjectByRow($sClass, $aRow);
|
||||
}
|
||||
|
||||
public static function GetObjectWithArchive($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
|
||||
{
|
||||
utils::PushArchiveMode(true);
|
||||
$oObject = static::GetObject($sClass, $iKey, $bMustBeFound, $bAllowAllData, $aModifierProperties);
|
||||
utils::PopArchiveMode();
|
||||
return $oObject;
|
||||
return self::GetObjectByRow($sClass, $aRow); // null should not be returned, this is handled in the callee
|
||||
}
|
||||
|
||||
public static function GetObjectByName($sClass, $sName, $bMustBeFound = true)
|
||||
@@ -5226,21 +5321,12 @@ abstract class MetaModel
|
||||
|
||||
public static function GetCacheEntries($sEnvironment = null)
|
||||
{
|
||||
if (!function_exists('apc_cache_info')) return array();
|
||||
if (is_null($sEnvironment))
|
||||
{
|
||||
$sEnvironment = MetaModel::GetEnvironmentId();
|
||||
}
|
||||
$aEntries = array();
|
||||
if (extension_loaded('apcu'))
|
||||
{
|
||||
// Beware: APCu behaves slightly differently from APC !!
|
||||
$aCacheUserData = @apc_cache_info();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCacheUserData = @apc_cache_info('user');
|
||||
}
|
||||
$aCacheUserData = apc_cache_info_compat();
|
||||
if (is_array($aCacheUserData) && isset($aCacheUserData['cache_list']))
|
||||
{
|
||||
$sPrefix = 'itop-'.$sEnvironment.'-';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
// Copyright (c) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// 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.
|
||||
@@ -15,14 +15,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* General definition of an expression tree (could be OQL, SQL or whatever)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
//
|
||||
|
||||
class MissingQueryArgument extends CoreException
|
||||
{
|
||||
@@ -89,9 +82,15 @@ abstract class Expression
|
||||
*/
|
||||
static public function FromOQL($sConditionExpr)
|
||||
{
|
||||
static $aCache = array();
|
||||
if (array_key_exists($sConditionExpr, $aCache))
|
||||
{
|
||||
return $aCache[$sConditionExpr];
|
||||
}
|
||||
$oOql = new OqlInterpreter($sConditionExpr);
|
||||
$oExpression = $oOql->ParseExpression();
|
||||
|
||||
$aCache[$sConditionExpr] = $oExpression;
|
||||
|
||||
return $oExpression;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,8 +191,15 @@ class ormCaseLog {
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->m_sLog;
|
||||
if($this->IsEmpty()) return '';
|
||||
|
||||
return $this->m_sLog;
|
||||
}
|
||||
|
||||
public function IsEmpty()
|
||||
{
|
||||
return ($this->m_sLog === null);
|
||||
}
|
||||
|
||||
public function ClearModifiedFlag()
|
||||
{
|
||||
|
||||
@@ -51,6 +51,8 @@ class ormDocument
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
if($this->IsEmpty()) return '';
|
||||
|
||||
return MyHelpers::beautifulstr($this->m_data, 100, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
* Object from the original set, minus the removed objects
|
||||
* @var DBObject[] array of iObjectId => DBObject
|
||||
*/
|
||||
protected $aPreserved;
|
||||
protected $aPreserved = array();
|
||||
|
||||
/**
|
||||
* @var DBObject[] New items
|
||||
@@ -130,12 +130,10 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
/**
|
||||
* @param DBObject $oObject
|
||||
* @param string $sClassAlias
|
||||
* @deprecated
|
||||
* @deprecated Since iTop 2.4, use ormLinkset->AddItem() instead.
|
||||
*/
|
||||
public function AddObject(DBObject $oObject, $sClassAlias = '')
|
||||
{
|
||||
trigger_error('iTop: ormLinkSet::AddObject() is deprecated use ormLinkSet::AddItem() instead.', E_USER_DEPRECATED);
|
||||
|
||||
$this->AddItem($oObject);
|
||||
}
|
||||
|
||||
@@ -158,9 +156,14 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
public function ModifyItem(DBObject $oLink)
|
||||
{
|
||||
assert($oLink instanceof $this->sClass);
|
||||
|
||||
$iObjectId = $oLink->GetKey();
|
||||
$this->aModified[$iObjectId] = $oLink;
|
||||
$this->bHasDelta = true;
|
||||
if (array_key_exists($iObjectId, $this->aPreserved))
|
||||
{
|
||||
unset($this->aPreserved[$iObjectId]);
|
||||
$this->aModified[$iObjectId] = $oLink;
|
||||
$this->bHasDelta = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function LoadOriginalIds()
|
||||
@@ -169,15 +172,22 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
{
|
||||
if ($this->oOriginalSet)
|
||||
{
|
||||
$this->aOriginalObjects = $this->oOriginalSet->ToArray();
|
||||
$this->aOriginalObjects = $this->GetArrayOfIndex();
|
||||
$this->aPreserved = $this->aOriginalObjects; // Copy (not effective until aPreserved gets modified)
|
||||
foreach ($this->aRemoved as $iObjectId)
|
||||
{
|
||||
if (array_key_exists($iObjectId, $this->aPreserved))
|
||||
{
|
||||
unset($this->aPreserved[$iObjectId]);
|
||||
}
|
||||
}
|
||||
foreach ($this->aRemoved as $iObjectId)
|
||||
{
|
||||
if (array_key_exists($iObjectId, $this->aPreserved))
|
||||
{
|
||||
unset($this->aPreserved[$iObjectId]);
|
||||
}
|
||||
}
|
||||
foreach ($this->aModified as $iObjectId => $oLink)
|
||||
{
|
||||
if (array_key_exists($iObjectId, $this->aPreserved))
|
||||
{
|
||||
unset($this->aPreserved[$iObjectId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -189,17 +199,29 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might want to rewind it.
|
||||
* @return array
|
||||
*/
|
||||
protected function GetArrayOfIndex()
|
||||
{
|
||||
$aRet = array();
|
||||
$this->oOriginalSet->Rewind();
|
||||
$iRow = 0;
|
||||
while ($oObject = $this->oOriginalSet->Fetch())
|
||||
{
|
||||
$aRet[$oObject->GetKey()] = $iRow++;
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might to rewind it.
|
||||
*
|
||||
* @param bool $bWithId
|
||||
* @return array
|
||||
* @deprecated
|
||||
* @deprecated Since iTop 2.4, use foreach($this as $oItem){} instead
|
||||
*/
|
||||
public function ToArray($bWithId = true)
|
||||
{
|
||||
trigger_error('iTop: ormLinkSet::ToArray() is deprecated use foreach instead.', E_USER_DEPRECATED);
|
||||
|
||||
$aRet = array();
|
||||
foreach($this as $oItem)
|
||||
{
|
||||
@@ -215,6 +237,28 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAttCode
|
||||
* @param bool $bWithId
|
||||
* @return array
|
||||
*/
|
||||
public function GetColumnAsArray($sAttCode, $bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
foreach($this as $oItem)
|
||||
{
|
||||
if ($bWithId)
|
||||
{
|
||||
$aRet[$oItem->GetKey()] = $oItem->Get($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[] = $oItem->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* The class of the objects of the collection (at least a common ancestor)
|
||||
*
|
||||
@@ -233,7 +277,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
public function Count()
|
||||
{
|
||||
$this->LoadOriginalIds();
|
||||
$iRet = count($this->aPreserved) + count($this->aAdded);
|
||||
$iRet = count($this->aPreserved) + count($this->aAdded) + count($this->aModified);
|
||||
return $iRet;
|
||||
}
|
||||
|
||||
@@ -290,11 +334,21 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
$iPreservedCount = count($this->aPreserved);
|
||||
if ($this->iCursor < $iPreservedCount)
|
||||
{
|
||||
$oRet = current($this->aPreserved);
|
||||
$iRet = current($this->aPreserved);
|
||||
$this->oOriginalSet->Seek($iRet);
|
||||
$oRet = $this->oOriginalSet->Fetch();
|
||||
}
|
||||
else
|
||||
{
|
||||
$oRet = current($this->aAdded);
|
||||
$iModifiedCount = count($this->aModified);
|
||||
if($this->iCursor < $iPreservedCount + $iModifiedCount)
|
||||
{
|
||||
$oRet = current($this->aModified);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oRet = current($this->aAdded);
|
||||
}
|
||||
}
|
||||
return $oRet;
|
||||
}
|
||||
@@ -315,9 +369,17 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
}
|
||||
else
|
||||
{
|
||||
next($this->aAdded);
|
||||
$iModifiedCount = count($this->aModified);
|
||||
if($this->iCursor < $iPreservedCount + $iModifiedCount)
|
||||
{
|
||||
next($this->aModified);
|
||||
}
|
||||
else
|
||||
{
|
||||
next($this->aAdded);
|
||||
}
|
||||
}
|
||||
// Increment AFTER moving the internal cursors because when starting aAdded, we must leave it intact
|
||||
// Increment AFTER moving the internal cursors because when starting aModified / aAdded, we must leave it intact
|
||||
$this->iCursor++;
|
||||
}
|
||||
|
||||
@@ -353,11 +415,12 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->LoadOriginalIds();
|
||||
$this->LoadOriginalIds();
|
||||
|
||||
$this->iCursor = 0;
|
||||
$this->iCursor = 0;
|
||||
reset($this->aPreserved);
|
||||
reset($this->aAdded);
|
||||
reset($this->aAdded);
|
||||
reset($this->aModified);
|
||||
}
|
||||
|
||||
public function HasDelta()
|
||||
@@ -429,7 +492,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
$this->aAdded = array();
|
||||
$this->aRemoved = array();
|
||||
$this->aModified = array();
|
||||
$this->aPreserved = $this->aOriginalObjects;
|
||||
$this->aPreserved = ($this->aOriginalObjects === null) ? array() : $this->aOriginalObjects;
|
||||
$this->bHasDelta = false;
|
||||
|
||||
/** @var AttributeLinkedSet $oAttDef */
|
||||
@@ -504,12 +567,15 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
|
||||
// Check for the existing links
|
||||
//
|
||||
/** @var DBObject[] $aExistingLinks */
|
||||
$aExistingLinks = array();
|
||||
/** @var Int[] $aExistingRemote */
|
||||
$aExistingRemote = array();
|
||||
if (count($aCheckLinks) > 0)
|
||||
{
|
||||
$oSearch = new DBObjectSearch($this->sClass);
|
||||
$oSearch->AddCondition('id', $aCheckLinks, 'IN');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
/** @var DBObject[] $aExistingLinks */
|
||||
$aExistingLinks = $oSet->ToArray();
|
||||
}
|
||||
|
||||
@@ -521,7 +587,6 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
$oSearch->AddCondition($sExtKeyToMe, $oHostObject->GetKey(), '=');
|
||||
$oSearch->AddCondition($sExtKeyToRemote, $aCheckRemote, 'IN');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
/** @var Int[] $aExistingRemote */
|
||||
$aExistingRemote = $oSet->GetColumnAsArray($sExtKeyToRemote);
|
||||
}
|
||||
|
||||
@@ -598,4 +663,34 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
//
|
||||
$oMtx->Unlock();
|
||||
}
|
||||
|
||||
public function ToDBObjectSet($bShowObsolete = true)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->sHostClass, $this->sAttCode);
|
||||
$oLinkSearch = $this->GetFilter();
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->sClass, $sExtKeyToRemote);
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
if (!$bShowObsolete && MetaModel::IsObsoletable($sTargetClass))
|
||||
{
|
||||
$oNotObsolete = new BinaryExpression(
|
||||
new FieldExpression('obsolescence_flag', $sTargetClass),
|
||||
'=',
|
||||
new ScalarExpression(0)
|
||||
);
|
||||
$oNotObsoleteRemote = new DBObjectSearch($sTargetClass);
|
||||
$oNotObsoleteRemote->AddConditionExpression($oNotObsolete);
|
||||
$oLinkSearch->AddCondition_PointingTo($oNotObsoleteRemote, $sExtKeyToRemote);
|
||||
}
|
||||
}
|
||||
$oLinkSet = new DBObjectSet($oLinkSearch);
|
||||
$oLinkSet->SetShowObsoleteData($bShowObsolete);
|
||||
if ($this->HasDelta())
|
||||
{
|
||||
$oLinkSet->AddObjectArray($this->aAdded);
|
||||
}
|
||||
return $oLinkSet;
|
||||
}
|
||||
}
|
||||
@@ -226,9 +226,9 @@ EOF
|
||||
$iNewWidth = $iWidth * $fScale;
|
||||
$iNewHeight = $iHeight * $fScale;
|
||||
|
||||
$sUrl = 'data:' . $value->GetMimeType() . ';base64,' . base64_encode($value->GetData());
|
||||
$sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData());
|
||||
}
|
||||
$sRet = '<img src="' . $sUrl . '" style="width: ' . $iNewWidth . 'px; height: ' . $iNewHeight . 'px">';
|
||||
$sRet = ($sUrl !== null) ? '<img src="'.$sUrl.'" style="width: '.$iNewWidth.'px; height: '.$iNewHeight.'px">' : '';
|
||||
$sRet = '<div class="view-image">'.$sRet.'</div>';
|
||||
}
|
||||
else
|
||||
|
||||
@@ -175,7 +175,8 @@ EOF
|
||||
}
|
||||
elseif ($oAttDef instanceof AttributeCustomFields)
|
||||
{
|
||||
$sRet = $oObj->GetAsHTML($sAttCode);
|
||||
// Stick to the weird implementation made in GetNextChunk
|
||||
$sRet = utils::TextToHtml($oObj->GetEditValue($sAttCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,6 +327,12 @@ EOF
|
||||
}
|
||||
$sData .= "<td x:str>$sField</td>";
|
||||
}
|
||||
elseif ($oAttDef instanceof AttributeCustomFields)
|
||||
{
|
||||
// GetAsHTML returns a table that would not fit
|
||||
$sField = utils::TextToHtml($oObj->GetEditValue($sAttCode));
|
||||
$sData .= "<td x:str>$sField</td>";
|
||||
}
|
||||
else if($oAttDef instanceof AttributeString)
|
||||
{
|
||||
$sField = $oObj->GetAsHTML($sAttCode, $this->bLocalizeOutput);
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
|
||||
class SQLObjectQuery extends SQLQuery
|
||||
{
|
||||
private $m_SourceOQL = '';
|
||||
public $m_aContextData = null;
|
||||
public $m_iOriginalTableCount = 0;
|
||||
private $m_sTable = '';
|
||||
private $m_sTableAlias = '';
|
||||
private $m_aFields = array();
|
||||
@@ -510,6 +511,7 @@ class SQLObjectQuery extends SQLQuery
|
||||
|
||||
public function OptimizeJoins($aUsedTables, $bTopCall = true)
|
||||
{
|
||||
$this->m_iOriginalTableCount = $this->CountTables();
|
||||
if ($bTopCall)
|
||||
{
|
||||
// Top call: complete the list of tables absolutely required to perform the right query
|
||||
@@ -612,4 +614,5 @@ class SQLObjectQuery extends SQLQuery
|
||||
// None of the tables is in the list of required tables
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@ $complement-light: #d6e8ef;
|
||||
$frame-background-color: #F1F1F1;
|
||||
$text-color: #000;
|
||||
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
|
||||
$version: "v2.4.0-beta";
|
||||
$version: "v2.4.0";
|
||||
BIN
css/font-combodo/combodo-webfont.ttf
Normal file
BIN
css/font-combodo/combodo-webfont.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -21,7 +21,7 @@ OS2Version: 0
|
||||
OS2_WeightWidthSlopeOnly: 0
|
||||
OS2_UseTypoMetrics: 1
|
||||
CreationTime: 1463745065
|
||||
ModificationTime: 1464178421
|
||||
ModificationTime: 1506001058
|
||||
OS2TypoAscent: 0
|
||||
OS2TypoAOffset: 1
|
||||
OS2TypoDescent: 0
|
||||
@@ -35,7 +35,6 @@ HheadAscent: 0
|
||||
HheadAOffset: 1
|
||||
HheadDescent: 0
|
||||
HheadDOffset: 1
|
||||
OS2Vendor: 'PfEd'
|
||||
MarkAttachClasses: 1
|
||||
DEI: 91125
|
||||
Encoding: ISO8859-1
|
||||
@@ -47,7 +46,7 @@ FitToEm: 0
|
||||
WinInfo: 0 31 10
|
||||
BeginPrivate: 0
|
||||
EndPrivate
|
||||
BeginChars: 256 8
|
||||
BeginChars: 256 11
|
||||
|
||||
StartChar: zero
|
||||
Encoding: 48 48 0
|
||||
@@ -210,7 +209,7 @@ StartChar: three
|
||||
Encoding: 51 51 3
|
||||
Width: 1022
|
||||
VWidth: 0
|
||||
Flags: MO
|
||||
Flags: M
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
@@ -261,11 +260,13 @@ StartChar: C
|
||||
Encoding: 67 67 4
|
||||
Width: 1080
|
||||
VWidth: 0
|
||||
Flags: HW
|
||||
Flags: W
|
||||
HStem: -112 36<398.67 444.211> 97 36<463.993 575.071> 116 37<411.524 459.906> 250 37<334.123 402.464> 335 37<749.246 821.773> 387 37<836.543 929.295> 396 37<873.093 933.545> 442 37<475 482 739.647 795.664> 621 37<286.042 389.13> 650 37<510.192 579.789>
|
||||
VStem: 53 37<216.048 298> 218 37<457.867 579.651> 272 36<60.6299 128.446> 439 37<479.452 577.67> 451 37<-73.2171 5.85426> 472 37<568.829 649.107> 553 37<359.872 417.574> 651 38<-34.3438 62.6665> 718 38<8.82031 164.606> 934 38<341.569 396>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
641 -116 m 4x9b20
|
||||
641 -116 m 4x9b39f0
|
||||
637 -116 633 -115 630 -113 c 4
|
||||
624 -110 616 -102 616 -88 c 4
|
||||
616 -84 617 -80 618 -75 c 4
|
||||
@@ -275,14 +276,14 @@ SplineSet
|
||||
651 31 641 52 624 75 c 4
|
||||
609 94 595 108 586 115 c 5
|
||||
562 107 523 97 500 97 c 6
|
||||
499 97 l 6xdb20
|
||||
499 97 l 6xdb39f0
|
||||
479 97 468 105 460 111 c 4
|
||||
457 114 455 115 453 116 c 4
|
||||
450 116 438 112 423 104 c 4
|
||||
412 98 405 94 401 90 c 5
|
||||
411 80 436 61 448 52 c 4
|
||||
460 43 468 37 473 32 c 4
|
||||
485 20 488 -4 488 -20 c 4
|
||||
485 20 488 -4 488 -20 c 4xb93af0
|
||||
488 -27 487 -33 487 -36 c 4
|
||||
485 -55 477 -90 452 -105 c 4
|
||||
444 -110 435 -112 426 -112 c 4
|
||||
@@ -321,10 +322,10 @@ SplineSet
|
||||
219 484 218 493 218 504 c 4
|
||||
218 526 222 550 231 575 c 4
|
||||
237 593 255 636 284 651 c 4
|
||||
293 656 305 658 320 658 c 4xb9a0
|
||||
293 656 305 658 320 658 c 4
|
||||
342 658 367 653 389 644 c 4
|
||||
416 633 437 617 452 597 c 4
|
||||
472 571 476 537 476 508 c 4
|
||||
472 571 476 537 476 508 c 4xb9bcf0
|
||||
476 497 476 487 475 479 c 5
|
||||
482 479 l 5
|
||||
505 499 l 5
|
||||
@@ -352,7 +353,7 @@ SplineSet
|
||||
766 473 767 473 768 473 c 4
|
||||
787 473 808 460 831 446 c 4
|
||||
845 437 865 424 873 424 c 4
|
||||
874 424 l 6x9d60
|
||||
874 424 l 6x9d79f0
|
||||
875 424 880 425 884 426 c 4
|
||||
897 429 915 433 930 433 c 4
|
||||
956 433 965 421 969 412 c 4
|
||||
@@ -362,7 +363,7 @@ SplineSet
|
||||
916 289 911 288 905 288 c 4
|
||||
888 288 863 299 835 311 c 4
|
||||
810 322 780 335 766 335 c 4
|
||||
765 335 764 335 764 335 c 4
|
||||
764 335 l 4
|
||||
763 335 757 331 748 315 c 4
|
||||
741 301 734 283 727 264 c 4
|
||||
721 248 715 231 708 216 c 5
|
||||
@@ -370,7 +371,7 @@ SplineSet
|
||||
756 69 755 58 753 47 c 4
|
||||
748 19 727 -22 708 -51 c 4
|
||||
697 -68 687 -82 677 -93 c 4
|
||||
663 -109 652 -116 641 -116 c 4x9b20
|
||||
663 -109 652 -116 641 -116 c 4x9b39f0
|
||||
308 85 m 5
|
||||
308 83 312 72 340 46 c 4
|
||||
357 30 374 18 374 18 c 6
|
||||
@@ -387,14 +388,14 @@ SplineSet
|
||||
383 55 362 72 362 90 c 4
|
||||
362 92 362 93 362 95 c 4
|
||||
363 100 366 113 402 134 c 4
|
||||
410 138 435 153 453 153 c 4xb9a0
|
||||
410 138 435 153 453 153 c 4xb9baf0
|
||||
455 153 458 152 460 152 c 4
|
||||
470 150 476 145 482 141 c 4
|
||||
488 136 491 133 499 133 c 6
|
||||
500 133 l 6xd920
|
||||
500 133 l 6xd93af0
|
||||
521 133 562 145 581 153 c 6
|
||||
589 156 l 5
|
||||
596 153 l 6xb920
|
||||
596 153 l 6xb93af0
|
||||
612 146 637 119 654 97 c 4
|
||||
670 75 689 44 689 16 c 4
|
||||
689 13 689 10 688 7 c 4
|
||||
@@ -413,7 +414,7 @@ SplineSet
|
||||
868 337 893 326 903 325 c 5
|
||||
907 329 916 340 924 359 c 4
|
||||
932 377 934 390 934 396 c 4
|
||||
933 396 932 396 930 396 c 4xdb20
|
||||
933 396 932 396 930 396 c 4xdb3af0
|
||||
919 396 902 392 892 390 c 4
|
||||
886 389 881 388 878 388 c 4
|
||||
876 388 875 387 873 387 c 4
|
||||
@@ -433,9 +434,9 @@ SplineSet
|
||||
629 559 619 566 619 566 c 6
|
||||
615 569 l 5
|
||||
580 633 l 5
|
||||
566 639 539 650 520 650 c 4x9d60
|
||||
566 639 539 650 520 650 c 4
|
||||
514 650 512 650 511 649 c 4
|
||||
510 648 509 644 509 637 c 4
|
||||
510 648 509 644 509 637 c 4x9d79f0
|
||||
509 629 510 618 514 602 c 4
|
||||
517 589 520 577 523 569 c 5
|
||||
562 561 l 5
|
||||
@@ -446,7 +447,7 @@ SplineSet
|
||||
435 465 l 6
|
||||
437 474 439 491 439 510 c 4
|
||||
439 533 436 558 423 575 c 4
|
||||
400 605 354 621 320 621 c 4x99a0
|
||||
400 605 354 621 320 621 c 4x99bcf0
|
||||
310 621 304 619 301 618 c 4
|
||||
281 608 255 548 255 504 c 4
|
||||
255 497 255 490 257 484 c 4
|
||||
@@ -475,22 +476,25 @@ SplineSet
|
||||
424 204 390 196 377 186 c 4
|
||||
330 149 310 105 308 85 c 5
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
|
||||
StartChar: I
|
||||
Encoding: 73 73 5
|
||||
Width: 1024
|
||||
VWidth: 0
|
||||
Flags: HW
|
||||
Flags: W
|
||||
HStem: -154 166<226 365 659 798> 126 26<498.267 525.733> 151 131<288 343 681 735> 313 132<288 343 681 735> 330 32<424.389 599.754> 443 26<498.267 525.733> 584 184<226 365 659 798>
|
||||
VStem: 51 175<12 151 445 584> 365 132<74 126 469 521> 366 31<282 313> 527 132<74 126 469 521> 627 31<282 313> 798 175<12 151 445 584>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
51 -154 m 1
|
||||
51 -154 m 1x8308
|
||||
51 768 l 1
|
||||
973 768 l 1
|
||||
973 -154 l 1
|
||||
51 -154 l 1
|
||||
497 469 m 2
|
||||
51 -154 l 1x8308
|
||||
497 469 m 1x87a8
|
||||
502 469 507 470 512 470 c 0
|
||||
517 470 522 469 527 469 c 1
|
||||
527 521 l 1
|
||||
@@ -498,35 +502,34 @@ SplineSet
|
||||
512 702 l 1
|
||||
414 604 l 1
|
||||
497 521 l 1
|
||||
497 469 l 1
|
||||
497 469 l 2
|
||||
497 469 l 1x87a8
|
||||
653 417 m 1
|
||||
681 445 l 1
|
||||
798 445 l 1
|
||||
798 445 l 1x9328
|
||||
798 584 l 1
|
||||
659 584 l 1
|
||||
659 467 l 1
|
||||
633 440 l 1
|
||||
643 433 649 425 653 417 c 1
|
||||
366 282 m 1
|
||||
366 282 m 1xb348
|
||||
366 313 l 1
|
||||
288 313 l 1
|
||||
206 396 l 1
|
||||
108 298 l 1
|
||||
206 200 l 1
|
||||
288 282 l 1
|
||||
366 282 l 1
|
||||
366 282 l 1xb348
|
||||
343 445 m 1
|
||||
371 417 l 1
|
||||
375 425 381 433 391 440 c 1
|
||||
365 467 l 1
|
||||
365 584 l 1
|
||||
365 584 l 1x9388
|
||||
226 584 l 1
|
||||
226 445 l 1
|
||||
343 445 l 1
|
||||
371 178 m 1
|
||||
343 151 l 1
|
||||
226 151 l 1
|
||||
226 151 l 1xa388
|
||||
226 12 l 1
|
||||
365 12 l 1
|
||||
365 129 l 1
|
||||
@@ -535,7 +538,7 @@ SplineSet
|
||||
818 396 m 1
|
||||
735 313 l 1
|
||||
658 313 l 1
|
||||
658 282 l 1
|
||||
658 282 l 1xb318
|
||||
735 282 l 1
|
||||
818 200 l 1
|
||||
916 298 l 1
|
||||
@@ -543,12 +546,12 @@ SplineSet
|
||||
653 178 m 1
|
||||
649 170 643 162 633 155 c 1
|
||||
659 129 l 1
|
||||
659 12 l 1
|
||||
659 12 l 1xa328
|
||||
798 12 l 1
|
||||
798 151 l 1
|
||||
681 151 l 1
|
||||
653 178 l 1
|
||||
527 126 m 1
|
||||
527 126 m 1xc3a8
|
||||
522 126 517 126 512 126 c 0
|
||||
507 126 502 126 497 126 c 1
|
||||
497 74 l 1
|
||||
@@ -556,8 +559,7 @@ SplineSet
|
||||
512 -106 l 1
|
||||
610 -8 l 1
|
||||
527 74 l 1
|
||||
527 126 l 1
|
||||
527 126 l 1
|
||||
527 126 l 1xc3a8
|
||||
610 348 m 0
|
||||
584 337 549 330 512 330 c 0
|
||||
475 330 441 337 414 348 c 0
|
||||
@@ -567,9 +569,9 @@ SplineSet
|
||||
449 157 479 152 512 152 c 0
|
||||
545 152 575 157 598 167 c 0
|
||||
616 174 627 184 627 192 c 2
|
||||
627 356 l 1
|
||||
627 356 l 1xcb58
|
||||
622 353 616 351 610 348 c 0
|
||||
512 443 m 1
|
||||
512 443 m 1x8f58
|
||||
479 443 449 438 426 428 c 0
|
||||
408 421 397 410 397 402 c 0
|
||||
397 394 408 384 426 377 c 0
|
||||
@@ -577,8 +579,7 @@ SplineSet
|
||||
545 362 575 367 598 377 c 0
|
||||
616 384 627 394 627 402 c 0
|
||||
627 410 616 421 598 428 c 0
|
||||
575 438 545 443 512 443 c 1
|
||||
512 443 l 1
|
||||
575 438 545 443 512 443 c 1x8f58
|
||||
EndSplineSet
|
||||
Validated: 5
|
||||
EndChar
|
||||
@@ -587,7 +588,8 @@ StartChar: four
|
||||
Encoding: 52 52 6
|
||||
Width: 1024
|
||||
VWidth: 0
|
||||
Flags: H
|
||||
HStem: -2 41<389.544 635.489> 292 109<316 441 550 675> 639 41<389.544 636.396>
|
||||
VStem: 117 41<241.556 436.857> 441 109<167 292 401 525> 868 41<249.643 435.223>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
@@ -607,7 +609,6 @@ SplineSet
|
||||
909 288 892 238 861 189 c 0
|
||||
835 149 801 111 757 77 c 1
|
||||
801 -67 l 1
|
||||
801 -67 l 1
|
||||
649 63 m 1
|
||||
733 17 l 1
|
||||
710 93 l 1
|
||||
@@ -618,7 +619,6 @@ SplineSet
|
||||
158 174 317 39 513 39 c 0
|
||||
552 39 592 49 634 59 c 2
|
||||
649 63 l 1
|
||||
649 63 l 1
|
||||
675 306 m 1
|
||||
675 298 667 292 657 292 c 2
|
||||
550 292 l 1
|
||||
@@ -640,7 +640,6 @@ SplineSet
|
||||
657 401 l 2
|
||||
667 401 675 394 675 386 c 2
|
||||
675 306 l 1
|
||||
675 306 l 1
|
||||
EndSplineSet
|
||||
Validated: 5
|
||||
EndChar
|
||||
@@ -649,15 +648,17 @@ StartChar: D
|
||||
Encoding: 68 68 7
|
||||
Width: 1080
|
||||
VWidth: 0
|
||||
Flags: HW
|
||||
Flags: W
|
||||
HStem: 198 131<79.9424 131.341> 306 98<835.102 921.871> 353 100<731.982 810.871>
|
||||
VStem: 238 219<460.138 583.719> 292 88<67.6511 114.863> 369 100<-72.2559 6.9753> 667 66<3.74069 76.8123>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
469 -14 m 4
|
||||
469 -14 m 4x26
|
||||
469 -45 459 -89 425 -89 c 4
|
||||
397 -89 372 -53 369 -41 c 4
|
||||
397 -89 372 -53 369 -41 c 4x26
|
||||
365 -27 363 7 363 7 c 5
|
||||
363 7 292 63 292 88 c 4
|
||||
363 7 292 63 292 88 c 4x2a
|
||||
292 113 317 164 366 202 c 4
|
||||
388 219 439 225 439 225 c 5
|
||||
439 225 414 269 373 269 c 4
|
||||
@@ -669,7 +670,7 @@ SplineSet
|
||||
119 206 108 198 97 198 c 4
|
||||
78 198 76 234 76 261 c 4
|
||||
76 268 76 274 76 279 c 4
|
||||
76 288 76 295 76 295 c 6
|
||||
76 295 l 6
|
||||
76 295 82 320 96 328 c 4
|
||||
97 328 98 329 99 329 c 4
|
||||
121 329 217 268 217 268 c 6
|
||||
@@ -696,12 +697,12 @@ SplineSet
|
||||
570 401 569 394 569 388 c 4
|
||||
569 355 614 330 614 330 c 5
|
||||
614 330 646 364 662 384 c 4
|
||||
678 404 734 453 763 453 c 4
|
||||
678 404 734 453 763 453 c 4xb2
|
||||
790 453 841 404 867 404 c 4
|
||||
878 404 902 413 924 413 c 4
|
||||
938 413 945 409 945 396 c 4
|
||||
945 371 922 318 905 307 c 4
|
||||
903 306 902 306 899 306 c 4
|
||||
903 306 902 306 899 306 c 4x52
|
||||
872 306 795 353 761 353 c 4
|
||||
758 353 756 353 754 352 c 4
|
||||
723 342 708 263 682 213 c 5
|
||||
@@ -714,11 +715,232 @@ SplineSet
|
||||
667 64 605 129 586 138 c 5
|
||||
565 130 522 118 499 118 c 4
|
||||
475 118 470 137 453 137 c 4
|
||||
437 137 380 108 380 93 c 4
|
||||
437 137 380 108 380 93 c 4x2a
|
||||
380 77 446 36 460 23 c 4
|
||||
465 18 469 3 469 -14 c 4
|
||||
465 18 469 3 469 -14 c 4x26
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
|
||||
StartChar: E
|
||||
Encoding: 69 69 8
|
||||
Width: 1024
|
||||
VWidth: 0
|
||||
HStem: -65 248<767.992 903.557> 62.9598 56.9516<226.56 349.224 705.189 710> 143 26.9554<256.859 324.845> 192.776 27.2245<289.957 314.952> 295.071 27.9295<269.575 354.789> 344 66<376.038 439.962> 433 25<407.015 431.988> 469 248<767.951 904.873>
|
||||
VStem: 66.5097 115.469<193.203 298.14> 204 32.9583<187.285 267.499> 257.966 57.0345<194.835 224.243> 335.831 30.8205<177.895 239.59> 388.713 44.4108<157.773 270.37> 407 25<433.012 457.985> 442 55.4336<365.791 447.874> 711 249<-8.06335 62 583 662.557>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
279 573 m 0x7ffb
|
||||
292 573 313 570 343 563 c 0
|
||||
462 535 489 420 496 389 c 0
|
||||
496.963 384.737 497.434 380.795 497.434 377.167 c 0
|
||||
497.434 354.414 478.912 344 447 344 c 0
|
||||
422.333 344 394.111 344.889 359.074 344.889 c 0
|
||||
341.556 344.889 322.333 344.667 301 344 c 0
|
||||
237 342 192 300 183 241 c 0
|
||||
182.31 236.477 181.979 231.948 181.979 227.44 c 0
|
||||
181.979 173.142 230.063 121.847 279 120 c 0
|
||||
280.57 119.941 282.134 119.911 283.69 119.911 c 0
|
||||
334.636 119.911 377.296 151.452 387 199 c 0
|
||||
388.159 204.678 388.713 210.303 388.713 215.813 c 0
|
||||
388.713 257.852 356.437 293.232 314 295 c 0
|
||||
312.865 295.047 311.742 295.071 310.63 295.071 c 0
|
||||
264.267 295.071 236.958 255.02 236.958 229.128 c 0
|
||||
236.958 206.914 253.918 170.972 286 170 c 0
|
||||
287.107 169.97 288.186 169.955 289.238 169.955 c 0
|
||||
323.358 169.955 329.15 185.419 334 199 c 0
|
||||
335.206 202.378 335.831 206.221 335.831 210.207 c 0
|
||||
335.831 222.743 329.657 236.689 316 242 c 0
|
||||
298 249 291 238 290 234 c 0
|
||||
289 228 294 220 299 220 c 0
|
||||
306 220 316 220 315 206 c 0
|
||||
314.143 195.714 302.265 192.776 292.592 192.776 c 0
|
||||
290.98 192.776 289.429 192.857 288 193 c 0
|
||||
278.231 193.977 257.966 202.588 257.966 228.155 c 0
|
||||
257.966 248.46 275.443 271.256 306.289 271.256 c 0
|
||||
308.143 271.256 310.047 271.172 312 271 c 0
|
||||
351.28 267.429 366.651 246.325 366.651 219.783 c 0
|
||||
366.651 216.594 366.429 213.326 366 210 c 0
|
||||
362 179 343 143 284 143 c 0
|
||||
225 143 204 192 204 229 c 0
|
||||
204 266 232 322 318 323 c 0
|
||||
318.502 323.006 319.002 323.009 319.501 323.009 c 0
|
||||
394.354 323.009 433.124 257.543 433.124 205.254 c 0
|
||||
433.124 198.198 432.418 191.383 431 185 c 0
|
||||
420.148 134.686 398.59 62.9598 273.187 62.9598 c 0
|
||||
271.478 62.9598 269.749 62.9731 268 63 c 0
|
||||
134.539 65.8599 66.5097 196.855 66.5097 295.718 c 0
|
||||
66.5097 300.562 66.673 305.329 67 310 c 0
|
||||
74 410 112 447 146 480 c 0
|
||||
204.987 537.114 264.85 531.109 264.85 543.245 c 0
|
||||
264.85 544.071 264.573 544.981 264 546 c 0
|
||||
260.913 551.732 257.827 557.659 257.827 562.495 c 0
|
||||
257.827 568.625 262.788 573 279 573 c 0x7ffb
|
||||
408 478 m 0
|
||||
389 478 374 463 374 444 c 0
|
||||
374 425 389 410 408 410 c 0
|
||||
427 410 442 425 442 444 c 0
|
||||
442 463 427 478 408 478 c 0
|
||||
835 717 m 0
|
||||
904 717 960 662 960 593 c 0
|
||||
960 524 904 469 835 469 c 0
|
||||
798 469 751 495 731 526 c 1
|
||||
515 456 l 1
|
||||
503 483 491 498 481 511 c 1
|
||||
712 583 l 2
|
||||
712 586 711 590 711 593 c 0
|
||||
711 662 766 717 835 717 c 0
|
||||
462 207 m 1
|
||||
727 121 l 1
|
||||
747 155 795 183 834 183 c 0
|
||||
903 183 958 128 958 59 c 0
|
||||
958 -10 903 -65 834 -65 c 0x9ff3
|
||||
765 -65 710 -10 710 59 c 0
|
||||
710 60 710 61 710 62 c 2
|
||||
456 143 l 1
|
||||
458.679 159.077 462.157 171.165 462.157 197.076 c 0
|
||||
462.157 200.176 462.107 203.474 462 207 c 1
|
||||
407 445 m 0x1ff7
|
||||
407 453 412 458 420 458 c 0
|
||||
428 458 432 453 432 445 c 0
|
||||
432 437 428 433 420 433 c 0
|
||||
412 433 407 437 407 445 c 0x1ff7
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
|
||||
StartChar: F
|
||||
Encoding: 70 70 9
|
||||
Width: 1024
|
||||
VWidth: 0
|
||||
HStem: -36 87<438.038 591.036> 87 39<470.027 570.5> 163 41<517.914 555.989> 241 41<519.089 577.135> 317 43<482.813 612.995> 394 100<654.807 741.193> 528 39<697.004 734.996>
|
||||
VStem: 177 177<195.689 296.938> 387 50<156.758 272.234> 469 87<171.273 203.985> 588 47<139.283 231.811> 669 67<122.953 266.087> 697 38<528.004 566.995> 750 85<426.5 559.5>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
502 742 m 0xfff4
|
||||
522 742 553 738 599 727 c 0
|
||||
780 684 822 509 833 462 c 0
|
||||
835 456 835 450 835 444 c 0
|
||||
835 409 806 392 758 392 c 0
|
||||
721 392 678 394 624 394 c 0
|
||||
597 394 568 393 535 392 c 0
|
||||
437 388 368 325 355 235 c 0
|
||||
354 228 354 222 354 215 c 0
|
||||
354 132 426 55 501 51 c 0
|
||||
504 51 507 51 510 51 c 0
|
||||
587 51 652 99 666 171 c 0
|
||||
668 180 669 188 669 196 c 0
|
||||
669 260 620 313 555 317 c 0
|
||||
553 317 550 317 548 317 c 0
|
||||
478 317 437 256 437 218 c 0
|
||||
437 184 463 127 512 126 c 0
|
||||
514 126 516 126 518 126 c 0
|
||||
569 126 578 150 586 171 c 0
|
||||
588 176 588 181 588 187 c 0
|
||||
588 207 579 228 557 237 c 0
|
||||
550 240 545 241 540 241 c 0
|
||||
525 241 520 230 518 225 c 0
|
||||
516 216 524 204 532 204 c 0
|
||||
543 204 556 202 556 183 c 0
|
||||
556 166 541 163 525 163 c 0
|
||||
522 163 518 163 515 163 c 0
|
||||
499 164 469 177 469 217 c 0
|
||||
469 247 497 282 543 282 c 0
|
||||
546 282 549 282 552 282 c 0
|
||||
611 277 635 243 635 202 c 0
|
||||
635 197 635 193 634 188 c 0
|
||||
628 141 598 87 508 87 c 0
|
||||
418 87 387 162 387 218 c 0
|
||||
387 274 430 358 561 360 c 0
|
||||
562 360 563 360 564 360 c 0
|
||||
677 360 736 262 736 182 c 0
|
||||
736 171 735 160 733 150 c 0
|
||||
716 74 683 -36 494 -36 c 0
|
||||
491 -36 487 -36 484 -36 c 0
|
||||
280 -32 177 170 177 321 c 0
|
||||
177 328 178 335 178 342 c 0
|
||||
188 495 246 549 298 600 c 0
|
||||
388 687 479 677 479 696 c 0
|
||||
479 697 479 698 478 700 c 0
|
||||
473 709 469 718 469 725 c 0
|
||||
469 735 477 742 502 742 c 0xfff4
|
||||
698 597 m 0
|
||||
669 597 646 574 646 545 c 0
|
||||
646 516 669 494 698 494 c 0
|
||||
727 494 750 516 750 545 c 0
|
||||
750 574 727 597 698 597 c 0
|
||||
697 547 m 0xffec
|
||||
697 560 703 567 716 567 c 0
|
||||
729 567 735 560 735 547 c 0
|
||||
735 534 729 528 716 528 c 0
|
||||
703 528 697 534 697 547 c 0xffec
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
|
||||
StartChar: O
|
||||
Encoding: 79 79 10
|
||||
Width: 1024
|
||||
VWidth: 0
|
||||
HStem: 1.59961 8<801.97 829.007> 20 35.2002<801.975 810.774 823.574 824.837> 33.5996 5.60059<810.774 817.806> 48.7998 6.40039<810.774 818.736> 61.5996 8.7998<801.043 829.91> 434.399 245.601<441.712 567.228>
|
||||
VStem: 780.375 8.7998<21.8033 49.6942> 801.975 8.7998<20 33.5996 39.2002 48.7998> 819.574 8.80078<40.0451 47.9513> 841.175 8.7998<21.5374 50.3356>
|
||||
LayerCount: 3
|
||||
Fore
|
||||
SplineSet
|
||||
504.375 680 m 0x8fc0
|
||||
672.375 680 816.375 560 846.774 395.2 c 0
|
||||
877.175 230.399 785.975 67.2002 629.175 7.2002 c 0
|
||||
621.975 4.7998 613.975 8 611.574 15.2002 c 2
|
||||
533.175 218.399 l 2
|
||||
530.774 225.6 533.975 234.399 541.175 236.8 c 0
|
||||
587.574 254.399 613.975 301.6 605.175 350.399 c 0
|
||||
596.375 399.2 553.975 434.399 504.375 434.399 c 0
|
||||
454.774 434.399 413.175 399.2 404.375 350.399 c 0
|
||||
395.574 301.6 421.175 254.399 467.574 236.8 c 0
|
||||
474.774 234.399 477.975 225.6 475.574 218.399 c 2
|
||||
397.975 15.2002 l 2
|
||||
395.574 8 386.774 4.7998 379.574 7.2002 c 0
|
||||
222.774 67.2002 131.574 230.399 161.975 395.2 c 0
|
||||
192.375 560 336.375 680 504.375 680 c 0x8fc0
|
||||
815.574 70.3994 m 0
|
||||
834.774 70.3994 849.975 55.2002 849.975 36 c 0
|
||||
849.975 16.7998 834.774 1.59961 815.574 1.59961 c 0
|
||||
796.375 1.59961 780.375 16.7998 780.375 36 c 0
|
||||
780.375 55.2002 796.375 70.3994 815.574 70.3994 c 0
|
||||
815.574 61.5996 m 0
|
||||
801.175 61.5996 789.175 50.3994 789.175 36 c 0
|
||||
789.175 21.5996 801.175 9.59961 815.574 9.59961 c 0
|
||||
829.975 9.59961 841.175 21.5996 841.175 36 c 0
|
||||
841.175 50.3994 829.975 61.5996 815.574 61.5996 c 0
|
||||
814.774 39.2002 m 2xbfc0
|
||||
816.375 39.2002 817.975 40 818.774 40.7998 c 0
|
||||
819.574 41.5996 819.574 42.3994 819.574 44 c 0
|
||||
819.574 45.5996 819.574 46.3994 818.774 47.2002 c 0
|
||||
817.975 48 816.375 48.7998 814.774 48.7998 c 2
|
||||
810.774 48.7998 l 1
|
||||
810.774 39.2002 l 1
|
||||
814.774 39.2002 l 2xbfc0
|
||||
810.774 33.5996 m 1
|
||||
810.774 20 l 1
|
||||
801.975 20 l 1
|
||||
801.975 55.2002 l 1xcfc0
|
||||
815.574 55.2002 l 2x9fc0
|
||||
820.375 55.2002 822.774 54.3994 825.175 52.7998 c 0
|
||||
827.574 51.2002 828.375 48.7998 828.375 45.5996 c 0
|
||||
828.375 43.2002 827.574 41.5996 826.774 40 c 0
|
||||
825.975 38.3994 824.375 36.7998 821.975 36 c 1
|
||||
823.574 36 824.375 35.2002 825.175 34.3994 c 0
|
||||
825.975 33.5996 827.574 32 828.375 29.5996 c 2
|
||||
833.175 20 l 1
|
||||
823.574 20 l 1xcfc0
|
||||
819.574 28.7998 l 2
|
||||
818.774 30.3994 817.175 31.2002 816.375 32 c 0
|
||||
815.574 32.7998 814.774 33.5996 813.175 33.5996 c 2
|
||||
810.774 33.5996 l 1
|
||||
EndSplineSet
|
||||
Validated: 524321
|
||||
EndChar
|
||||
EndChars
|
||||
EndSplineFont
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: 'CombodoRegular';
|
||||
src: url('combodo-webfont.woff2?v=1.0') format('woff2'),
|
||||
url('combodo-webfont.woff?v=1.0') format('woff'),
|
||||
url('combodo-webfont.ttf?v=1.0') format('truetype');
|
||||
src: url('combodo-webfont.woff2?v=2.0') format('woff2'),
|
||||
url('combodo-webfont.woff?v=2.0') format('woff'),
|
||||
url('combodo-webfont.ttf?v=2.0') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
@@ -193,7 +193,16 @@
|
||||
.fc-combodo-icon:before {
|
||||
content: "D";
|
||||
}
|
||||
.fc-itophub-icon:before {
|
||||
content: "E";
|
||||
}
|
||||
.fc-chameleon-icon:before {
|
||||
content: "F";
|
||||
}
|
||||
.fc-itop-icon:before {
|
||||
content: "I";
|
||||
}
|
||||
.fc-opensource-icon:before {
|
||||
content: "O";
|
||||
}
|
||||
|
||||
|
||||
50
css/font-combodo/glyphs/E.svg
Executable file
50
css/font-combodo/glyphs/E.svg
Executable file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1000"
|
||||
height="1000"
|
||||
viewBox="0 0 264.58333 264.58334"
|
||||
version="1.1"
|
||||
id="svg909">
|
||||
<defs
|
||||
id="defs903" />
|
||||
<metadata
|
||||
id="metadata906">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
transform="matrix(2.6189878,0,0,2.6189878,-138.11438,-66.566639)"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 77.776825,48.628779 c -3.105953,0.0165 -2.465143,1.56905 -1.672249,3.00189 0.969595,1.75214 -6.046384,0.53457 -12.856064,7.17372 -3.69523,3.60269 -7.8302,7.46233 -8.56485,18.39112 -0.73465,10.9288 6.57401,26.601051 21.834325,26.890351 14.098468,0.26727 16.523001,-7.762201 17.760671,-13.268961 1.323287,-5.88768 -2.939907,-15.10068 -12.294338,-14.96704 -9.354428,0.13364 -12.428178,6.14692 -12.428178,10.15597 0,4.00904 2.27182,9.35447 8.686288,9.35447 6.414468,0 8.552552,-3.87524 8.953457,-7.2161 0.400905,-3.34087 -1.12866,-6.23284 -5.863206,-6.68176 -3.664545,-0.34747 -5.823431,2.30622 -5.896281,4.44314 -0.100228,2.93996 2.194808,3.98392 3.307291,4.04264 1.112483,0.0587 2.766575,-0.003 2.856155,-1.33635 0.10023,-1.49182 -0.935023,-1.63676 -1.686717,-1.62005 -0.534409,0.0119 -1.147985,-0.88438 -0.985986,-1.50379 0.121989,-0.46643 0.78549,-1.62036 2.790009,-0.81855 2.004523,0.8018 2.544982,3.13823 2.021065,4.67723 -0.534538,1.57021 -1.18617,3.2909 -5.228621,3.17397 -3.536694,-0.1023 -5.411874,-4.25964 -5.328354,-6.68177 0.0939,-2.724 3.190312,-7.1826 8.402068,-6.91534 5.211754,0.26728 8.953352,5.07775 7.884274,10.42314 -1.069079,5.34539 -6.013196,8.82024 -11.759488,8.55297 -5.746294,-0.26727 -11.359094,-6.68189 -10.423654,-13.09636 0.93544,-6.41447 5.87967,-10.95789 12.828675,-11.22516 6.949005,-0.26727 11.885592,0.016 15.894636,0.016 4.009047,0 6.155487,-1.61955 5.353677,-4.96042 -0.8018,-3.34086 -3.786135,-15.85543 -16.689419,-18.91977 -3.29736,-0.78307 -5.483391,-1.09268 -6.895186,-1.0852 z m 13.978992,10.35854 a 3.685268,3.685268 0 0 1 3.685563,3.68505 3.685268,3.685268 0 0 1 -3.685563,3.68556 3.685268,3.685268 0 0 1 -3.685048,-3.68556 3.685268,3.685268 0 0 1 3.685048,-3.68505 z"
|
||||
id="path882" />
|
||||
<path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 138.24445,32.953249 a 13.49711,13.49711 0 0 0 -13.49685,13.49685 13.49711,13.49711 0 0 0 0.0465,1.06195 l -25.043431,7.84087 c 1.104251,1.4075 2.257151,3.10658 3.611151,6.01255 l 23.55566,-7.5799 a 13.49711,13.49711 0 0 0 11.32696,6.1619 13.49711,13.49711 0 0 0 13.49737,-13.49737 13.49711,13.49711 0 0 0 -13.49737,-13.49685 z"
|
||||
id="rect827" />
|
||||
<path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 97.624193,88.491979 c 0.07421,3.57897 -0.303877,5.04652 -0.587044,6.95772 l 27.570411,8.739001 a 13.49711,13.49711 0 0 0 -0.0134,0.37258 13.49711,13.49711 0 0 0 13.49737,13.49737 13.49711,13.49711 0 0 0 13.49685,-13.49737 13.49711,13.49711 0 0 0 -13.49685,-13.496851 13.49711,13.49711 0 0 0 -11.65201,6.71794 z"
|
||||
id="rect827-1" />
|
||||
<circle
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.40000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path888"
|
||||
cx="93.031555"
|
||||
cy="62.530666"
|
||||
r="1.3701637" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
41
css/font-combodo/glyphs/F.svg
Executable file
41
css/font-combodo/glyphs/F.svg
Executable file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1000"
|
||||
height="1000"
|
||||
viewBox="0 0 264.58333 264.58334"
|
||||
version="1.1"
|
||||
id="svg909">
|
||||
<defs
|
||||
id="defs903" />
|
||||
<metadata
|
||||
id="metadata906">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(0,-32.41665)"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#1b1b1b;fill-opacity:1;stroke:#000000;stroke-width:1.71210456;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 128.74663,48.188011 c -13.29429,0.07062 -10.55146,6.715944 -7.15766,12.848874 4.15012,7.499617 -25.880108,2.288099 -55.027316,30.705397 -15.81655,15.420458 -33.515303,31.940728 -36.659797,78.718798 -3.144494,46.77813 28.138482,113.85946 93.456613,115.09774 60.34513,1.14398 70.72277,-33.22425 76.02032,-56.79463 5.66401,-25.20081 -12.58357,-64.63485 -52.62298,-64.06284 -40.0394,0.57201 -53.195848,26.31042 -53.195848,43.47021 0,17.15974 9.723978,40.03957 37.179578,40.03957 27.4556,0 36.60716,-16.58704 38.32314,-30.88679 1.71598,-14.2998 -4.83096,-26.67818 -25.09606,-28.59968 -15.68521,-1.48726 -24.9258,9.87122 -25.23762,19.0178 -0.429,12.5838 9.39435,17.05222 14.15607,17.30356 4.76172,0.25125 11.84166,-0.0128 12.22509,-5.71993 0.42901,-6.38538 -4.00214,-7.00576 -7.21959,-6.93424 -2.28741,0.0509 -4.91368,-3.78538 -4.22028,-6.43661 0.52215,-1.99644 3.3621,-6.93557 11.94197,-3.50361 8.57988,3.43191 10.89319,13.43244 8.65069,20.01977 -2.28797,6.72091 -5.07712,14.08591 -22.37987,13.58542 -15.13797,-0.43787 -23.16423,-18.23237 -22.80675,-28.59972 0.40192,-11.65944 13.65537,-30.74341 35.96305,-29.59947 22.30767,1.14403 38.32269,21.7341 33.74675,44.61377 -4.57593,22.87966 -25.73805,37.75293 -50.33368,36.60894 -24.59564,-1.14398 -48.619888,-28.60023 -44.615958,-56.05584 4.00393,-27.45561 25.166518,-46.90263 54.910078,-48.04662 29.74356,-1.14398 50.87344,0.0685 68.0332,0.0685 17.15977,0 26.34709,-6.93209 22.91514,-21.23189 -3.43192,-14.29975 -16.20565,-67.865386 -71.43508,-80.981563 -14.11356,-3.351744 -23.47035,-4.676956 -29.5132,-4.644939 z m 59.83374,44.337259 a 15.77391,15.77391 0 0 1 15.77517,15.77298 15.77391,15.77391 0 0 1 -15.77517,15.77516 15.77391,15.77391 0 0 1 -15.77297,-15.77516 15.77391,15.77391 0 0 1 15.77297,-15.77298 z"
|
||||
id="path882" />
|
||||
<circle
|
||||
style="opacity:1;fill:#101010;fill-opacity:1;stroke:#000000;stroke-width:1.71210456;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path888"
|
||||
cx="194.04086"
|
||||
cy="107.69173"
|
||||
r="5.8646588" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
87
css/font-combodo/glyphs/O.svg
Executable file
87
css/font-combodo/glyphs/O.svg
Executable file
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1000"
|
||||
height="1000"
|
||||
viewBox="0 0 264.58333 264.58334"
|
||||
version="1.1"
|
||||
id="svg876"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
|
||||
sodipodi:docname="O.svg">
|
||||
<defs
|
||||
id="defs870" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="-272.85714"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1005"
|
||||
inkscape:window-x="1911"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata873">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-32.41664)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:8.99672318;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 131.53572,50.179132 c -54.174274,0 -100.702568,38.6765 -110.575582,91.938598 -9.873159,53.26282 19.698102,106.06258 70.277674,125.4761 2.319548,0.89024 4.921621,-0.26836 5.811987,-2.58786 L 122.30183,199.2106 c 0.89023,-2.31957 -0.26838,-4.92164 -2.58789,-5.812 -14.87072,-5.70891 -23.515673,-21.14784 -20.612431,-36.80689 2.903191,-15.6588 16.504681,-26.96534 32.434211,-26.96534 15.92952,0 29.53338,11.30654 32.43657,26.96534 2.90326,15.65905 -5.74171,31.09798 -20.61242,36.80689 -2.31951,0.89036 -3.47812,3.49245 -2.58788,5.812 l 25.25202,65.79537 c 0.89038,2.31821 3.49074,3.47652 5.8096,2.58786 50.57958,-19.41352 80.15083,-72.21328 70.27768,-125.4761 -9.87301,-53.262098 -56.4013,-91.938598 -110.57557,-91.938598 z"
|
||||
id="path3773"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssccscsssccccss" />
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g3797"
|
||||
transform="matrix(1.2200654,0,0,1.2200654,455.86197,1099.5367)"
|
||||
inkscape:export-filename="/home/rafael/workspace/logo-osi/3/png/logo396x412.png"
|
||||
inkscape:export-xdpi="48.18"
|
||||
inkscape:export-ydpi="48.18">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.25831962;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m -183.5617,-698.57555 c -5.02556,0 -9.12392,4.09113 -9.12392,9.10782 0,5.01668 4.09836,9.10781 9.12392,9.10781 5.02556,0 9.12392,-4.09113 9.12392,-9.10781 0,-5.01669 -4.09836,-9.10782 -9.12392,-9.10782 z m 0,2.25596 c 3.80399,0 6.8633,3.05458 6.8633,6.85186 0,3.79727 -3.05931,6.85119 -6.8633,6.85119 -3.80399,0 -6.86397,-3.05392 -6.86397,-6.85119 0,-3.79728 3.05998,-6.85186 6.86397,-6.85186 z"
|
||||
id="path3015"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
aria-label="R"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:0%;font-family:OpenSymbol;-inkscape-font-specification:'OpenSymbol Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
id="text3793">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -183.7552,-690.46513 q 0.74769,0 1.06902,-0.27807 0.3275,-0.27807 0.3275,-0.91454 0,-0.63028 -0.3275,-0.90217 -0.32133,-0.27189 -1.06902,-0.27189 h -1.00105 v 2.36667 z m -1.00105,1.64369 v 3.4913 h -2.37902 v -9.22569 h 3.63342 q 1.82289,0 2.66946,0.61175 0.85274,0.61175 0.85274,1.93412 0,0.91454 -0.44491,1.50157 -0.43873,0.58703 -1.32855,0.8651 0.48817,0.11123 0.87128,0.50671 0.3893,0.38929 0.78477,1.18642 l 1.29147,2.62002 h -2.53351 l -1.12463,-2.29252 q -0.33986,-0.69208 -0.69208,-0.94543 -0.34604,-0.25335 -0.92689,-0.25335 z"
|
||||
style="font-size:12.65519524px;line-height:1.25"
|
||||
id="path863" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
@@ -18,6 +18,9 @@ aIcons = {
|
||||
'combodo-icon': 'Combodo icon',
|
||||
'combodo-icon-o': 'Combodo icon (outline)',
|
||||
'itop-icon': 'iTop icon',
|
||||
'itophub-icon': 'iTop Hub icon',
|
||||
'chameleon-icon': 'Hub\'s Chameleon icon',
|
||||
'opensource-icon': 'Open Source Logo',
|
||||
}
|
||||
|
||||
function GenerateTable() {
|
||||
|
||||
BIN
css/font-open-sans/OpenSans-Bold-cyrillic-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-cyrillic-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-cyrillic.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-cyrillic.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-greek-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-greek-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-greek.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-greek.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-latin-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-latin-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-latin.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-latin.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Bold-vietnamese.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Bold-vietnamese.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-cyrillic-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-cyrillic-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-cyrillic.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-cyrillic.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-greek-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-greek-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-greek.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-greek.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-latin-ext.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-latin-ext.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-latin.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-latin.woff2
Normal file
Binary file not shown.
BIN
css/font-open-sans/OpenSans-Regular-vietnamese.woff2
Normal file
BIN
css/font-open-sans/OpenSans-Regular-vietnamese.woff2
Normal file
Binary file not shown.
112
css/font-open-sans/font-open-sans.css
Normal file
112
css/font-open-sans/font-open-sans.css
Normal file
@@ -0,0 +1,112 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-cyrillic-ext.woff2') format('woff2');
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-cyrillic.woff2') format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-greek-ext.woff2') format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-greek.woff2') format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-vietnamese.woff2') format('woff2');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-latin-ext.woff2') format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'), url('./OpenSans-Regular-latin.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-cyrillic-ext.woff2') format('woff2');
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-cyrillic.woff2') format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-greek-ext.woff2') format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-greek.woff2') format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-vietnamese.woff2') format('woff2');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-latin-ext.woff2') format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url('./OpenSans-Bold-latin.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
||||
}
|
||||
2159
css/light-grey.css
2159
css/light-grey.css
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,14 @@ body.printable-version {
|
||||
.ui-layout-content {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.ui-layout-content .ui-tabs-nav li {
|
||||
/* Overriding jQuery UI theme to see active tab better */
|
||||
margin-bottom: 2px;
|
||||
|
||||
&.ui-tabs-active{
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.raw_output {
|
||||
font-family: Courier-New, Courier, Arial, Helvetica;
|
||||
@@ -107,6 +115,12 @@ table.listResults td .view-image {
|
||||
.view-image {
|
||||
display: inline-block;
|
||||
|
||||
img[src=""],
|
||||
img[src="null"] {
|
||||
// Hiding "broken" image when src is not set
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&.dirty {
|
||||
// The image will be modified when saving the changes
|
||||
|
||||
@@ -835,7 +849,7 @@ table.listResults tr.even td.truncated, .wizContainer table.listResults tr.even
|
||||
}
|
||||
|
||||
/* Beware: IE6 does not support multiple selector with multiple classes, only the last class is used */
|
||||
table.listResults tr.even td.hover.truncated, , .wizContainer table.listResults tr.even td.hover.truncated {
|
||||
table.listResults tr.even td.hover.truncated, .wizContainer table.listResults tr.even td.hover.truncated {
|
||||
background: #fdf5d0 url(../images/truncated.png?v=#{$version}) bottom repeat-x;
|
||||
}
|
||||
|
||||
@@ -1245,6 +1259,18 @@ span.form_validation {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
/* Helper classes for object details display. */
|
||||
.one-col-details {
|
||||
min-width: 300px;
|
||||
max-width: 600px;
|
||||
}
|
||||
.n-cols-details {
|
||||
width: 100%;
|
||||
|
||||
> tbody > tr > td {
|
||||
min-width: 240px;
|
||||
}
|
||||
}
|
||||
.details {
|
||||
border-collapse: collapse;
|
||||
noborder-bottom: 2px #fff solid;
|
||||
@@ -1269,18 +1295,24 @@ fieldset .details>.field_container {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
&.field_large{
|
||||
&.field_large {
|
||||
display: inherit;
|
||||
|
||||
/* .field_label, .field_data */
|
||||
> div {
|
||||
display: inherit;
|
||||
|
||||
&.field_label{
|
||||
&.field_label {
|
||||
width: inherit;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&.field_data {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* .field_value, .field_comments, .field_infos */
|
||||
> div {
|
||||
}
|
||||
@@ -1496,6 +1528,12 @@ fieldset .details>.field_container {
|
||||
}
|
||||
}
|
||||
}
|
||||
.one-col-details .details .field_container.field_small {
|
||||
div.field_label {
|
||||
/* On a single column, field labels can take more width but they are limited so it doesn't feel weird when all labels are short */
|
||||
width: 145px;
|
||||
}
|
||||
}
|
||||
/* This is extracted from the ".details > .field_container ..." because of the fullscreen option (element is moved at the end of the body */
|
||||
.field_input_text{
|
||||
border: none;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -21,13 +21,13 @@
|
||||
* Authent External
|
||||
* Module definition file for the "External Authentication" module
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-external/2.2.0',
|
||||
'authent-external/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -63,4 +63,3 @@ SetupWebPage::AddModule(
|
||||
'settings' => array(),
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
@@ -9,7 +9,7 @@ if (function_exists('ldap_connect'))
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-ldap/2.2.0',
|
||||
'authent-ldap/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -63,5 +63,3 @@ SetupWebPage::AddModule(
|
||||
);
|
||||
|
||||
} // if (function_exists('ldap_connect'))
|
||||
|
||||
?>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-local/2.2.0',
|
||||
'authent-local/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -40,5 +40,3 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="Attachment" _delta="define">
|
||||
<parent>DBObject</parent>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -39,4 +39,3 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Attachments:NoAttachment' => 'Kein Attachment. ',
|
||||
'Attachments:PreviewNotAvailable' => 'Vorschau für diesen Attachment-Typ nicht verfügbar.',
|
||||
));
|
||||
?>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-attachments/2.3.0',
|
||||
'itop-attachments/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -145,5 +145,3 @@ if (!class_exists('AttachmentInstaller'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -24,4 +24,4 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Attachment:Max_Ko' => '(Максимальный размер файла: %1$s кБ)',
|
||||
'Attachments:NoAttachment' => 'Нет вложений.',
|
||||
'Attachments:PreviewNotAvailable' => 'Предварительный просмотр не доступен для этого типа вложений.',
|
||||
));
|
||||
));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -291,4 +291,3 @@ class ItopBackup extends ModuleHandlerAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-backup/2.2.0',
|
||||
'itop-backup/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -56,5 +56,3 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -47,4 +47,3 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'bkp-wait-restore' => 'Пожалуйста, дождитесь завершения восстановления...',
|
||||
'bkp-success-restore' => 'Восстановление успешно завершено.',
|
||||
));
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="lnkVirtualDeviceToVolume" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-bridge-virtualization-storage/2.3.0',
|
||||
'itop-bridge-virtualization-storage/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -43,6 +43,3 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="Change" _delta="define">
|
||||
<parent>Ticket</parent>
|
||||
@@ -7,7 +7,7 @@
|
||||
<comment><![CDATA[/**
|
||||
* Persistent classes for a CMDB
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/]]></comment>
|
||||
<category>bizmodel,searchable,changemgmt</category>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-change-mgmt-itil/2.3.0',
|
||||
'itop-change-mgmt-itil/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -42,5 +42,3 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-change-mgmt/2.3.0',
|
||||
'itop-change-mgmt/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
@@ -91,5 +91,3 @@ class ChangeManagementInstaller extends ModuleInstallerAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1663,6 +1663,8 @@
|
||||
<attribute id="name"/>
|
||||
<attribute id="org_id"/>
|
||||
<attribute id="organization_name"/>
|
||||
<attribute id="location_id"/>
|
||||
<attribute id="location_name"/>
|
||||
<attribute id="finalclass"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
|
||||
@@ -395,8 +395,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:Group/Attribute:status+' => '',
|
||||
'Class:Group/Attribute:status/Value:implementation' => 'Implementation',
|
||||
'Class:Group/Attribute:status/Value:implementation+' => 'Implementation',
|
||||
'Class:Group/Attribute:status/Value:obsolete' => 'Veraltet',
|
||||
'Class:Group/Attribute:status/Value:obsolete+' => 'Veraltet',
|
||||
'Class:Group/Attribute:status/Value:obsolete' => 'Obsolet (Veraltet)',
|
||||
'Class:Group/Attribute:status/Value:obsolete+' => 'Obsolet (Veraltet)',
|
||||
'Class:Group/Attribute:status/Value:production' => 'Produktion',
|
||||
'Class:Group/Attribute:status/Value:production+' => 'Produktion',
|
||||
'Class:Group/Attribute:org_id' => 'Organisation',
|
||||
@@ -489,7 +489,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:Document/Attribute:status+' => '',
|
||||
'Class:Document/Attribute:status/Value:draft' => 'Entwurf',
|
||||
'Class:Document/Attribute:status/Value:draft+' => '',
|
||||
'Class:Document/Attribute:status/Value:obsolete' => 'Veraltet',
|
||||
'Class:Document/Attribute:status/Value:obsolete' => 'Obsolet (Veraltet)',
|
||||
'Class:Document/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:Document/Attribute:status/Value:published' => 'Veröffentlicht',
|
||||
'Class:Document/Attribute:status/Value:published+' => '',
|
||||
@@ -1184,4 +1184,4 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:Subnet/Tab:FreeIPs-count' => 'Freie IPs: %1$s',
|
||||
'Class:Subnet/Tab:FreeIPs-explain' => 'Hier ist eine Aufstellung von 10 freien IP Adressen',
|
||||
));
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -685,7 +685,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:SoftwareInstance/Attribute:softwarelicence_id+' => '',
|
||||
'Class:SoftwareInstance/Attribute:softwarelicence_name' => 'Nom Licence logiciel',
|
||||
'Class:SoftwareInstance/Attribute:softwarelicence_name+' => '',
|
||||
'Class:SoftwareInstance/Attribute:path' => 'Chemin d`installation',
|
||||
'Class:SoftwareInstance/Attribute:path' => 'Chemin d\'installation',
|
||||
'Class:SoftwareInstance/Attribute:path+' => '',
|
||||
'Class:SoftwareInstance/Attribute:status' => 'Statut',
|
||||
'Class:SoftwareInstance/Attribute:status+' => '',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-config/1.0.2',
|
||||
'itop-config/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="Rack" _delta="define">
|
||||
<parent>PhysicalDevice</parent>
|
||||
@@ -20,6 +20,10 @@
|
||||
<reconciliation>
|
||||
<attributes>
|
||||
<attribute id="name"/>
|
||||
<attribute id="org_id"/>
|
||||
<attribute id="organization_name"/>
|
||||
<attribute id="location_id"/>
|
||||
<attribute id="location_name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
</properties>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-datacenter-mgmt/2.2.0',
|
||||
'itop-datacenter-mgmt/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="TelephonyCI" _delta="define">
|
||||
<parent>PhysicalDevice</parent>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-endusers-devices/2.2.0',
|
||||
'itop-endusers-devices/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="Ticket">
|
||||
<methods>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-full-itil/1.0.0', array(
|
||||
'itop-full-itil/2.4.0', array(
|
||||
// Identification
|
||||
//
|
||||
'label' => 'Bridge - Request management ITIL + Incident management ITIL',
|
||||
|
||||
@@ -38,7 +38,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:Incident/Attribute:status/Value:assigned+' => '',
|
||||
'Class:Incident/Attribute:status/Value:escalated_ttr' => 'Escalate ttr',
|
||||
'Class:Incident/Attribute:status/Value:escalated_ttr+' => '',
|
||||
'Class:Incident/Attribute:status/Value:waiting_for_approval' => 'En attente d`approbation',
|
||||
'Class:Incident/Attribute:status/Value:waiting_for_approval' => 'En attente d\'approbation',
|
||||
'Class:Incident/Attribute:status/Value:waiting_for_approval+' => '',
|
||||
'Class:Incident/Attribute:status/Value:pending' => 'En attente',
|
||||
'Class:Incident/Attribute:status/Value:pending+' => '',
|
||||
|
||||
@@ -105,7 +105,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Incident/Attribute:servicesubcategory_id+' => 'Подкатегория услуги',
|
||||
'Class:Incident/Attribute:servicesubcategory_name' => 'Подкатегория услуги',
|
||||
'Class:Incident/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:Incident/Attribute:escalation_flag' => '«Флаг эскалации',
|
||||
'Class:Incident/Attribute:escalation_flag' => 'Флаг эскалации',
|
||||
'Class:Incident/Attribute:escalation_flag+' => 'Флаг повышенного приоритета',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:no' => 'Нет',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:no+' => 'Нет',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
|
||||
<classes>
|
||||
<class id="KnownError" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-knownerror-mgmt/2.3.0',
|
||||
'itop-knownerror-mgmt/2.4.0',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-portal-base/1.1.0', array(
|
||||
'itop-portal-base/2.4.0', array(
|
||||
// Identification
|
||||
'label' => 'Portal Development Library',
|
||||
'category' => 'Portal',
|
||||
@@ -40,4 +40,3 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -714,15 +714,18 @@ class ObjectFormManager extends FormManager
|
||||
// Note: We can't do this in AttributeExternalKey::MakeFormField() in the Field::SetOnFinalizeCallback() because at this point we have no information about the portal scope and ignore_silos flag, hence it always applies silos.
|
||||
// As a workaround we have to manually check if the field's current value is among the scope
|
||||
|
||||
/** @var DBObjectSearch $oValuesScope */
|
||||
$oValuesScope = $oField->GetSearch()->DeepClone();
|
||||
$oBinaryExp = new BinaryExpression(new FieldExpression('id', $oValuesScope->GetClassAlias()), '=', new ScalarExpression( $oField->GetCurrentValue() ));
|
||||
$oValuesScope->AddConditionExpression($oBinaryExp);
|
||||
$oValuesSet = new DBObjectSet($oValuesScope);
|
||||
|
||||
if( $oValuesSet->Count() === 0 )
|
||||
if(!$oField->GetReadOnly())
|
||||
{
|
||||
$oField->SetCurrentValue(null);
|
||||
/** @var DBObjectSearch $oValuesScope */
|
||||
$oValuesScope = $oField->GetSearch()->DeepClone();
|
||||
$oBinaryExp = new BinaryExpression(new FieldExpression('id', $oValuesScope->GetClassAlias()), '=', new ScalarExpression($oField->GetCurrentValue()));
|
||||
$oValuesScope->AddConditionExpression($oBinaryExp);
|
||||
$oValuesSet = new DBObjectSet($oValuesScope);
|
||||
|
||||
if($oValuesSet->Count() === 0)
|
||||
{
|
||||
$oField->SetCurrentValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
// - Field that require processing on their subfields
|
||||
|
||||
@@ -23,12 +23,9 @@ use \Exception;
|
||||
use \DOMNodeList;
|
||||
use \DOMFormatException;
|
||||
use \utils;
|
||||
use \UserRights;
|
||||
use \ProfilesConfig;
|
||||
use \MetaModel;
|
||||
use \DBSearch;
|
||||
use \DBUnionSearch;
|
||||
use \Combodo\iTop\DesignElement;
|
||||
|
||||
class LifecycleValidatorHelper
|
||||
{
|
||||
@@ -161,10 +158,10 @@ class LifecycleValidatorHelper
|
||||
}
|
||||
|
||||
// Retrieving profiles for the stimulus
|
||||
$oProfilesNode = $oStimulusNode->GetOptionalElement('allowed_profiles');
|
||||
$oProfilesNode = $oStimulusNode->GetOptionalElement('denied_profiles');
|
||||
$aProfilesNames = array();
|
||||
// If no profile is specified, we consider that it's for ALL the profiles
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0))
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./denied_profile')->length === 0))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
@@ -173,13 +170,13 @@ class LifecycleValidatorHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode)
|
||||
foreach ($oProfilesNode->GetNodes('./denied_profile') as $oProfileNode)
|
||||
{
|
||||
// Retrieving mandatory profile id attribute
|
||||
$sProfileId = $oProfileNode->getAttribute('id');
|
||||
if ($sProfileId === '')
|
||||
{
|
||||
throw new DOMFormatException('Stimulus tag must have an id attribute.', null, null, $oProfileNode);
|
||||
throw new DOMFormatException('Profile tag must have an id attribute.', null, null, $oProfileNode);
|
||||
}
|
||||
$aProfilesNames[] = $sProfileId;
|
||||
}
|
||||
@@ -287,6 +284,12 @@ class LifecycleValidatorHelper
|
||||
{
|
||||
$aStimuli = array();
|
||||
|
||||
// Preparing available stimuli
|
||||
foreach(MetaModel::EnumStimuli($sClass) as $sStimulusCode => $aData)
|
||||
{
|
||||
$aStimuli[$sStimulusCode] = true;
|
||||
}
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
@@ -297,19 +300,16 @@ class LifecycleValidatorHelper
|
||||
$sLifecycleValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sLifecycleValuesClass::GetProfileStimuli($iProfileId, $sClass);
|
||||
|
||||
// If the profile / class tuple is not present (null), it means that all stimuli are allowed
|
||||
if($aProfileMatrix === null)
|
||||
foreach($aProfileMatrix as $sStimulusCode)
|
||||
{
|
||||
$aImplicitStimuli = array_keys(MetaModel::EnumStimuli($sClass));
|
||||
$aStimuli = array_merge_recursive($aStimuli, $aImplicitStimuli);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aStimuli = array_merge_recursive($aStimuli, $aProfileMatrix);
|
||||
if(array_key_exists($sStimulusCode, $aStimuli))
|
||||
{
|
||||
unset($aStimuli[$sStimulusCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aStimuli;
|
||||
return array_keys($aStimuli);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,7 +374,7 @@ class LifecycleValidatorHelper
|
||||
// File generated by LifeCycleValidatorHelper
|
||||
//
|
||||
// Please do not edit manually
|
||||
// List of constant lifecycles
|
||||
// List of denied stimuli by profiles in the lifecycles
|
||||
// - used by the portal LifecycleValidatorHelper
|
||||
//
|
||||
class $sClassName
|
||||
@@ -382,12 +382,14 @@ class $sClassName
|
||||
protected static \$aPROFILES = $sProfiles;
|
||||
|
||||
/**
|
||||
* Returns the denied stimuli for a profile / class
|
||||
*
|
||||
* @param integer \$iProfileId
|
||||
* @param string \$sClass
|
||||
*/
|
||||
public static function GetProfileStimuli(\$iProfileId, \$sClass)
|
||||
{
|
||||
\$aStimuli = null;
|
||||
\$aStimuli = array();
|
||||
|
||||
\$sLifecycleKey = \$iProfileId.'_'.\$sClass;
|
||||
if (isset(self::\$aPROFILES[\$sLifecycleKey]))
|
||||
|
||||
@@ -186,8 +186,11 @@
|
||||
var iItemFlags = 0;
|
||||
// - Adding stub div
|
||||
var textElem = $('<div></div>').addClass('mosaic-item-text');
|
||||
// - Adding wrapper to textElem to easily control text's subnodes flow
|
||||
var textWrapperElem = $('<div></div>').addClass('mosaic-item-text-wrapper');
|
||||
textWrapperElem.appendTo(textElem);
|
||||
// - Adding image
|
||||
if( (item.image !== undefined) && (item.image !== '') )
|
||||
if( (item.image !== undefined) && (item.image !== '') && (item.image !== null) )
|
||||
{
|
||||
iItemFlags += 4;
|
||||
aElem.append( $('<div></div>').addClass('mosaic-item-image').append( $('<img />').attr('src', item.image) ) );
|
||||
@@ -196,13 +199,13 @@
|
||||
if( (item.name !== undefined) && (item.name !== '') )
|
||||
{
|
||||
iItemFlags += 1;
|
||||
textElem.append( $('<div></div>').addClass('mosaic-item-name').html(item.name) );
|
||||
textWrapperElem.append( $('<div></div>').addClass('mosaic-item-name').html(item.name) );
|
||||
}
|
||||
// - Adding description
|
||||
if( (item.description !== undefined) && (item.description !== '') )
|
||||
{
|
||||
iItemFlags += 2;
|
||||
textElem.append( $('<div></div>').addClass('mosaic-item-description').html(item.description) );
|
||||
textWrapperElem.append( $('<div></div>').addClass('mosaic-item-description').html(item.description) );
|
||||
}
|
||||
aElem.append( textElem );
|
||||
// - Adding CSS class to adjust the layout regarding which properties are available
|
||||
@@ -408,6 +411,7 @@
|
||||
registerFilterListeners();
|
||||
|
||||
// Open first level if only one item
|
||||
// TODO: We must disable opening of first level when pre-filtering when filtering will be implemented
|
||||
if($('#brick_content_mosaic > .mosaic-group[data-level-id="L"] > .mosaic-group-item').length == 1)
|
||||
{
|
||||
setTimeout(function(){
|
||||
|
||||
@@ -411,8 +411,8 @@
|
||||
registerFilterListeners();
|
||||
collapseAll();
|
||||
|
||||
// Open first level if only one item
|
||||
if($('#brick_content_tree > .list-group-item').length == 1)
|
||||
// Open first level if only one item and not pre-filtering
|
||||
if( ($('#brick_content_tree > .list-group-item').length == 1) && ($('#brick_search_field').val() === '') )
|
||||
{
|
||||
setTimeout(function(){
|
||||
$('#brick_content_tree > .list-group-item > .tree-toggle').trigger('click');
|
||||
|
||||
@@ -37,9 +37,11 @@
|
||||
<link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/scroller.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
<link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/select.bootstrap.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
<link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/datatables/css/select.dataTables.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Font Combodo #}
|
||||
{# - Font OpenSans #}
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-open-sans/font-open-sans.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Font Combodo #}
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-combodo/font-combodo.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Font awesome #}
|
||||
{# - Font awesome #}
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-awesome/css/font-awesome.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Misc libs #}
|
||||
<link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/css/typeaheadjs.bootstrap.css'|add_itop_version }}" rel="stylesheet">
|
||||
@@ -104,9 +106,7 @@
|
||||
{# Date-time picker for Bootstrap #}
|
||||
<script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js'|add_itop_version }}"></script>
|
||||
{# Typeahead files for autocomplete #}
|
||||
<script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/bloodhound.min.js'|add_itop_version }}"></script>
|
||||
<script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/typeahead.bundle.min.js'|add_itop_version }}"></script>
|
||||
<script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/js/typeahead.jquery.min.js'|add_itop_version }}"></script>
|
||||
<script type="text/javascript" src="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/handlebars/js/handlebars.min-768ddbd.js'|add_itop_version }}"></script>
|
||||
{# Form files #}
|
||||
<script type="text/javascript" src="{{ app['combodo.absolute_url'] ~ 'js/form_handler.js'|add_itop_version }}"></script>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,700");
|
||||
/*!
|
||||
* Combodo portal theme v1.0.0
|
||||
* Based on Bootswatch Simplex
|
||||
@@ -2745,6 +2744,10 @@ textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-
|
||||
/* To mask border from previous li item */
|
||||
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.8) inset;
|
||||
}
|
||||
.navbar-nav > li:last-child.active > a {
|
||||
margin-top: 0px;
|
||||
/* Overflow hack */
|
||||
}
|
||||
.navbar-nav > li > a {
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
@import 'variables.scss';
|
||||
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,700");
|
||||
|
||||
/*!
|
||||
* Combodo portal theme v1.0.0
|
||||
@@ -3471,10 +3470,13 @@ select[multiple].input-group-sm>.input-group-btn>.btn {
|
||||
border-right-width: 20px;
|
||||
border-right-color: $body-bg;
|
||||
}
|
||||
.navbar-nav>li.active>a{
|
||||
margin-top: -1px; /* To mask border from previous li item */
|
||||
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.8) inset;
|
||||
}
|
||||
.navbar-nav>li.active>a{
|
||||
margin-top: -1px; /* To mask border from previous li item */
|
||||
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.8) inset;
|
||||
}
|
||||
.navbar-nav>li:last-child.active>a{
|
||||
margin-top: 0px; /* Overflow hack */
|
||||
}
|
||||
.navbar-nav>li>a {
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
|
||||
@@ -628,10 +628,19 @@ table .group-actions {
|
||||
border-radius: 0px 0px 4px 4px;
|
||||
font-size: 1em;
|
||||
}
|
||||
/****************/
|
||||
/* - Mosaic mode */
|
||||
/* Note: Some of the CSS is factorised in the "Tree mode" part */
|
||||
/****************/
|
||||
/****************************************************************/
|
||||
/* - Mosaic mode */
|
||||
/* */
|
||||
/* Note: Some of the CSS is factorised in the "Tree mode" part */
|
||||
/* */
|
||||
/* Note: .mosaic-item-layout-x classes are for different */
|
||||
/* presentation modes. Like in binary, add the values to know */
|
||||
/* which class to use. */
|
||||
/* - 1 is for name */
|
||||
/* - 2 is for description */
|
||||
/* - 4 is for image */
|
||||
/* eg. .mosaic-item-layout-5 when just name and image */
|
||||
/****************************************************************/
|
||||
#brick_content_mosaic {
|
||||
position: relative;
|
||||
padding: 10px 10px 1px 10px;
|
||||
@@ -685,6 +694,11 @@ table .group-actions {
|
||||
.mosaic-item-image > img {
|
||||
max-width: 85%;
|
||||
}
|
||||
.mosaic-item-text {
|
||||
max-width: 1px;
|
||||
/* This is an arbitrary value. It is just here to make .mosaic-item-name wrap when there is a very long word in it. */
|
||||
overflow: hidden;
|
||||
}
|
||||
.mosaic-group-item > .mosaic-group-item-actions {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
@@ -698,7 +712,7 @@ table .group-actions {
|
||||
color: #eee;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
/* All layout */
|
||||
/* All layouts */
|
||||
/* Layout 2 */
|
||||
/* Layout 5/7 */
|
||||
.mosaic-group-item > .mosaic-group-item-actions {
|
||||
@@ -720,6 +734,8 @@ table .group-actions {
|
||||
}
|
||||
.mosaic-item-name {
|
||||
font-size: 14px;
|
||||
max-height: 50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mosaic-item-description {
|
||||
display: none;
|
||||
@@ -732,7 +748,10 @@ table .group-actions {
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
/* All layout */
|
||||
/* All layouts */
|
||||
/* .mosaic-item-image{
|
||||
vertical-align: inherit; Note: This was introduced to avoid image from going down the tile when .mosaic-item-name was way too long, but the .mosaic-item-image glitched by being a little too high. As a very long .mosaic-item-name is extremely rare, we decided that it was not worth it.
|
||||
}*/
|
||||
/* Layout 1 */
|
||||
/* Layout 7 */
|
||||
.mosaic-group-item {
|
||||
@@ -741,6 +760,7 @@ table .group-actions {
|
||||
height: 120px;
|
||||
margin-right: 1.95%;
|
||||
/* We don't put 2% to keep a margin in case of a bad browser rendering */
|
||||
word-break: break-word;
|
||||
}
|
||||
.mosaic-item {
|
||||
padding: 10px;
|
||||
@@ -749,7 +769,14 @@ table .group-actions {
|
||||
background-color: #ea7d1e;
|
||||
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.20);
|
||||
}
|
||||
.mosaic-item-text .mosaic-item-text-wrapper {
|
||||
max-height: 100px;
|
||||
/* Must be .mosaic-item absolute height (in px) */
|
||||
}
|
||||
.mosaic-item-name {
|
||||
max-height: 100%;
|
||||
/* It's ok if description is pushed down and not visible; but we truncate before it flows out of the tile */
|
||||
overflow: hidden;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
@@ -770,32 +797,39 @@ table .group-actions {
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
/* Layout 7 */
|
||||
/* Layout 5 & 7 */
|
||||
.mosaic-item {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.mosaic-group-back {
|
||||
font-size: 40px;
|
||||
}
|
||||
.mosaic-item-layout-7 .mosaic-item-image {
|
||||
.mosaic-item-layout-5 .mosaic-item-image, .mosaic-item-layout-7 .mosaic-item-image {
|
||||
display: table-cell;
|
||||
width: 105px;
|
||||
padding-left: 5px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
.mosaic-item-layout-7 .mosaic-item-image > img {
|
||||
max-width: 100%;
|
||||
.mosaic-item-layout-5 .mosaic-item-image > img, .mosaic-item-layout-7 .mosaic-item-image > img {
|
||||
max-width: 105px;
|
||||
/* Equals parent element width */
|
||||
}
|
||||
.mosaic-item-layout-7 .mosaic-item-name {
|
||||
.mosaic-item-layout-5 .mosaic-item-name, .mosaic-item-layout-7 .mosaic-item-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
/* All layouts */
|
||||
.mosaic-group-item {
|
||||
width: 24%;
|
||||
height: 140px;
|
||||
margin-right: 1.3%;
|
||||
}
|
||||
.mosaic-item-text .mosaic-item-text-wrapper {
|
||||
max-height: 120px;
|
||||
/* Must be .mosaic-item absolute height (in px) */
|
||||
/* overflow hidden inherited */
|
||||
}
|
||||
}
|
||||
/* Helper classes to remove margin depending on the screen size */
|
||||
@media (min-width: 768px) and (max-width: 992px) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user