Merge remote-tracking branch 'origin/develop' into feature/backoffice-full-moon-design

# Conflicts:
#	application/datamodel.application.xml
#	application/itopwebpage.class.inc.php
#	css/light-grey.scss
This commit is contained in:
Molkobain
2020-08-19 10:20:37 +02:00
80 changed files with 2483 additions and 1530 deletions

View File

@@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\DBTools\Service\DBAnalyzerUtils;
@include_once('../approot.inc.php');
@include_once('../../approot.inc.php');
@include_once('../../../approot.inc.php');
require_once(APPROOT.'application/startup.inc.php');
require_once('../db_analyzer.class.inc.php');
require_once('../src/Service/DBAnalyzerUtils.php');
$oDBAnalyzer = new DatabaseAnalyzer(0);
$aResults = $oDBAnalyzer->CheckIntegrity([]);
if (empty($aResults))
{
echo "Database OK\n";
exit(0);
}
$sReportFile = DBAnalyzerUtils::GenerateReport($aResults);
echo "Report generated: {$sReportFile}.log\n";

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\DBTools\Service\DBAnalyzerUtils;
@include_once('../../approot.inc.php');
require_once(APPROOT.'application/startup.inc.php');
@@ -53,7 +55,7 @@ function DisplayDBInconsistencies(iTopWebPage &$oP, ApplicationContext &$oAppCon
$bRunAnalysis = intval(utils::ReadParam('run_analysis', '0'));
if ($bRunAnalysis)
{
$oDBAnalyzer = new DatabaseAnalyzer();
$oDBAnalyzer = new DatabaseAnalyzer(0);
$aResults = $oDBAnalyzer->CheckIntegrity($aClassSelection);
if (empty($aResults))
{
@@ -199,88 +201,23 @@ function DisplayDBInconsistencies(iTopWebPage &$oP, ApplicationContext &$oAppCon
*/
function DisplayInconsistenciesReport($aResults)
{
$sDBToolsFolder = str_replace("\\", '/', APPROOT.'log/');
$sReportFile = 'dbtools-report-'.date('Y-m-d-H-i-s');
$sCleanupFile = 'dbtools-cleanup-'.date('Y-m-d-H-i-s');
$fReport = fopen($sDBToolsFolder.$sReportFile.'.txt', 'w');
$fCleanUp = fopen($sDBToolsFolder.$sCleanupFile.'.txt', 'w');
fwrite($fReport, 'Database Maintenance tools: '.date('Y-m-d H:i:s')."\r\n");
foreach($aResults as $sClass => $aErrorList)
{
fwrite($fReport, '');
foreach($aErrorList as $sErrorLabel => $aError)
{
fwrite($fReport, "\r\n----------\r\n");
fwrite($fReport, 'Class: '.MetaModel::GetName($sClass).' ('.$sClass.")\r\n");
$iCount = $aError['count'];
fwrite($fReport, 'Count: '.$iCount."\r\n");
fwrite($fReport, 'Error: '.$sErrorLabel."\r\n");
$sQuery = $aError['query'];
fwrite($fReport, 'Query: '.$sQuery."\r\n");
if (isset($aError['fixit']))
{
fwrite($fReport, "\r\nFix it (indication):\r\n\r\n");
$aFixitQueries = $aError['fixit'];
foreach($aFixitQueries as $sFixitQuery)
{
fwrite($fReport, "$sFixitQuery\r\n");
}
fwrite($fReport, "\r\n");
}
if (isset($aError['cleanup']))
{
$aQueries = $aError['cleanup'];
foreach($aQueries as $sQuery)
{
fwrite($fCleanUp, "$sQuery;\r\n");
}
}
$sQueryResult = '';
$aIdList = array();
foreach($aError['res'] as $aRes)
{
foreach($aRes as $sKey => $sValue)
{
$sQueryResult .= "'$sKey'='$sValue' ";
if ($sKey == 'id')
{
$aIdList[] = $sValue;
}
}
$sQueryResult .= "\r\n";
}
fwrite($fReport, "Result: \r\n".$sQueryResult);
$sIdList = '('.implode(',', $aIdList).')';
fwrite($fReport, 'Ids: '.$sIdList."\r\n");
}
}
fclose($fReport);
fclose($fCleanUp);
$sReportFile = DBAnalyzerUtils::GenerateReport($aResults);
$sZipReport = "{$sReportFile}.zip";
$oArchive = new ZipArchive();
$oArchive->open($sDBToolsFolder.$sReportFile.'.zip', ZipArchive::CREATE);
$oArchive->addFile($sDBToolsFolder.$sReportFile.'.txt', $sReportFile.'.txt');
$oArchive->addFile($sDBToolsFolder.$sCleanupFile.'.txt', $sCleanupFile.'.txt');
$oArchive->open($sZipReport, ZipArchive::CREATE);
$oArchive->addFile($sReportFile.'.log', basename($sReportFile.'.log'));
$oArchive->close();
unlink($sDBToolsFolder.$sReportFile.'.txt');
unlink($sDBToolsFolder.$sCleanupFile.'.txt');
$sReportFile = $sDBToolsFolder.$sReportFile.'.zip';
header('Content-Description: File Transfer');
header('Content-Type: multipart/x-zip');
header('Content-Disposition: inline; filename="'.basename($sReportFile).'"');
header('Content-Disposition: inline; filename="'.basename($sZipReport).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.filesize($sReportFile));
readfile($sReportFile);
unlink($sReportFile);
header('Content-Length: '.filesize($sZipReport));
readfile($sZipReport);
unlink($sZipReport);
exit(0);
}

View File

@@ -42,7 +42,8 @@ SetupWebPage::AddModule(
//
'datamodel' => array(
'model.combodo-db-tools.php',
'src/Service/DBToolsUtils.php'
'src/Service/DBToolsUtils.php',
'src/Service/DBAnalyzerUtils.php',
),
'webservice' => array(),
'data.struct' => array(),

View File

@@ -0,0 +1,81 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\DBTools\Service;
use CoreException;
use DictExceptionMissingString;
use MetaModel;
class DBAnalyzerUtils
{
/**
* @param $aResults
*
* @return string
* @throws CoreException
* @throws DictExceptionMissingString
*/
public static function GenerateReport($aResults)
{
$sDBToolsFolder = str_replace("\\", '/', APPROOT.'log/');
$sReportFile = 'dbtools-report';
$fReport = fopen($sDBToolsFolder.$sReportFile.'.log', 'w');
fwrite($fReport, 'Database Maintenance tools: '.date('Y-m-d H:i:s')."\r\n");
foreach ($aResults as $sClass => $aErrorList)
{
fwrite($fReport, '');
foreach ($aErrorList as $sErrorLabel => $aError)
{
fwrite($fReport, "\r\n----------\r\n");
fwrite($fReport, 'Class: '.MetaModel::GetName($sClass).' ('.$sClass.")\r\n");
$iCount = $aError['count'];
fwrite($fReport, 'Count: '.$iCount."\r\n");
fwrite($fReport, 'Error: '.$sErrorLabel."\r\n");
$sQuery = $aError['query'];
fwrite($fReport, 'Query: '.$sQuery."\r\n");
if (isset($aError['fixit']))
{
fwrite($fReport, "\r\nFix it (indication):\r\n\r\n");
$aFixitQueries = $aError['fixit'];
foreach ($aFixitQueries as $sFixitQuery)
{
fwrite($fReport, "$sFixitQuery\r\n");
}
fwrite($fReport, "\r\n");
}
$sQueryResult = '';
$aIdList = array();
foreach ($aError['res'] as $aRes)
{
foreach ($aRes as $sKey => $sValue)
{
$sQueryResult .= "'$sKey'='$sValue' ";
if ($sKey == 'id')
{
$aIdList[] = $sValue;
}
}
$sQueryResult .= "\r\n";
}
fwrite($fReport, "Result: \r\n".$sQueryResult);
$sIdList = '('.implode(',', $aIdList).')';
fwrite($fReport, 'Ids: '.$sIdList."\r\n");
}
}
fclose($fReport);
$sReportFile = $sDBToolsFolder.$sReportFile;
return $sReportFile;
}
}

View File

@@ -20,8 +20,8 @@ function ExportStartExport() {
var oParams = {};
oParams.operation = 'export_build';
oParams.format = sFormat;
oParams.expression = sOQL;
oParams.fields = sFields;
oParams.token = sToken;
oParams.start = 1;
$.post(GetAbsoluteUrlAppRoot() + 'pages/ajax.render.php', oParams, function (data) {
if (data == null) {
ExportError('Export failed (no data provided), please contact your administrator');

View File

@@ -326,6 +326,10 @@ class ManageBrick extends PortalBrick
return $this->sTileMode;
}
public function GetDecorationCssClass()
{
return static::$aPresentationData[$this->sTileMode]['decorationCssClass'];
}
/**
* Sets the tile mode (display)
*

View File

@@ -20,22 +20,22 @@
namespace Combodo\iTop\Portal\Controller;
use AttributeExternalKey;
use AttributeLinkedSetIndirect;
use BinaryExpression;
use Combodo\iTop\Portal\Brick\AbstractBrick;
use Combodo\iTop\Portal\Brick\BrowseBrick;
use Combodo\iTop\Portal\Helper\BrowseBrickHelper;
use DBObjectSearch;
use DBObjectSet;
use DBSearch;
use FieldExpression;
use MetaModel;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use MetaModel;
use DBSearch;
use DBObjectSet;
use BinaryExpression;
use FieldExpression;
use VariableExpression;
use AttributeExternalKey;
use Combodo\iTop\Portal\Brick\AbstractBrick;
use Combodo\iTop\Portal\Brick\BrowseBrick;
/**
* Class BrowseBrickController
@@ -156,8 +156,11 @@ class BrowseBrickController extends BrickController
{
if (array_key_exists($sLevelAlias, $aRealiasingMap))
{
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($aRealiasingMap[$sLevelAlias],
$sLevelAlias);
/** @since 2.7.2 */
foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToChange)
{
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($sAliasToChange, $sLevelAlias);
}
}
}
}

View File

@@ -28,6 +28,7 @@ use AttributeImage;
use AttributeSet;
use AttributeTagSet;
use BinaryExpression;
use BulkExport;
use CMDBSource;
use Combodo\iTop\Portal\Brick\AbstractBrick;
use Combodo\iTop\Portal\Brick\ManageBrick;
@@ -245,11 +246,18 @@ class ManageBrickController extends BrickController
}
$sFields = implode(',', $aFields);
$sFormat = 'xlsx';
$oSearch->UpdateContextFromUser();
$oExporter = BulkExport::FindExporter($sFormat, $oSearch);
$oExporter->SetObjectList($oSearch);
$oExporter->SetFormat($sFormat);
$oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
$oExporter->SetFields($sFields);
$aData = array(
'oBrick' => $oBrick,
'sBrickId' => $sBrickId,
'sFields' => $sFields,
'sOQL' => $oSearch->ToOQL(),
'sToken' => $oExporter->SaveState(),
);
return $this->render(static::EXCEL_EXPORT_TEMPLATE_PATH, $aData);

View File

@@ -27,9 +27,8 @@
<script type="text/javascript">
var sDataState = 'not-yet-started';
var sOQL = {{ sOQL|json_encode|raw }};
var sToken = {{ sToken|raw }};
var sFormat = 'xlsx';
var sFields = "{{ sFields }}";
$(document).ready(function () {
window.setTimeout(function () {

View File

@@ -10,7 +10,7 @@
id="brick-{{ oBrick.GetId }}"
data-brick-id="{{ oBrick.GetId }}">
<div>
<div class="tile_title"><span class="icon fas fa-{{ oBrick.GetTileMode }}"></span> {{ oBrick.GetTitle()|dict_s }}
<div class="tile_title"><span class="icon fas fa-{{ oBrick.GetDecorationCssClass }}"></span> {{ oBrick.GetTitle()|dict_s }}
({{ iCount }})</span> </div>
{% include 'itop-portal-base/portal/templates/bricks/manage/mode-' ~ oBrick.GetTileMode ~ '.html.twig' with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
</div>

View File

@@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<ActionEmail id="1">
<name>Notification to a Workgroup</name>
<description>This action informs a team that a ticket has been assigned their workgroup</description>
<status>disabled</status>
<test_recipient></test_recipient>
<from>test@test.com</from>
<reply_to></reply_to>
<to>SELECT Team WHERE id=:this-&gt;workgroup_id</to>
<cc></cc>
<bcc></bcc>
<subject>The ticket $this-&gt;name()$, priority $this-&gt;label(priority)$ has been assigned to the workgroup $this-&gt;workgroup_name$</subject>
<body>&lt;html&gt;
&lt;body&gt;
&lt;p&gt;The ticket $this-&gt;name()$ has been assigned to the workgroup $this-&gt;workgroup_name$.&lt;/p&gt;
&lt;p&gt;Description: $this-&gt;title$&lt;/p&gt;
&lt;p&gt;Title: $this-&gt;title$&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;for more information on this ticket, click here: $this-&gt;hyperlink()$&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</body>
<importance>normal</importance>
</ActionEmail>
<ActionEmail id="2">
<name>Notification to Agent</name>
<description>This action informs an agent that a ticket has been assigned to her/him</description>
<status>disabled</status>
<test_recipient></test_recipient>
<from>test@test.com</from>
<reply_to></reply_to>
<to>SELECT Person WHERE id=:this-&gt;agent_id</to>
<cc></cc>
<bcc></bcc>
<subject>The ticket $this-&gt;name()$, priority $this-&gt;label(priority)$ has been assigned to you</subject>
<body>&lt;html&gt;
&lt;body&gt;
&lt;p&gt;The ticket $this-&gt;name()$ has been assigned to you.&lt;/p&gt;
&lt;p&gt;Description: $this-&gt;title$&lt;/p&gt;
&lt;p&gt;Title: $this-&gt;title$&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;for more information on this ticket, click here: $this-&gt;hyperlink()$&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</body>
<importance>normal</importance>
</ActionEmail>
<ActionEmail id="3">
<name>Notification to caller</name>
<description>This action is used to inform the caller</description>
<status>disabled</status>
<test_recipient></test_recipient>
<from>test@test.com</from>
<reply_to></reply_to>
<to>SELECT Person WHERE id=:this-&gt;caller_id</to>
<cc></cc>
<bcc></bcc>
<subject>Ticket $this-&gt;name()$, priority $this-&gt;label(priority)$ - $this-&gt;status$</subject>
<body>&lt;html&gt;
&lt;body&gt;
&lt;p&gt;The ticket $this-&gt;name()$ has changed to status $this-&gt;status$&lt;/p&gt;
&lt;p&gt;Last update: $this-&gt;last_update$&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;for more information on this ticket, click here: $this-&gt;hyperlink(portal)$&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</body>
<importance>normal</importance>
</ActionEmail>
</Set>