2016-10-06 15:57:01 +00:00
< ? php
/**
* File :
* class . module . php
*
* Description :
* cApi class
*
* @ package Core
* @ subpackage cApi
2019-07-03 11:58:28 +00:00
* @ version $Rev $
2016-10-06 15:57:01 +00:00
* @ since 2.0
* @ author Ortwin Pinke < o . pinke @ conlite . org >
* @ copyright ( c ) 2015 , conlite . org
* @ license http :// www . gnu . de / documents / gpl . en . html GPL v3 ( english version )
* @ license http :// www . gnu . de / documents / gpl . de . html GPL v3 ( deutsche Version )
* @ link http :// www . conlite . org ConLite . org
*
2019-07-03 11:58:28 +00:00
* $Id $
2016-10-06 15:57:01 +00:00
*/
if ( ! defined ( 'CON_FRAMEWORK' )) {
die ( 'Illegal call' );
}
cInclude ( 'includes' , 'functions.upl.php' );
class cApiModuleCollection extends ItemCollection {
/**
* Constructor Function
* @ param none
*/
public function __construct () {
global $cfg ;
parent :: __construct ( $cfg [ " tab " ][ " mod " ], " idmod " );
$this -> _setItemClass ( " cApiModule " );
}
/**
* Creates a new communication item
*/
public function create ( $name ) {
global $auth , $client ;
2016-10-08 13:39:50 +00:00
$item = parent :: createNewItem ();
2016-10-06 15:57:01 +00:00
$item -> set ( " idclient " , $client );
$item -> set ( " name " , $name );
$item -> set ( " author " , $auth -> auth [ " uid " ]);
$item -> set ( " created " , date ( " Y-m-d H:i:s " ), false );
$item -> store ();
return $item ;
}
public function delete ( $iIdMod ) {
/* @var $oMod cApiModule */
$oMod = $this -> _itemClassInstance ;
$oMod -> _bNoted = TRUE ;
$oMod -> loadByPrimaryKey ( $iIdMod );
2023-07-19 16:33:52 +00:00
if ( $oMod -> isLoaded () && $oMod -> hasModuleFolder ()) {
$oMod -> deleteModuleFolder ();
2016-10-06 15:57:01 +00:00
}
unset ( $oMod );
return parent :: delete ( $iIdMod );
}
}
/**
* Module access class
*/
class cApiModule extends Item {
2023-07-19 16:33:52 +00:00
public $_oldumask ;
/**
* @ var mixed
*/
public $_sModAliasOld ;
public $_bNoted ;
2016-10-06 15:57:01 +00:00
protected $_error ;
/**
* Assoziative package structure array
* @ var array
*/
protected $_packageStructure ;
protected $_bOutputFromFile = false ;
protected $_bInputFromFile = false ;
2023-07-19 16:33:52 +00:00
private array $aUsedTemplates = [];
2016-10-06 15:57:01 +00:00
/**
* Configuration Array of ModFileEdit
* array is set with entries in local config file
*
* @ var array
*/
2023-07-19 16:33:52 +00:00
private $_aModFileEditConf = [ 'use' => false , 'modFolderName' => 'data/modules' ];
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
private ? string $_sModAlias = null ;
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
private ? string $_sModPath = null ;
private array $_aModDefaultStruct = [ 'css' , 'js' , 'php' , 'template' , 'image' , 'lang' , 'xml' ];
2016-10-06 15:57:01 +00:00
/**
* Constructor Function
* @ param mixed $mId Specifies the ID of item to load
*/
public function __construct ( $mId = false ) {
2022-10-25 18:28:00 +00:00
$cfg = cRegistry :: getConfig ();
$cfgClient = cRegistry :: getClientConfig ( cRegistry :: getClientId ());
2021-05-21 17:32:51 +00:00
2016-10-06 15:57:01 +00:00
parent :: __construct ( $cfg [ " tab " ][ " mod " ], " idmod " );
// Using no filters is just for compatibility reasons.
// That's why you don't have to stripslashes values if you store them
// using ->set. You have to add slashes, if you store data directly
// (data not from a form field)
2023-07-19 16:33:52 +00:00
$this -> setFilters ([], []);
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
$this -> _packageStructure = [ " jsfiles " => $cfgClient [ " js " ][ " path " ], " tplfiles " => $cfgClient [ " tpl " ][ " path " ], " cssfiles " => $cfgClient [ " css " ][ " path " ]];
2016-10-06 15:57:01 +00:00
if ( isset ( $cfg [ 'dceModEdit' ]) && is_array ( $cfg [ 'dceModEdit' ])) {
2022-10-25 18:28:00 +00:00
$this -> _aModFileEditConf [ 'clientPath' ] = $cfgClient [ " path " ][ " frontend " ];
2016-10-06 15:57:01 +00:00
$this -> _aModFileEditConf = array_merge ( $this -> _aModFileEditConf , $cfg [ 'dceModEdit' ]);
if ( ! isset ( $cfg [ 'dceModEdit' ][ 'modPath' ]) || empty ( $cfg [ 'dceModEdit' ][ 'modPath' ])) {
2022-10-25 18:28:00 +00:00
$this -> _aModFileEditConf [ 'modPath' ] = $cfgClient [ " path " ][ " frontend " ]
2016-10-06 15:57:01 +00:00
. $this -> _aModFileEditConf [ 'modFolderName' ] . " / " ;
}
}
2023-07-19 16:33:52 +00:00
$cApiClient = new cApiClient ( cRegistry :: getClientId ());
$aClientProp = $cApiClient -> getPropertiesByType ( 'modfileedit' );
if ( $aClientProp !== []) {
2021-05-21 17:32:51 +00:00
$this -> _aModFileEditConf = array_merge ( $this -> _aModFileEditConf , $aClientProp );
}
2016-10-08 13:39:50 +00:00
2016-10-06 15:57:01 +00:00
if ( $mId !== false ) {
$this -> loadByPrimaryKey ( $mId );
}
}
public function createModuleFolder () {
//echo $this->_aModFileEditConf['modPath'];
2021-05-21 17:32:51 +00:00
$sPathErrorLog = cRegistry :: getConfigValue ( 'path' , 'logs' ) . 'errorlog.txt' ;
2016-10-06 15:57:01 +00:00
if ( is_writable ( $this -> _aModFileEditConf [ 'clientPath' ]) && ! file_exists ( $this -> _aModFileEditConf [ 'modPath' ])) {
try {
mkdir ( $this -> _aModFileEditConf [ 'modPath' ], 0777 , true );
} catch ( Exception $ex ) {
2023-07-19 16:33:52 +00:00
$oWriter = cLogWriter :: factory ( " File " , [ 'destination' => $sPathErrorLog ]);
2016-10-06 15:57:01 +00:00
$oLog = new cLog ( $oWriter );
2019-08-19 03:13:29 +00:00
$oLog -> log ( $ex -> getFile () . " ( " . $ex -> getLine () . " ): " . $ex -> getMessage (), cLog :: WARN );
2016-10-06 15:57:01 +00:00
}
}
2021-05-21 17:32:51 +00:00
if ( $this -> _aModFileEditConf [ 'use' ] == true && is_writable ( $this -> _aModFileEditConf [ 'modPath' ])) {
2016-10-06 15:57:01 +00:00
if ( ! is_dir ( $this -> getModulePath ())) {
$this -> _oldumask = umask ( 0 );
2021-05-21 17:32:51 +00:00
try {
mkdir ( $this -> getModulePath (), 0777 );
} catch ( Exception $ex ) {
2023-07-19 16:33:52 +00:00
$oWriter = cLogWriter :: factory ( " File " , [ 'destination' => $sPathErrorLog ]);
2021-05-21 17:32:51 +00:00
$oLog = new cLog ( $oWriter );
$oLog -> log ( $ex -> getFile () . " ( " . $ex -> getLine () . " ): " . $ex -> getMessage (), cLog :: WARN );
}
if ( is_writable ( $this -> getModulePath ())) {
2016-10-06 15:57:01 +00:00
return $this -> _createModuleStruct ();
}
umask ( $this -> _oldumask );
}
2021-05-21 17:32:51 +00:00
} else {
2023-07-19 16:33:52 +00:00
$oWriter = cLogWriter :: factory ( " File " , [ 'destination' => $sPathErrorLog ]);
2021-05-21 17:32:51 +00:00
$oLog = new cLog ( $oWriter );
$oLog -> log ( __FILE__ . " ( " . __LINE__ . " ): " . 'Error: Cannot create mod path ' . $this -> getModulePath (), cLog :: WARN );
2016-10-06 15:57:01 +00:00
}
return FALSE ;
}
public function deleteModuleFolder () {
2023-07-19 16:33:52 +00:00
if ( $this -> _aModFileEditConf [ 'use' ] == TRUE && is_writable ( $this -> _aModFileEditConf [ 'modPath' ]) && is_dir ( $this -> getModulePath ())) {
return $this -> _recursiveRemoveDirectory ( $this -> getModulePath ());
2016-10-06 15:57:01 +00:00
}
return FALSE ;
}
public function getModuleAlias () {
return $this -> _sModAlias ;
}
public function hasModuleFolder () {
$sOldPath = $this -> _aModFileEditConf [ 'modPath' ] . uplCreateFriendlyName ( $this -> get ( " name " ));
return ( file_exists ( $this -> getModulePath ()) || file_exists ( $sOldPath ));
}
public function getModulePath () {
if ( empty ( $this -> _sModPath )) {
$this -> _setModulePath ();
}
return $this -> _sModPath ;
}
protected function _setModulePath () {
$this -> _sModPath = $this -> _aModFileEditConf [ 'modPath' ] . $this -> getModuleAlias () . " / " ;
}
/**
* Returns the translated name of the module if a translation exists .
*
* @ param none
* @ return string Translated module name or original
*/
public function getTranslatedName () {
global $lang ;
// If we're not loaded, return
if ( $this -> virgin == true ) {
return false ;
}
$modname = $this -> getProperty ( " translated-name " , $lang );
if ( $modname === false ) {
return $this -> get ( " name " );
} else {
return $modname ;
}
}
/**
* Sets the translated name of the module
*
* @ param $name string Translated name of the module
* @ return none
*/
public function setTranslatedName ( $name ) {
global $lang ;
$this -> setProperty ( " translated-name " , $lang , $name );
}
/**
* Parses the module for mi18n strings and returns them in an array
*
* @ return array Found strings for this module
*/
public function parseModuleForStrings () {
2023-05-05 07:20:09 +00:00
global $cfg ;
2016-10-06 15:57:01 +00:00
if ( $this -> virgin == true ) {
return false ;
}
// Fetch the code, append input to output
$code = $this -> get ( " output " );
$code .= $this -> get ( " input " );
// Initialize array
2023-07-19 16:33:52 +00:00
$strings = [];
2016-10-06 15:57:01 +00:00
// Split the code into mi18n chunks
$varr = preg_split ( '/mi18n([\s]*)\(([\s]*)"/' , $code , - 1 );
2023-07-19 16:33:52 +00:00
if (( is_countable ( $varr ) ? count ( $varr ) : 0 ) > 1 ) {
2016-10-06 15:57:01 +00:00
foreach ( $varr as $key => $value ) {
// Search first closing
$closing = strpos ( $value , '")' );
if ( $closing === false ) {
$closing = strpos ( $value , '" )' );
}
if ( $closing !== false ) {
$value = substr ( $value , 0 , $closing ) . '")' ;
}
// Append mi18n again
$varr [ $key ] = 'mi18n("' . $value ;
// Parse for the mi18n stuff
preg_match_all ( '/mi18n([\s]*)\("(.*)"\)/' , $varr [ $key ], $results );
// Append to strings array if there are any results
2023-07-19 16:33:52 +00:00
if ( is_array ( $results [ 1 ]) && ( is_countable ( $results [ 2 ]) ? count ( $results [ 2 ]) : 0 ) > 0 ) {
2016-10-06 15:57:01 +00:00
$strings = array_merge ( $strings , $results [ 2 ]);
}
// Unset the results for the next run
unset ( $results );
}
}
// adding dynamically new module translations by content types
// this function was introduced with contenido 4.8.13
// checking if array is set to prevent crashing the module translation page
2023-07-19 16:33:52 +00:00
if ( is_array ( $cfg [ 'translatable_content_types' ]) && $cfg [ 'translatable_content_types' ] !== []) {
2016-10-06 15:57:01 +00:00
// iterate over all defines cms content types
foreach ( $cfg [ 'translatable_content_types' ] as $sContentType ) {
// check if the content type exists and include his class file
if ( file_exists ( $cfg [ 'contenido' ][ 'path' ] . " classes/class. " . strtolower ( $sContentType ) . " .php " )) {
cInclude ( " classes " , " class. " . strtolower ( $sContentType ) . " .php " );
// if the class exists, has the method "addModuleTranslations"
// and the current module contains this cms content type we
// add the additional translations for the module
2021-05-21 17:32:51 +00:00
if ( class_exists ( $sContentType ) && method_exists ( $sContentType , 'addModuleTranslations' ) && preg_match ( '/' . strtoupper ( $sContentType ) . '\[\d+\]/' , $code )) {
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
$strings = call_user_func ([ $sContentType , 'addModuleTranslations' ], $strings );
2016-10-06 15:57:01 +00:00
}
}
}
}
// Make the strings unique
return array_unique ( $strings );
}
/**
* Checks if the module is in use
* @ return bool Specifies if the module is in use
*/
public function moduleInUse ( $module , $bSetData = false ) {
global $cfg ;
2023-07-19 16:33:52 +00:00
$dbConLite = new DB_ConLite ();
2016-10-06 15:57:01 +00:00
$sql = " SELECT
c . idmod , c . idtpl , t . name
FROM
" . $cfg["tab"] [ " container " ] . " as c ,
" . $cfg["tab"] [ " tpl " ] . " as t
WHERE
c . idmod = '" . Contenido_Security::toInteger($module) . "' AND
t . idtpl = c . idtpl
GROUP BY c . idtpl
ORDER BY t . name " ;
2023-07-19 16:33:52 +00:00
$dbConLite -> query ( $sql );
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
if ( $dbConLite -> nf () == 0 ) {
2016-10-06 15:57:01 +00:00
return false ;
} else {
$i = 0 ;
// save the datas of used templates in array
if ( $bSetData === true ) {
2023-07-19 16:33:52 +00:00
while ( $dbConLite -> next_record ()) {
$this -> aUsedTemplates [ $i ][ 'tpl_name' ] = $dbConLite -> f ( 'name' );
$this -> aUsedTemplates [ $i ][ 'tpl_id' ] = ( int ) $dbConLite -> f ( 'idmod' );
2016-10-06 15:57:01 +00:00
$i ++ ;
}
}
return true ;
}
}
/**
* Get the informations of used templates
* @ return array template data
*/
public function getUsedTemplates () {
return $this -> aUsedTemplates ;
}
/**
* Checks if the module is a pre - 4.3 module
* @ return boolean true if this module is an old one
2022-10-25 18:28:00 +00:00
*
* @ deprecated since version 2.0
2016-10-06 15:57:01 +00:00
*/
public function isOldModule () {
// Keywords to scan
2023-07-19 16:33:52 +00:00
$scanKeywords = [ '$cfgTab' , 'idside' , 'idsidelang' ];
2016-10-06 15:57:01 +00:00
$input = $this -> get ( " input " );
$output = $this -> get ( " output " );
2023-07-19 16:33:52 +00:00
foreach ( $scanKeywords as $scanKeyword ) {
if ( strstr ( $input , $scanKeyword )) {
2016-10-06 15:57:01 +00:00
return true ;
}
2023-07-19 16:33:52 +00:00
if ( strstr ( $output , $scanKeyword )) {
2016-10-06 15:57:01 +00:00
return true ;
}
}
}
public function getField ( $field ) {
$value = parent :: getField ( $field );
2023-07-19 16:33:52 +00:00
if ( $field === " name " && $value == " " ) {
$value = i18n ( " - Unnamed Module - " );
2016-10-06 15:57:01 +00:00
}
return ( $value );
}
public function store ( $bJustStore = false ) {
global $cfg ;
/* dceModFileEdit (c)2009-2011 www.dceonline.de */
2023-07-19 16:33:52 +00:00
if ( $this -> _aModFileEditConf [ 'use' ] == true && ( $this -> _aModFileEditConf [ 'allModsFromFile' ] == true || ( is_array ( $this -> _aModFileEditConf [ 'modsFromFile' ]) && in_array ( $this -> get ( 'idmod' ), $this -> _aModFileEditConf [ 'modsFromFile' ])))) {
2016-10-06 15:57:01 +00:00
$this -> modifiedValues [ 'output' ] = true ;
$this -> modifiedValues [ 'input' ] = true ;
}
/* End dceModFileEdit (c)2009-2011 www.dceonline.de */
if ( $bJustStore ) {
// Just store changes, e.g. if specifying the mod package
parent :: store ();
} else {
cInclude ( " includes " , " functions.con.php " );
parent :: store ();
conGenerateCodeForAllArtsUsingMod ( $this -> get ( " idmod " ));
2023-07-19 16:33:52 +00:00
if ( $this -> _shouldStoreToFile () && $this -> _makeFileDirectoryStructure ()) {
$sRootPath = $cfg [ 'path' ][ 'contenido' ] . $cfg [ 'path' ][ 'modules' ] . $this -> get ( " idclient " ) . " / " ;
file_put_contents ( $sRootPath . $this -> get ( " idmod " ) . " .xml " , $this -> export ( $this -> get ( " idmod " ) . " .xml " , true ));
2016-10-06 15:57:01 +00:00
}
}
}
public function getModFileEditConf () {
return $this -> _aModFileEditConf ;
}
2023-07-19 16:33:52 +00:00
protected function _recursiveRemoveDirectory ( $directory ) : bool {
2016-10-06 15:57:01 +00:00
foreach ( glob ( " { $directory } /* " ) as $file ) {
if ( is_dir ( $file )) {
$this -> _recursiveRemoveDirectory ( $file );
} else {
unlink ( $file );
}
}
return rmdir ( $directory );
}
protected function _makeFileDirectoryStructure () {
global $cfg ;
$sRootPath = $cfg [ 'path' ][ 'contenido' ] . $cfg [ 'path' ][ 'modules' ];
if ( ! is_dir ( $sRootPath )) {
@ mkdir ( $sRootPath );
}
$sRootPath = $cfg [ 'path' ][ 'contenido' ] . $cfg [ 'path' ][ 'modules' ] . $this -> get ( " idclient " ) . " / " ;
if ( ! is_dir ( $sRootPath )) {
@ mkdir ( $sRootPath );
}
if ( is_dir ( $sRootPath )) {
return true ;
} else {
return false ;
}
}
protected function _shouldStoreToFile () {
if ( getSystemProperty ( " modules " , " storeasfiles " ) == " true " ) {
return true ;
} else {
return false ;
}
}
2023-05-05 07:17:38 +00:00
/**
* @ return mixed
*/
public function getError ()
{
return $this -> _error ;
}
2016-10-06 15:57:01 +00:00
protected function _shouldLoadFromFiles () {
if ( getSystemProperty ( " modules " , " loadfromfiles " ) == " true " ) {
return true ;
} else {
return false ;
}
}
/**
* Parse import xml file , stores data in global variable ( -> event handler functions )
*
* @ param string $sFile Filename including path of import xml file
* @ param string $sType Import type , " module " or " package "
* @ return bool Returns true , if file has been parsed
*/
private function _parseImportFile ( $sFile , $sType = " module " , $sEncoding = " ISO-8859-1 " ) {
global $_mImport ;
2023-07-19 16:33:52 +00:00
$clXmlParser = new clXmlParser ( $sEncoding );
2016-10-06 15:57:01 +00:00
if ( $sType == " module " ) {
2023-07-19 16:33:52 +00:00
$clXmlParser -> setEventHandlers ([ " /module/name " => " cHandler_ModuleData " , " /module/description " => " cHandler_ModuleData " , " /module/type " => " cHandler_ModuleData " , " /module/input " => " cHandler_ModuleData " , " /module/output " => " cHandler_ModuleData " ]);
2016-10-06 15:57:01 +00:00
} else {
2023-07-19 16:33:52 +00:00
$aHandler = [
" /modulepackage/guid " => " cHandler_ModuleData " ,
2016-10-06 15:57:01 +00:00
#"/modulepackage/repository_guid" => "cHandler_ModuleData",
" /modulepackage/module/name " => " cHandler_ModuleData " ,
" /modulepackage/module/description " => " cHandler_ModuleData " ,
" /modulepackage/module/type " => " cHandler_ModuleData " ,
" /modulepackage/module/output " => " cHandler_ModuleData " ,
2023-07-19 16:33:52 +00:00
" /modulepackage/module/input " => " cHandler_ModuleData " ,
];
2016-10-06 15:57:01 +00:00
// Add file handler (e.g. js, css, templates)
2023-07-19 16:33:52 +00:00
foreach ( array_keys ( $this -> _packageStructure ) As $sFileType ) {
2016-10-06 15:57:01 +00:00
// Note, that $aHandler["/modulepackage/" . $sFileType] and using
// a handler which uses the node name (here: FileType) doesn't work,
// as the event handler for the filetype node will be fired
// after the node has been successfully parsed, not before.
// So, we have a little redundancy here, but maybe we need
// this in the future.
$aHandler [ " /modulepackage/ " . $sFileType . " /area " ] = " cHandler_ItemArea " ;
$aHandler [ " /modulepackage/ " . $sFileType . " /name " ] = " cHandler_ItemName " ;
$aHandler [ " /modulepackage/ " . $sFileType . " /content " ] = " cHandler_ItemData " ;
}
// Layouts
$aHandler [ " /modulepackage/layouts/area " ] = " cHandler_ItemArea " ;
$aHandler [ " /modulepackage/layouts/name " ] = " cHandler_ItemName " ;
$aHandler [ " /modulepackage/layouts/description " ] = " cHandler_ItemData " ;
$aHandler [ " /modulepackage/layouts/content " ] = " cHandler_ItemData " ;
// Translations
$aHandler [ " /modulepackage/translations/language " ] = " cHandler_ItemArea " ;
$aHandler [ " /modulepackage/translations/string/original " ] = " cHandler_ItemName " ;
$aHandler [ " /modulepackage/translations/string/translation " ] = " cHandler_Translation " ;
2023-07-19 16:33:52 +00:00
$clXmlParser -> setEventHandlers ( $aHandler );
2016-10-06 15:57:01 +00:00
}
2023-07-19 16:33:52 +00:00
if ( $clXmlParser -> parseFile ( $sFile )) {
2016-10-06 15:57:01 +00:00
return true ;
} else {
2023-07-19 16:33:52 +00:00
$this -> _error = $clXmlParser -> error ;
2016-10-06 15:57:01 +00:00
return false ;
}
}
/**
* Imports the a module from a XML file
* Uses xmlparser and callbacks
*
* @ param string $file Filename of data file ( full path )
*/
public function import ( $sFile ) {
global $_mImport ;
if ( $this -> _parseImportFile ( $sFile , " module " )) {
$bStore = false ;
foreach ( $_mImport [ " module " ] as $key => $value ) {
if ( $this -> get ( $key ) != $value ) {
$this -> set ( $key , addslashes ( $value ));
$bStore = true ;
}
}
if ( $bStore == true ) {
$this -> store ();
}
return true ;
} else {
return false ;
}
}
/**
* Exports the specified module strings to a file
*
* @ param $filename string Filename to return
* @ param $return boolean if false , the result is immediately sent to the browser
*/
public function export ( $filename , $return = false ) {
2023-07-19 16:33:52 +00:00
$xmlTree = new XmlTree ( '1.0' , 'ISO-8859-1' );
$root = & $xmlTree -> addRoot ( 'module' );
2016-10-06 15:57:01 +00:00
$root -> appendChild ( " name " , clHtmlSpecialChars ( $this -> get ( " name " )));
$root -> appendChild ( " description " , clHtmlSpecialChars ( $this -> get ( " description " )));
$root -> appendChild ( " type " , clHtmlSpecialChars ( $this -> get ( " type " )));
$root -> appendChild ( " input " , clHtmlSpecialChars ( $this -> get ( " input " )));
$root -> appendChild ( " output " , clHtmlSpecialChars ( $this -> get ( " output " )));
if ( $return == false ) {
ob_end_clean ();
header ( " Content-Type: text/xml " );
2023-07-19 16:33:52 +00:00
header ( " Etag: " . md5 ( random_int ( 0 , mt_getrandmax ())));
2016-10-06 15:57:01 +00:00
header ( " Content-Disposition: attachment;filename= \" $filename\ " " );
2023-07-19 16:33:52 +00:00
$xmlTree -> dump ( false );
2016-10-06 15:57:01 +00:00
} else {
2023-07-19 16:33:52 +00:00
return stripslashes ( $xmlTree -> dump ( true ));
2016-10-06 15:57:01 +00:00
}
}
public function getPackageOverview ( $sFile ) {
global $_mImport ;
if ( $this -> _parseImportFile ( $sFile , " package " )) {
2023-07-19 16:33:52 +00:00
$aData = [];
2016-10-06 15:57:01 +00:00
$aData [ " guid " ] = $_mImport [ " module " ][ " guid " ];
$aData [ " repository_guid " ] = $_mImport [ " module " ][ " repository_guid " ];
$aData [ " name " ] = $_mImport [ " module " ][ " name " ];
// Files
2023-07-19 16:33:52 +00:00
foreach ( array_keys ( $this -> _packageStructure ) as $sFileType ) {
2016-10-06 15:57:01 +00:00
if ( is_array ( $_mImport [ " items " ][ $sFileType ])) {
$aData [ $sFileType ] = array_keys ( $_mImport [ " items " ][ $sFileType ]);
}
}
// Layouts
if ( is_array ( $_mImport [ " items " ][ " layouts " ])) {
$aData [ " layouts " ] = array_keys ( $_mImport [ " items " ][ " layouts " ]);
}
// Translation languages
if ( is_array ( $_mImport [ " translations " ])) {
$aData [ " translations " ] = array_keys ( $_mImport [ " translations " ]);
}
return $aData ;
} else {
return false ;
}
}
/**
* Imports a module package from a XML file Uses xmlparser and callbacks
*
* @ param string $sFile Filename of data file ( including path )
* @ param array $aOptions Optional . An array of arrays specifying , how the items
* of the xml file will be imported . If specified , has to
* contain an array of this structure :
*
* $aOptions [ " items " ][ < filetype > ][ < clHtmlSpecialChars ( filename ) > ] = " skip " , " append " or " overwrite " ;
* $aOptions [ " translations " ][ < PackageLanguage > ] = < AssignedIDLang > ;
*
* If a file is not mentioned in the $aOptions [ " items " ][ < filetype > ]
* array , it is new and will be imported .
*
* If a < PackageLang > is not found in $aOptions [ " translations " ],
* then the translations for this language will be ignored
*
* @ return bool Returns true , if import has been successfully finished
*/
2023-07-19 16:33:52 +00:00
public function importPackage ( $sFile , $aOptions = []) {
$bStore = null ;
2016-10-06 15:57:01 +00:00
global $_mImport , $client ;
cInclude ( " includes " , " functions.file.php " );
cInclude ( " includes " , " functions.lay.php " ); // You won't believe the code in there (or what is missing in class.layout.php...)
// Ensure correct options structure
2023-07-19 16:33:52 +00:00
foreach ( array_keys ( $this -> _packageStructure ) as $sFileType ) {
2016-10-06 15:57:01 +00:00
if ( ! is_array ( $aOptions [ " items " ][ $sFileType ])) {
2023-07-19 16:33:52 +00:00
$aOptions [ " items " ][ $sFileType ] = [];
2016-10-06 15:57:01 +00:00
}
}
// Layouts
if ( ! is_array ( $aOptions [ " items " ][ " layouts " ])) {
2023-07-19 16:33:52 +00:00
$aOptions [ " items " ][ " layouts " ] = [];
2016-10-06 15:57:01 +00:00
}
// Translations
if ( ! is_array ( $aOptions [ " translations " ])) {
2023-07-19 16:33:52 +00:00
$aOptions [ " translations " ] = [];
2016-10-06 15:57:01 +00:00
}
// Parse file
if ( $this -> _parseImportFile ( $sFile , " package " )) {
// Import data
// Module
foreach ( $_mImport [ " module " ] as $sKey => $sData ) {
if ( $this -> get ( $sKey ) != $sData ) {
$this -> set ( $sKey , addslashes ( $sData ));
$bStore = true ;
}
}
if ( $bStore == true ) {
$this -> store ();
}
// Files
foreach ( $this -> _packageStructure as $sFileType => $sFilePath ) {
if ( is_array ( $_mImport [ " items " ][ $sFileType ])) {
foreach ( $_mImport [ " items " ][ $sFileType ] as $sFileName => $aContent ) {
2021-05-21 17:32:51 +00:00
if ( ! array_key_exists ( clHtmlSpecialChars ( $sFileName ), $aOptions [ " items " ][ $sFileType ]) || $aOptions [ " items " ][ $sFileType ][ clHtmlSpecialChars ( $sFileName )] == " overwrite " ) {
2016-10-06 15:57:01 +00:00
if ( ! file_exists ( $sFilePath . $sFileName )) {
createFile ( $sFileName , $sFilePath );
}
fileEdit ( $sFileName , $aContent [ " content " ], $sFilePath );
2023-07-19 16:33:52 +00:00
} elseif ( $aOptions [ " items " ][ $sFileType ][ clHtmlSpecialChars ( $sFileName )] == " append " ) {
2016-10-06 15:57:01 +00:00
$sOriginalContent = getFileContent ( $sFileName , $sFilePath );
fileEdit ( $sFileName , $sOriginalContent . $aContent [ " content " ], $sFilePath );
}
}
}
}
// Layouts
if ( is_array ( $_mImport [ " items " ][ " layouts " ])) {
foreach ( $_mImport [ " items " ][ " layouts " ] as $sLayout => $aContent ) {
2021-05-21 17:32:51 +00:00
if ( ! array_key_exists ( clHtmlSpecialChars ( $sLayout ), $aOptions [ " items " ][ " layouts " ]) || $aOptions [ " items " ][ " layouts " ][ clHtmlSpecialChars ( $sLayout )] == " overwrite " ) {
2016-10-06 15:57:01 +00:00
$oLayouts = new cApiLayoutCollection ;
$oLayouts -> setWhere ( " idclient " , $client );
$oLayouts -> setWhere ( " name " , $sLayout );
$oLayouts -> query ();
if ( ! $oLayout = $oLayouts -> next ()) {
layEditLayout ( false , addslashes ( $sLayout ), addslashes ( $aContent [ " description " ]), addslashes ( $aContent [ " content " ]));
} else {
layEditLayout ( $oLayout -> get ( $oLayout -> primaryKey ), addslashes ( $sLayout ), addslashes ( $aContent [ " description " ]), addslashes ( $aContent [ " content " ]));
}
} elseif ( $aOptions [ " items " ][ " layouts " ][ clHtmlSpecialChars ( $sLayout )] == " append " ) {
$oLayouts = new cApiLayoutCollection ;
$oLayouts -> setWhere ( " idclient " , $client );
$oLayouts -> setWhere ( " name " , $sLayout );
$oLayouts -> query ();
if ( ! $oLayout = $oLayouts -> next ()) {
layEditLayout ( false , addslashes ( $sLayout ), addslashes ( $aContent [ " description " ]), addslashes ( $aContent [ " content " ]));
} else {
layEditLayout ( $oLayout -> get ( $oLayout -> primaryKey ), addslashes ( $sLayout ), addslashes ( $oLayout -> get ( " description " ) . $aContent [ " description " ]), addslashes ( $oLayout -> get ( " code " ) . $aContent [ " content " ]));
}
}
}
}
// Translations
if ( is_array ( $_mImport [ " translations " ])) {
2023-07-19 16:33:52 +00:00
$cApiModuleTranslationCollection = new cApiModuleTranslationCollection ();
2016-10-06 15:57:01 +00:00
$iID = $this -> get ( $this -> primaryKey );
2023-07-19 16:33:52 +00:00
foreach ( array_keys ( $_mImport [ " translations " ]) as $sPackageLang ) {
2016-10-06 15:57:01 +00:00
if ( array_key_exists ( $sPackageLang , $aOptions [ " translations " ])) {
foreach ( $_mImport [ " translations " ][ $sPackageLang ] as $sOriginal => $sTranslation ) {
2023-07-19 16:33:52 +00:00
$cApiModuleTranslationCollection -> create ( $iID , $aOptions [ " translations " ][ $sPackageLang ], $sOriginal , $sTranslation );
2016-10-06 15:57:01 +00:00
}
}
}
}
return true ;
} else {
return false ;
}
}
/**
* Exports the specified module and attached files to a file
*
* @ param string $sPackageFileName Filename to return
* @ param bool $bReturn if false , the result is immediately sent to the browser
*/
public function exportPackage ( $sPackageFileName , $bReturn = false ) {
global $cfgClient , $client ;
cInclude ( " includes " , " functions.file.php " );
2023-07-19 16:33:52 +00:00
$xmlTree = new XmlTree ( '1.0' , 'ISO-8859-1' );
$oRoot = & $xmlTree -> addRoot ( 'modulepackage' );
2016-10-06 15:57:01 +00:00
$oRoot -> appendChild ( " package_guid " , $this -> get ( " package_guid " ));
$oRoot -> appendChild ( " package_data " , $this -> get ( " package_data " )); // This is serialized and more or less informal data
$aData = unserialize ( $this -> get ( " package_data " ));
if ( ! is_array ( $aData )) {
2023-07-19 16:33:52 +00:00
$aData = [];
2016-10-06 15:57:01 +00:00
$aData [ " repository_guid " ] = " " ;
2023-07-19 16:33:52 +00:00
$aData [ " jsfiles " ] = [];
$aData [ " tplfiles " ] = [];
$aData [ " cssfiles " ] = [];
$aData [ " layouts " ] = [];
$aData [ " translations " ] = [];
2016-10-06 15:57:01 +00:00
}
// Export basic module
$oNodeModule = & $oRoot -> appendChild ( " module " );
$oNodeModule -> appendChild ( " name " , clHtmlSpecialChars ( $this -> get ( " name " )));
$oNodeModule -> appendChild ( " description " , clHtmlSpecialChars ( $this -> get ( " description " )));
$oNodeModule -> appendChild ( " type " , clHtmlSpecialChars ( $this -> get ( " type " )));
$oNodeModule -> appendChild ( " input " , clHtmlSpecialChars ( $this -> get ( " input " )));
$oNodeModule -> appendChild ( " output " , clHtmlSpecialChars ( $this -> get ( " output " )));
// Export files (e.g. js, css, templates)
foreach ( $this -> _packageStructure As $sFileType => $sFilePath ) {
$oNodeFiles = & $oRoot -> appendChild ( $sFileType );
2023-07-19 16:33:52 +00:00
foreach ( $aData [ $sFileType ] as $sFileName ) {
if ( is_readable ( $sFilePath . $sFileName )) {
$sContent = getFileContent ( $sFileName , $sFilePath );
$oNodeFiles -> appendChild ( " area " , clHtmlSpecialChars ( $sFileType ));
$oNodeFiles -> appendChild ( " name " , clHtmlSpecialChars ( $sFileName ));
$oNodeFiles -> appendChild ( " content " , clHtmlSpecialChars ( $sContent ));
2016-10-06 15:57:01 +00:00
}
}
}
unset ( $sContent );
// Export layouts
$oNodeLayouts = & $oRoot -> appendChild ( " layouts " );
2023-07-19 16:33:52 +00:00
$cApiLayoutCollection = new cApiLayoutCollection ;
$cApiLayoutCollection -> setWhere ( " idclient " , $client );
$cApiLayoutCollection -> query ();
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
while ( $oLayout = $cApiLayoutCollection -> next ()) {
2016-10-06 15:57:01 +00:00
if ( in_array ( $oLayout -> get ( $oLayout -> primaryKey ), $aData [ " layouts " ])) {
$oNodeLayouts -> appendChild ( " area " , " layouts " );
$oNodeLayouts -> appendChild ( " name " , clHtmlSpecialChars ( $oLayout -> get ( " name " )));
$oNodeLayouts -> appendChild ( " description " , clHtmlSpecialChars ( $oLayout -> get ( " description " )));
$oNodeLayouts -> appendChild ( " content " , clHtmlSpecialChars ( $oLayout -> get ( " code " )));
}
}
unset ( $oLayout );
2023-07-19 16:33:52 +00:00
unset ( $cApiLayoutCollection );
2016-10-06 15:57:01 +00:00
// Export translations
2023-07-19 16:33:52 +00:00
$cApiLanguageCollection = new cApiLanguageCollection ();
$cApiLanguageCollection -> setOrder ( " idlang " );
$cApiLanguageCollection -> query ();
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
if ( $cApiLanguageCollection -> count () > 0 ) {
2016-10-06 15:57:01 +00:00
$iIDMod = $this -> get ( $this -> primaryKey );
2023-07-19 16:33:52 +00:00
while ( $oLang = $cApiLanguageCollection -> next ()) {
2016-10-06 15:57:01 +00:00
$iID = $oLang -> get ( $oLang -> primaryKey );
if ( in_array ( $iID , $aData [ " translations " ])) {
$oNodeTrans = & $oRoot -> appendChild ( " translations " );
// This is nice, but it doesn't help so much,
// as this data is available too late on import ...
2023-07-19 16:33:52 +00:00
$oNodeTrans -> setNodeAttribs ([ " origin-language-id " => $iID , " origin-language-name " => clHtmlSpecialChars ( $oLang -> get ( " name " ))]);
2016-10-06 15:57:01 +00:00
// ... so we store the important information with the data
$oNodeTrans -> appendChild ( " language " , clHtmlSpecialChars ( $oLang -> get ( " name " )));
$oTranslations = new cApiModuleTranslationCollection ;
$oTranslations -> setWhere ( " idmod " , $iIDMod );
$oTranslations -> setWhere ( " idlang " , $iID );
$oTranslations -> query ();
while ( $oTranslation = $oTranslations -> next ()) {
$oNodeString = & $oNodeTrans -> appendChild ( " string " );
$oNodeString -> appendChild ( " original " , clHtmlSpecialChars ( $oTranslation -> get ( " original " )));
$oNodeString -> appendChild ( " translation " , clHtmlSpecialChars ( $oTranslation -> get ( " translation " )));
}
}
}
}
2023-07-19 16:33:52 +00:00
unset ( $cApiLanguageCollection );
2016-10-06 15:57:01 +00:00
unset ( $oLang );
if ( $bReturn == false ) {
ob_end_clean ();
header ( " Content-Type: text/xml " );
2023-07-19 16:33:52 +00:00
header ( " Etag: " . md5 ( random_int ( 0 , mt_getrandmax ())));
2016-10-06 15:57:01 +00:00
header ( " Content-Disposition: attachment;filename= \" $sPackageFileName\ " " );
2023-07-19 16:33:52 +00:00
$xmlTree -> dump ( false );
2016-10-06 15:57:01 +00:00
} else {
2023-07-19 16:33:52 +00:00
return stripslashes ( $xmlTree -> dump ( true ));
2016-10-06 15:57:01 +00:00
}
}
/* dceModFileEdit (c)2009-2012 www.dceonline.de */
/**
* Overridden parent method for hooking dceModFileEdit
*
* @ return void
*/
protected function _onLoad () {
$this -> _sModAlias = strtolower ( uplCreateFriendlyName ( $this -> get ( 'name' )));
$this -> _sModAliasOld = uplCreateFriendlyName ( $this -> get ( 'name' ));
$this -> _setOutputFromPhpFile ();
$this -> _setInputFromPhpFile ();
}
/**
* Use a PHP - file , if present , for module output
*
* @ return boolean
*/
private function _setOutputFromPhpFile () {
// dceModEdit not enabled or not present
if ( $this -> _aModFileEditConf [ 'use' ] !== true ) {
return false ;
}
2021-05-21 17:32:51 +00:00
return $this -> _setFieldFromFile ( 'output' , $this -> _sModAlias . " _output.php " );
2016-10-06 15:57:01 +00:00
}
/**
* Use a PHP - file , if present , for module input
*
* @ return boolean
*/
private function _setInputFromPhpFile () {
cInclude ( 'includes' , 'functions.upl.php' );
// dceModEdit not enabled or not present
if ( $this -> _aModFileEditConf [ 'use' ] !== true ) {
return false ;
}
2021-05-21 17:32:51 +00:00
return $this -> _setFieldFromFile ( 'input' , $this -> _sModAlias . " _input.php " );
2016-10-06 15:57:01 +00:00
}
private function _displayNoteFromFile ( $bIsOldPath = FALSE ) {
2023-07-19 16:33:52 +00:00
if ( property_exists ( $this , '_bNoted' ) && $this -> _bNoted !== null && $this -> _bNoted === true ) {
2016-10-06 15:57:01 +00:00
return ;
}
global $frame , $area ;
if ( $frame == 4 && $area == 'mod_edit' ) {
$sAddMess = '' ;
if ( $bIsOldPath ) {
$sAddMess .= " <br> " . i18n ( " Using old CamelCase for name of modulefolder. You may lowercase the name for modulefolder " );
}
2023-07-19 16:33:52 +00:00
$contenidoNotification = new Contenido_Notification ();
$contenidoNotification -> displayNotification ( 'warning' , i18n ( " Module uses Output- and/or InputFromFile. Editing and Saving may not be possible in backend. " ) . $sAddMess );
2016-10-06 15:57:01 +00:00
$this -> _bNoted = true ;
}
}
/**
* read file and set an object field
2023-07-19 16:33:52 +00:00
*
2016-10-06 15:57:01 +00:00
* @ param string $sFile
* @ param string $sField
*/
2023-07-19 16:33:52 +00:00
private function _setFieldFromFile ( $sField , $sFile ) : bool {
2016-10-06 15:57:01 +00:00
$bIsOldPath = TRUE ;
$sFile = strtolower ( $sFile );
2023-07-19 16:33:52 +00:00
if ( ! str_contains ( $sFile , $this -> _aModFileEditConf [ 'modPath' ])) {
2016-10-06 15:57:01 +00:00
$sFile = $this -> _aModFileEditConf [ 'modPath' ] . $sFile ;
}
// check for new struct since CL 2.0
if ( is_dir ( $this -> _aModFileEditConf [ 'modPath' ] . $this -> _sModAlias ) && is_writable ( $this -> _aModFileEditConf [ 'modPath' ] . $this -> _sModAlias ) && file_exists ( $this -> _aModFileEditConf [ 'modPath' ] .
$this -> _sModAlias . " /php/ " . $this -> _sModAlias .
" _ " . $sField . " .php " )) {
$sFile = $this -> _aModFileEditConf [ 'modPath' ] .
$this -> _sModAlias . " /php/ " . $this -> _sModAlias .
" _ " . $sField . " .php " ;
$bIsOldPath = FALSE ;
}
if ( is_file ( $sFile ) && is_readable ( $sFile )) {
$iFileSize = ( int ) filesize ( $sFile );
if ( $iFileSize > 0 && $fh = fopen ( $sFile , 'r' )) {
$this -> set ( $sField , fread ( $fh , $iFileSize ), false );
fclose ( $fh );
switch ( $sField ) {
case " output " :
$this -> _bOutputFromFile = true ;
break ;
case " input " :
$this -> _bInputFromFile = true ;
default :
break ;
}
$this -> _displayNoteFromFile ( $bIsOldPath );
return true ;
}
} else {
switch ( $sField ) {
case " output " :
$this -> _bOutputFromFile = false ;
break ;
case " input " :
$this -> _bInputFromFile = false ;
default :
break ;
}
}
return false ;
}
public function isLoadedFromFile ( $sWhat = " all " ) {
2023-07-19 16:33:52 +00:00
return match ( $sWhat ) {
" all " => $this -> _bOutputFromFile || $this -> _bInputFromFile ,
" output " => $this -> _bOutputFromFile ,
" input " => $this -> _bInputFromFile ,
default => false ,
};
2016-10-06 15:57:01 +00:00
}
/* End dceModFileEdit (c)2009-2012 www.dceonline.de */
private function _createModuleStruct () {
$bDone = FALSE ;
if ( $this -> _aModFileEditConf [ 'use' ] == TRUE && is_writable ( $this -> _sModPath )) {
$bDone = TRUE ;
foreach ( $this -> _aModDefaultStruct as $sFolder ) {
$bDone = $bDone && mkdir ( $this -> _sModPath . $sFolder );
}
}
$this -> _createModulePhpFiles ();
umask ( $this -> _oldumask );
return $bDone ;
}
private function _createModulePhpFiles () {
$sPath = $this -> _sModPath . " php/ " ;
2023-07-19 16:33:52 +00:00
$aFileTpl = [ 'output' => " <?php \n \n ?> " , 'input' => " ?><?php \n \n ?><?php " ];
2016-10-06 15:57:01 +00:00
if ( is_writable ( $sPath )) {
$sOutputFile = $sPath . $this -> _sModAlias . " _output.php " ;
$sInputFile = $sPath . $this -> _sModAlias . " _input.php " ;
if ( ! file_exists ( $sOutputFile )) {
$rFileHandler = fopen ( $sOutputFile , " w " );
if ( is_resource ( $rFileHandler )) {
if ( $this -> getField ( 'output' ) == " " ) {
fwrite ( $rFileHandler , $aFileTpl [ 'output' ]);
} else {
fwrite ( $rFileHandler , $this -> getField ( 'output' ));
}
fclose ( $rFileHandler );
}
}
if ( ! file_exists ( $sInputFile )) {
$rFileHandler = fopen ( $sInputFile , " w " );
if ( is_resource ( $rFileHandler )) {
if ( $this -> getField ( 'input' ) == " " ) {
fwrite ( $rFileHandler , $aFileTpl [ 'input' ]);
} else {
fwrite ( $rFileHandler , $this -> getField ( 'input' ));
}
fclose ( $rFileHandler );
}
}
}
}
}
// end class
class cApiModuleTranslationCollection extends ItemCollection {
protected $_error ;
2022-10-26 17:38:53 +00:00
protected $f_obj ;
2016-10-06 15:57:01 +00:00
/**
* Constructor Function
* @ param none
*/
public function __construct () {
global $cfg ;
parent :: __construct ( $cfg [ " tab " ][ " mod_translations " ], " idmodtranslation " );
$this -> _setItemClass ( " cApiModuleTranslation " );
}
/**
* Creates a new module translation item
*/
public function create ( $idmod , $idlang , $original , $translation = false ) {
// Check if the original already exists. If it does,
// update the translation if passed
2023-07-19 16:33:52 +00:00
$cApiModuleTranslation = new cApiModuleTranslation ();
$sorg = $cApiModuleTranslation -> _inFilter ( $original );
2016-10-06 15:57:01 +00:00
$this -> select ( " idmod = ' $idmod ' AND idlang = ' $idlang ' AND original = ' $sorg ' " );
if ( $item = $this -> next ()) {
if ( $translation !== false ) {
$item -> set ( " translation " , $translation );
$item -> store ();
}
return $item ;
} else {
2016-10-08 13:39:50 +00:00
$item = parent :: createNewItem ();
2016-10-06 15:57:01 +00:00
$item -> set ( " idmod " , $idmod );
$item -> set ( " idlang " , $idlang );
$item -> set ( " original " , $original );
$item -> set ( " translation " , $translation );
$item -> store ();
return $item ;
}
}
/**
* Fetches a translation
*
* @ param $module int Module ID
* @ param $lang int Language ID
* @ param $string string String to lookup
*/
public function fetchTranslation ( $module , $lang , $string ) {
// If the f_obj does not exist, create one
if ( ! is_object ( $this -> f_obj )) {
$this -> f_obj = new cApiModuleTranslation ();
}
// Create original string
$sorg = $this -> _itemClassInstance -> _inFilter ( $string );
// Look up
$this -> select ( " idmod = ' $module ' AND idlang=' $lang ' AND original = ' $sorg ' " );
if ( $t = $this -> next ()) {
$translation = $t -> get ( " translation " );
if ( $translation != " " ) {
return $translation ;
} else {
return $string ;
}
} else {
return $string ;
}
}
public function import ( $idmod , $idlang , $file ) {
global $_mImport ;
2023-07-19 16:33:52 +00:00
$clXmlParser = new clXmlParser ( " ISO-8859-1 " );
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
$clXmlParser -> setEventHandlers ([ " /module/translation/string/original " => " cHandler_ItemName " , " /module/translation/string/translation " => " cHandler_Translation " ]);
2016-10-06 15:57:01 +00:00
$_mImport [ " current_item_area " ] = " current " ; // Pre-specification, as this won't be set from the XML file (here)
2023-07-19 16:33:52 +00:00
if ( $clXmlParser -> parseFile ( $file )) {
2016-10-06 15:57:01 +00:00
foreach ( $_mImport [ " translations " ][ " current " ] as $sOriginal => $sTranslation ) {
$this -> create ( $idmod , $idlang , $sOriginal , $sTranslation );
}
return true ;
} else {
2023-07-19 16:33:52 +00:00
$this -> _error = $clXmlParser -> error ;
2016-10-06 15:57:01 +00:00
return false ;
}
}
/**
* Exports the specified module strings to a file
*
* @ param $idmod int Module ID
* @ param $idlang int Language ID
* @ param $filename string Filename to return
* @ param $return boolean if false , the result is immediately sent to the browser
*/
public function export ( $idmod , $idlang , $filename , $return = false ) {
2023-07-19 16:33:52 +00:00
$cApiLanguage = new cApiLanguage ( $idlang );
2016-10-06 15:57:01 +00:00
#$langstring = $langobj->get("name") . ' ('.$idlang.')';
2023-07-19 16:33:52 +00:00
$cApiModuleTranslationCollection = new cApiModuleTranslationCollection ;
$cApiModuleTranslationCollection -> select ( " idmod = ' $idmod ' AND idlang=' $idlang ' " );
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
$xmlTree = new XmlTree ( '1.0' , 'ISO-8859-1' );
$root = & $xmlTree -> addRoot ( 'module' );
2016-10-06 15:57:01 +00:00
$translation = & $root -> appendChild ( 'translation' );
2023-07-19 16:33:52 +00:00
$translation -> setNodeAttribs ([ " origin-language-id " => $idlang , " origin-language-name " => $cApiLanguage -> get ( " name " )]);
2016-10-06 15:57:01 +00:00
2023-07-19 16:33:52 +00:00
while ( $otranslation = $cApiModuleTranslationCollection -> next ()) {
2016-10-06 15:57:01 +00:00
$string = & $translation -> appendChild ( " string " );
$string -> appendChild ( " original " , clHtmlSpecialChars ( $otranslation -> get ( " original " )));
$string -> appendChild ( " translation " , clHtmlSpecialChars ( $otranslation -> get ( " translation " )));
}
if ( $return == false ) {
header ( " Content-Type: text/xml " );
2023-07-19 16:33:52 +00:00
header ( " Etag: " . md5 ( random_int ( 0 , mt_getrandmax ())));
2016-10-06 15:57:01 +00:00
header ( " Content-Disposition: attachment;filename= \" $filename\ " " );
2023-07-19 16:33:52 +00:00
$xmlTree -> dump ( false );
2016-10-06 15:57:01 +00:00
} else {
2023-07-19 16:33:52 +00:00
return $xmlTree -> dump ( true );
2016-10-06 15:57:01 +00:00
}
}
}
/**
* Module access class
*/
class cApiModuleTranslation extends Item {
/**
* Constructor Function
* @ param $loaditem Item to load
*/
public function __construct ( $loaditem = false ) {
global $cfg ;
parent :: __construct ( $cfg [ " tab " ][ " mod_translations " ], " idmodtranslation " );
if ( $loaditem !== false ) {
$this -> loadByPrimaryKey ( $loaditem );
}
}
public function useInFilter ( $sValue ) {
return $this -> _inFilter ( $sValue );
}
}
function cHandler_ModuleData ( $sName , $aAttribs , $sContent ) {
global $_mImport ;
$_mImport [ " module " ][ $sName ] = $sContent ;
}
// The following three functions references all file data (e.g. for css,
// js and template files) and layout data
// Note, that first the type is specified (from the "area" information
// in the xml file).
// Second, filename is specified based on "name" node content.
// Third, file content is stored using type, name and node content.
// You will have to specify individual handler functions, if one of
// the file areas may store additional data (e.g. a description)
function cHandler_ItemArea ( $sName , $aAttribs , $sContent ) {
global $_mImport ;
$_mImport [ " current_item_area " ] = $sContent ;
}
function cHandler_ItemName ( $sName , $aAttribs , $sContent ) {
global $_mImport ;
$_mImport [ " current_item_name " ] = $sContent ;
}
function cHandler_ItemData ( $sName , $aAttribs , $sContent ) {
global $_mImport ;
$_mImport [ " items " ][ $_mImport [ " current_item_area " ]][ $_mImport [ " current_item_name " ]][ $sName ] = $sContent ;
}
// Separate language area, as someone may specify "cssfiles" or something
// as language name, funny guy...
function cHandler_Translation ( $sName , $aAttribs , $sContent ) {
global $_mImport ;
$_mImport [ " translations " ][ $_mImport [ " current_item_area " ]][ $_mImport [ " current_item_name " ]] = $sContent ;
}