mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
@@ -51,7 +51,8 @@
|
||||
"core",
|
||||
"application",
|
||||
"sources/application",
|
||||
"sources/Composer"
|
||||
"sources/Composer",
|
||||
"sources/Controller"
|
||||
],
|
||||
"exclude-from-classmap": [
|
||||
"core/dbobjectsearch.class.php",
|
||||
|
||||
@@ -4181,7 +4181,7 @@ abstract class MetaModel
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Contact WHERE id = :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetContactId()));
|
||||
$oSet->OptimizeColumnLoad($aCurrentContact);
|
||||
$oSet->OptimizeColumnLoad(['Contact' => $aCurrentContact]);
|
||||
$oUser = $oSet->fetch();
|
||||
foreach ($aCurrentContact as $sField)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
function ExportStartExport() {
|
||||
var oParams = {};
|
||||
oParams.operation = 'export_build';
|
||||
oParams.operation = 'export_build_portal';
|
||||
oParams.format = sFormat;
|
||||
oParams.token = sToken;
|
||||
oParams.start = 1;
|
||||
@@ -56,7 +56,7 @@ function ExportRun(data) {
|
||||
$('#export-close').show();
|
||||
}
|
||||
else {
|
||||
oParams.operation = 'export_build';
|
||||
oParams.operation = 'export_build_portal';
|
||||
}
|
||||
|
||||
$.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\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.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\\DesignElement' => $baseDir . '/core/designdocument.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\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.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\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.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
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Controller\AjaxRenderController;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||
|
||||
require_once('../approot.inc.php');
|
||||
@@ -51,17 +52,17 @@ try
|
||||
// Only allow export functions to portal users
|
||||
switch ($operation)
|
||||
{
|
||||
case 'export_build':
|
||||
case 'export_build_portal':
|
||||
case 'export_cancel':
|
||||
case 'export_download':
|
||||
case 'cke_img_upload':
|
||||
case 'cke_upload_and_browse':
|
||||
case 'cke_browse':
|
||||
$sRequestedPortalId = null;
|
||||
$sRequestedPortalId = null; // Allowed for all users
|
||||
break;
|
||||
|
||||
default:
|
||||
$sRequestedPortalId = 'backoffice';
|
||||
$sRequestedPortalId = 'backoffice'; // Allowed only for console users
|
||||
break;
|
||||
}
|
||||
LoginWebPage::DoLoginEx($sRequestedPortalId, false);
|
||||
@@ -79,9 +80,10 @@ try
|
||||
// some operations are also used in the portal though
|
||||
switch ($operation)
|
||||
{
|
||||
case 'export_build':
|
||||
case 'export_build_portal':
|
||||
case 'export_download':
|
||||
// do nothing : used in portal (export.js in portal-base)
|
||||
break;
|
||||
|
||||
default:
|
||||
ContextTag::AddContext(ContextTag::TAG_CONSOLE);
|
||||
@@ -2444,113 +2446,11 @@ EOF
|
||||
break;
|
||||
|
||||
case 'export_build':
|
||||
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 (!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();
|
||||
}
|
||||
AjaxRenderController::ExportBuild($oPage, false);
|
||||
break;
|
||||
|
||||
// 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));
|
||||
}
|
||||
case 'export_build_portal':
|
||||
AjaxRenderController::ExportBuild($oPage, true);
|
||||
break;
|
||||
|
||||
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