mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 15:22:17 +02:00
Merge remote-tracking branch 'origin/support/2.7.2' into support/2.7
This commit is contained in:
@@ -51,7 +51,8 @@
|
|||||||
"core",
|
"core",
|
||||||
"application",
|
"application",
|
||||||
"sources/application",
|
"sources/application",
|
||||||
"sources/Composer"
|
"sources/Composer",
|
||||||
|
"sources/Controller"
|
||||||
],
|
],
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
"core/dbobjectsearch.class.php",
|
"core/dbobjectsearch.class.php",
|
||||||
|
|||||||
@@ -4181,7 +4181,7 @@ abstract class MetaModel
|
|||||||
{
|
{
|
||||||
$oSearch = DBObjectSearch::FromOQL("SELECT Contact WHERE id = :id");
|
$oSearch = DBObjectSearch::FromOQL("SELECT Contact WHERE id = :id");
|
||||||
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetContactId()));
|
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetContactId()));
|
||||||
$oSet->OptimizeColumnLoad($aCurrentContact);
|
$oSet->OptimizeColumnLoad(['Contact' => $aCurrentContact]);
|
||||||
$oUser = $oSet->fetch();
|
$oUser = $oSet->fetch();
|
||||||
foreach ($aCurrentContact as $sField)
|
foreach ($aCurrentContact as $sField)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
function ExportStartExport() {
|
function ExportStartExport() {
|
||||||
var oParams = {};
|
var oParams = {};
|
||||||
oParams.operation = 'export_build';
|
oParams.operation = 'export_build_portal';
|
||||||
oParams.format = sFormat;
|
oParams.format = sFormat;
|
||||||
oParams.token = sToken;
|
oParams.token = sToken;
|
||||||
oParams.start = 1;
|
oParams.start = 1;
|
||||||
@@ -56,7 +56,7 @@ function ExportRun(data) {
|
|||||||
$('#export-close').show();
|
$('#export-close').show();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
oParams.operation = 'export_build';
|
oParams.operation = 'export_build_portal';
|
||||||
}
|
}
|
||||||
|
|
||||||
$.post(GetAbsoluteUrlAppRoot() + 'pages/ajax.render.php', oParams, function (data) {
|
$.post(GetAbsoluteUrlAppRoot() + 'pages/ajax.render.php', oParams, function (data) {
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ return array(
|
|||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/application/TwigBase/Twig/Extension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/application/TwigBase/Twig/Extension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
||||||
|
'Combodo\\iTop\\Controller\\AjaxRenderController' => $baseDir . '/sources/Controller/AjaxRenderController.php',
|
||||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php',
|
'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php',
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/Extension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/Extension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
||||||
|
'Combodo\\iTop\\Controller\\AjaxRenderController' => __DIR__ . '/../..' . '/sources/Controller/AjaxRenderController.php',
|
||||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php',
|
'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Controller\AjaxRenderController;
|
||||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||||
|
|
||||||
require_once('../approot.inc.php');
|
require_once('../approot.inc.php');
|
||||||
@@ -51,17 +52,17 @@ try
|
|||||||
// Only allow export functions to portal users
|
// Only allow export functions to portal users
|
||||||
switch ($operation)
|
switch ($operation)
|
||||||
{
|
{
|
||||||
case 'export_build':
|
case 'export_build_portal':
|
||||||
case 'export_cancel':
|
case 'export_cancel':
|
||||||
case 'export_download':
|
case 'export_download':
|
||||||
case 'cke_img_upload':
|
case 'cke_img_upload':
|
||||||
case 'cke_upload_and_browse':
|
case 'cke_upload_and_browse':
|
||||||
case 'cke_browse':
|
case 'cke_browse':
|
||||||
$sRequestedPortalId = null;
|
$sRequestedPortalId = null; // Allowed for all users
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$sRequestedPortalId = 'backoffice';
|
$sRequestedPortalId = 'backoffice'; // Allowed only for console users
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LoginWebPage::DoLoginEx($sRequestedPortalId, false);
|
LoginWebPage::DoLoginEx($sRequestedPortalId, false);
|
||||||
@@ -79,9 +80,10 @@ try
|
|||||||
// some operations are also used in the portal though
|
// some operations are also used in the portal though
|
||||||
switch ($operation)
|
switch ($operation)
|
||||||
{
|
{
|
||||||
case 'export_build':
|
case 'export_build_portal':
|
||||||
case 'export_download':
|
case 'export_download':
|
||||||
// do nothing : used in portal (export.js in portal-base)
|
// do nothing : used in portal (export.js in portal-base)
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ContextTag::AddContext(ContextTag::TAG_CONSOLE);
|
ContextTag::AddContext(ContextTag::TAG_CONSOLE);
|
||||||
@@ -2444,113 +2446,11 @@ EOF
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'export_build':
|
case 'export_build':
|
||||||
register_shutdown_function(function () {
|
AjaxRenderController::ExportBuild($oPage, false);
|
||||||
$aErr = error_get_last();
|
break;
|
||||||
if (($aErr !== null) && ($aErr['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR)))
|
|
||||||
{
|
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode(array('code' => 'error', 'percentage' => 100, 'message' => Dict::Format('UI:Error_Details', $aErr['message'])));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$token = utils::ReadParam('token', null);
|
|
||||||
$sTokenForDisplay = utils::HtmlEntities($token);
|
|
||||||
$aResult = array( // Fallback error, just in case
|
|
||||||
'code' => 'error',
|
|
||||||
'percentage' => 100,
|
|
||||||
'message' => "Export not found for token: '$sTokenForDisplay'",
|
|
||||||
);
|
|
||||||
$data = '';
|
|
||||||
if ($token === null)
|
|
||||||
{
|
|
||||||
if (!ContextTag::Check('backoffice'))
|
|
||||||
{
|
|
||||||
throw new Exception('Missing token');
|
|
||||||
}
|
|
||||||
$sFormat = utils::ReadParam('format', '');
|
|
||||||
$sExpression = utils::ReadParam('expression', null, false, 'raw_data');
|
|
||||||
$iQueryId = utils::ReadParam('query', null);
|
|
||||||
if ($sExpression === null)
|
|
||||||
{
|
|
||||||
$oQuerySearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $iQueryId));
|
|
||||||
$oQuerySearch->UpdateContextFromUser();
|
|
||||||
$oQueries = new DBObjectSet($oQuerySearch);
|
|
||||||
if ($oQueries->Count() > 0)
|
|
||||||
{
|
|
||||||
$oQuery = $oQueries->Fetch();
|
|
||||||
$sExpression = $oQuery->Get('oql');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => "Invalid query phrasebook identifier: '$iQueryId'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($sExpression !== null)
|
|
||||||
{
|
|
||||||
$oSearch = DBObjectSearch::FromOQL($sExpression);
|
|
||||||
$oSearch->UpdateContextFromUser();
|
|
||||||
$oExporter = BulkExport::FindExporter($sFormat, $oSearch);
|
|
||||||
$oExporter->SetObjectList($oSearch);
|
|
||||||
$oExporter->SetFormat($sFormat);
|
|
||||||
$oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
|
|
||||||
$oExporter->ReadParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
// First pass, generate the headers
|
case 'export_build_portal':
|
||||||
$data .= $oExporter->GetHeader();
|
AjaxRenderController::ExportBuild($oPage, true);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oExporter = BulkExport::FindExporterFromToken($token);
|
|
||||||
if (utils::ReadParam('start', 0, false, 'integer') == 1)
|
|
||||||
{
|
|
||||||
// From portal, the first call is using a token
|
|
||||||
$data .= $oExporter->GetHeader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($oExporter)
|
|
||||||
{
|
|
||||||
$data .= $oExporter->GetNextChunk($aResult);
|
|
||||||
if ($aResult['code'] != 'done')
|
|
||||||
{
|
|
||||||
$oExporter->AppendToTmpFile($data);
|
|
||||||
$aResult['token'] = $oExporter->SaveState();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Last pass
|
|
||||||
$data .= $oExporter->GetFooter();
|
|
||||||
$oExporter->AppendToTmpFile($data);
|
|
||||||
$aResult['token'] = $oExporter->SaveState();
|
|
||||||
if (substr($oExporter->GetMimeType(), 0, 5) == 'text/')
|
|
||||||
{
|
|
||||||
// Result must be encoded in UTF-8 to be passed as part of a JSON structure
|
|
||||||
$sCharset = $oExporter->GetCharacterSet();
|
|
||||||
if (strtoupper($sCharset) != 'UTF-8')
|
|
||||||
{
|
|
||||||
$aResult['text_result'] = iconv($sCharset, 'UTF-8', file_get_contents($oExporter->GetTmpFilePath()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aResult['text_result'] = file_get_contents($oExporter->GetTmpFilePath());
|
|
||||||
}
|
|
||||||
$aResult['mime_type'] = $oExporter->GetMimeType();
|
|
||||||
}
|
|
||||||
$aResult['message'] = Dict::Format('Core:BulkExport:ClickHereToDownload_FileName', $oExporter->GetDownloadFileName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$oPage->add(json_encode($aResult));
|
|
||||||
} catch (BulkExportException $e)
|
|
||||||
{
|
|
||||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->GetLocalizedMessage()));
|
|
||||||
$oPage->add(json_encode($aResult));
|
|
||||||
} catch (Exception $e)
|
|
||||||
{
|
|
||||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->getMessage()));
|
|
||||||
$oPage->add(json_encode($aResult));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'export_download':
|
case 'export_download':
|
||||||
|
|||||||
116
sources/Controller/AjaxRenderController.php
Normal file
116
sources/Controller/AjaxRenderController.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Controller;
|
||||||
|
|
||||||
|
use ajax_page;
|
||||||
|
use BulkExport;
|
||||||
|
use BulkExportException;
|
||||||
|
use DBObjectSearch;
|
||||||
|
use DBObjectSet;
|
||||||
|
use Dict;
|
||||||
|
use Exception;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
class AjaxRenderController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param \ajax_page $oPage
|
||||||
|
*
|
||||||
|
* @param bool $bTokenOnly
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function ExportBuild(ajax_page $oPage, bool $bTokenOnly)
|
||||||
|
{
|
||||||
|
register_shutdown_function(function () {
|
||||||
|
$aErr = error_get_last();
|
||||||
|
if (($aErr !== null) && ($aErr['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR))) {
|
||||||
|
ob_end_clean();
|
||||||
|
echo json_encode(array('code' => 'error', 'percentage' => 100, 'message' => Dict::Format('UI:Error_Details', $aErr['message'])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
$token = utils::ReadParam('token', null);
|
||||||
|
$sTokenForDisplay = utils::HtmlEntities($token);
|
||||||
|
$aResult = array( // Fallback error, just in case
|
||||||
|
'code' => 'error',
|
||||||
|
'percentage' => 100,
|
||||||
|
'message' => "Export not found for token: '$sTokenForDisplay'",
|
||||||
|
);
|
||||||
|
$data = '';
|
||||||
|
if ($token === null) {
|
||||||
|
if ($bTokenOnly) {
|
||||||
|
throw new Exception('Access not allowed');
|
||||||
|
}
|
||||||
|
$sFormat = utils::ReadParam('format', '');
|
||||||
|
$sExpression = utils::ReadParam('expression', null, false, 'raw_data');
|
||||||
|
$iQueryId = utils::ReadParam('query', null);
|
||||||
|
if ($sExpression === null) {
|
||||||
|
$oQuerySearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $iQueryId));
|
||||||
|
$oQuerySearch->UpdateContextFromUser();
|
||||||
|
$oQueries = new DBObjectSet($oQuerySearch);
|
||||||
|
if ($oQueries->Count() > 0) {
|
||||||
|
$oQuery = $oQueries->Fetch();
|
||||||
|
$sExpression = $oQuery->Get('oql');
|
||||||
|
} else {
|
||||||
|
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => "Invalid query phrasebook identifier: '$iQueryId'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($sExpression !== null) {
|
||||||
|
$oSearch = DBObjectSearch::FromOQL($sExpression);
|
||||||
|
$oSearch->UpdateContextFromUser();
|
||||||
|
$oExporter = BulkExport::FindExporter($sFormat, $oSearch);
|
||||||
|
$oExporter->SetObjectList($oSearch);
|
||||||
|
$oExporter->SetFormat($sFormat);
|
||||||
|
$oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
|
||||||
|
$oExporter->ReadParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
// First pass, generate the headers
|
||||||
|
$data .= $oExporter->GetHeader();
|
||||||
|
} else {
|
||||||
|
$oExporter = BulkExport::FindExporterFromToken($token);
|
||||||
|
if (utils::ReadParam('start', 0, false, 'integer') == 1) {
|
||||||
|
// From portal, the first call is using a token
|
||||||
|
$data .= $oExporter->GetHeader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oExporter) {
|
||||||
|
$data .= $oExporter->GetNextChunk($aResult);
|
||||||
|
if ($aResult['code'] != 'done') {
|
||||||
|
$oExporter->AppendToTmpFile($data);
|
||||||
|
$aResult['token'] = $oExporter->SaveState();
|
||||||
|
} else {
|
||||||
|
// Last pass
|
||||||
|
$data .= $oExporter->GetFooter();
|
||||||
|
$oExporter->AppendToTmpFile($data);
|
||||||
|
$aResult['token'] = $oExporter->SaveState();
|
||||||
|
if (substr($oExporter->GetMimeType(), 0, 5) == 'text/') {
|
||||||
|
// Result must be encoded in UTF-8 to be passed as part of a JSON structure
|
||||||
|
$sCharset = $oExporter->GetCharacterSet();
|
||||||
|
if (strtoupper($sCharset) != 'UTF-8') {
|
||||||
|
$aResult['text_result'] = iconv($sCharset, 'UTF-8', file_get_contents($oExporter->GetTmpFilePath()));
|
||||||
|
} else {
|
||||||
|
$aResult['text_result'] = file_get_contents($oExporter->GetTmpFilePath());
|
||||||
|
}
|
||||||
|
$aResult['mime_type'] = $oExporter->GetMimeType();
|
||||||
|
}
|
||||||
|
$aResult['message'] = Dict::Format('Core:BulkExport:ClickHereToDownload_FileName', $oExporter->GetDownloadFileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$oPage->add(json_encode($aResult));
|
||||||
|
} catch (BulkExportException $e) {
|
||||||
|
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->GetLocalizedMessage()));
|
||||||
|
$oPage->add(json_encode($aResult));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->getMessage()));
|
||||||
|
$oPage->add(json_encode($aResult));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user