Improvement options to processmaker
- Add plugins-translation-update - Add plugins-translation-create
This commit is contained in:
85
workflow/engine/bin/tasks/cliPlugins.php
Normal file
85
workflow/engine/bin/tasks/cliPlugins.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* cliPlugins.php
|
||||
*
|
||||
* ProcessMaker Open Source Edition
|
||||
* Copyright (C) 2011 Colosa Inc.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For more information, contact Colosa Inc, 2566 Le Jeune Rd.,
|
||||
* Coral Gables, FL, 33134, USA, or email info@colosa.com.
|
||||
*
|
||||
* @package workflow-engine-bin-tasks
|
||||
*/
|
||||
|
||||
G::LoadClass("system");
|
||||
G::LoadClass("wsTools");
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
CLI::taskName('plugins-translation-update');
|
||||
CLI::taskDescription(<<<EOT
|
||||
Upgrade workspaces.
|
||||
|
||||
This command should be run after ProcessMaker files are upgraded so that all
|
||||
workspaces are upgraded to the current version.
|
||||
EOT
|
||||
);
|
||||
CLI::taskArg('plugin', false);
|
||||
CLI::taskArg('lang', false);
|
||||
//CLI::taskOpt("buildACV", "If the option is enabled, performs the Build Cache View.", "ACV", "buildACV");
|
||||
CLI::taskRun(run_update);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
CLI::taskName('plugins-translation-create');
|
||||
CLI::taskDescription(<<<EOT
|
||||
Upgrade workspaces.
|
||||
|
||||
This command should be run after ProcessMaker files are upgraded so that all
|
||||
workspaces are upgraded to the current version.
|
||||
EOT
|
||||
);
|
||||
CLI::taskArg('plugin', true);
|
||||
CLI::taskArg('lang', true);
|
||||
//CLI::taskOpt("buildACV", "If the option is enabled, performs the Build Cache View.", "ACV", "buildACV");
|
||||
CLI::taskRun(run_create);
|
||||
|
||||
|
||||
/**
|
||||
* A version of rm_dir which does not exits on error.
|
||||
*
|
||||
* @param string $filename directory or file to remove
|
||||
* @param bool $filesOnly either to remove the containing directory as well or not
|
||||
*/
|
||||
|
||||
|
||||
function run_create($command, $args)
|
||||
{
|
||||
CLI::logging("Creating file .po ..\n");
|
||||
|
||||
$language = new Language();
|
||||
$language->createLanguagePlugin($command[0], $command[1]);
|
||||
CLI::logging("Creating successful\n");
|
||||
|
||||
}
|
||||
|
||||
function run_update($command, $args)
|
||||
{
|
||||
CLI::logging("Updating...\n");
|
||||
|
||||
$language = new Language();
|
||||
$language->updateLanguagePlugin($command[0], $command[1]);
|
||||
CLI::logging("Update successful\n");
|
||||
|
||||
}
|
||||
@@ -541,6 +541,267 @@ class Language extends BaseLanguage
|
||||
}
|
||||
G::streamFile( $sPOFile, true );
|
||||
}
|
||||
function updateLanguagePlugin ($plugin, $idLanguage)
|
||||
{
|
||||
if (!file_exists(PATH_PLUGINS . $plugin)) {
|
||||
throw new Exception( 'The plugin ' . $plugin . ' not exist' );
|
||||
die();
|
||||
}
|
||||
if (!file_exists(PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . $plugin . '.' . $idLanguage . '.po')) {
|
||||
throw new Exception( 'The not exist the file ' . $plugin . '.' . $idLanguage . '.po' );
|
||||
die();
|
||||
}
|
||||
$languageFile = PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . $plugin . '.' . $idLanguage . '.po' ;//PATH_LANGUAGECONT . $plugin . '.' . $idLanguage;
|
||||
try {
|
||||
G::LoadSystem( 'i18n_po' );
|
||||
$POFile = new i18n_PO( $languageFile );
|
||||
$POFile->readInit();
|
||||
$POHeaders = $POFile->getHeaders();
|
||||
|
||||
$oTranslation = new Translation();
|
||||
$countItems = 0;
|
||||
$countItemsSuccess = 0;
|
||||
$errorMsg = '';
|
||||
|
||||
while ($rowTranslation = $POFile->getTranslation()) {
|
||||
$countItems ++;
|
||||
if (! isset( $POFile->translatorComments[0] ) || ! isset( $POFile->translatorComments[1] ) || ! isset( $POFile->references[0] )) {
|
||||
throw new Exception( 'The .po file doesn\'t have valid directives for Processmaker!' );
|
||||
}
|
||||
|
||||
foreach ($POFile->translatorComments as $a => $aux) {
|
||||
$identifier = '';
|
||||
$context = '';
|
||||
$aux = trim( $aux );
|
||||
if ($aux == 'TRANSLATION') {
|
||||
$identifier = $aux;
|
||||
} else {
|
||||
$var = explode( '/', $aux );
|
||||
if ($var[0] == 'LABEL') {
|
||||
$context = $aux;
|
||||
}
|
||||
if ($var[0] == 'JAVASCRIPT') {
|
||||
$context = $aux;
|
||||
}
|
||||
}
|
||||
if ($identifier == '' && $context == '') {
|
||||
$context = $aux;
|
||||
}
|
||||
if (preg_match( '/^([\w-]+)\/([\w-]+\/*[\w-]*\.xml\?)/', $aux, $match )) {
|
||||
$identifier = $aux;
|
||||
} else {
|
||||
if (preg_match( '/^([\w-]+)\/([\w-]+\/*[\w-]*\.xml$)/', $aux, $match )) {
|
||||
$context = $aux;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$reference = $POFile->references[0];
|
||||
|
||||
if ($identifier != 'TRANSLATION') {
|
||||
$xmlForm = $context;
|
||||
//erik: expresion to prevent and hable correctly dropdown values like -1, -2 etc.
|
||||
preg_match( '/^([\w_]+)\s-\s([\w_]+)\s*-*\s*([\w\W]*)$/', $reference, $match );
|
||||
|
||||
if (! file_exists( PATH_PLUGINS . $plugin . PATH_SEP . $xmlForm )) {
|
||||
$errorMsg .= 'file doesn\'t exist: ' . PATH_PLUGINS . $plugin . $xmlForm . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count( $match ) < 4) {
|
||||
$near = isset( $rowTranslation['msgid'] ) ? $rowTranslation['msgid'] : (isset( $rowTranslation['msgstr'] ) ? $rowTranslation['msgstr'] : '');
|
||||
$errorMsg .= "Invalid Translation reference: \"$reference\", near -> " . strip_tags($near) . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
G::LoadSystem( 'dynaformhandler' );
|
||||
$dynaform = new dynaFormHandler( PATH_PLUGINS . $plugin . PATH_SEP . $xmlForm );
|
||||
$fieldName = $match[2];
|
||||
|
||||
$codes = explode( '-', $reference );
|
||||
|
||||
if (sizeof( $codes ) == 2) {
|
||||
//is a normal node
|
||||
$dynaform->addChilds( $fieldName, Array ($idLanguage => stripcslashes( str_replace( chr( 10 ), '', $rowTranslation['msgstr'] ) )
|
||||
) );
|
||||
} elseif (sizeof( $codes ) > 2) {
|
||||
//is a node child for a language node
|
||||
$name = $match[3] == "''" ? '' : $match[3];
|
||||
$childNode = Array (
|
||||
Array ('name' => 'option','value' => $rowTranslation['msgstr'],'attributes' =>
|
||||
Array ('name' => $name)
|
||||
)
|
||||
);
|
||||
|
||||
$dynaform->addChilds( $fieldName, Array ($idLanguage => null
|
||||
), $childNode );
|
||||
}
|
||||
$countItemsSuccess ++;
|
||||
}
|
||||
}
|
||||
|
||||
$trn = new Translation();
|
||||
$trn->generateFileTranslationPlugin( $plugin, $idLanguage );
|
||||
$trn->addTranslationEnvironmentPlugins( $plugin, $idLanguage, $POHeaders, $countItemsSuccess );
|
||||
|
||||
//fill the results
|
||||
$results = new stdClass();
|
||||
$results->recordsCount = $countItems;
|
||||
$results->recordsCountSuccess = $countItemsSuccess;
|
||||
$results->lang = $languageID;
|
||||
$results->headers = $POHeaders;
|
||||
$results->errMsg = $errorMsg;
|
||||
|
||||
return $results;
|
||||
} catch (Exception $oError) {
|
||||
throw ($oError);
|
||||
}
|
||||
}
|
||||
|
||||
function createLanguagePlugin ($plugin, $idLanguage)
|
||||
{
|
||||
G::LoadSystem( 'i18n_po' );
|
||||
G::LoadClass( "system" );
|
||||
|
||||
//creating the .po file
|
||||
//$sPOFile = PATH_LANGUAGECONT . $plugin . '.' . $idLanguage . '.po';
|
||||
$sPOFile = PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . $plugin . '.' . $idLanguage . '.po';
|
||||
$poFile = new i18n_PO( $sPOFile );
|
||||
$poFile->buildInit();
|
||||
|
||||
$language = new Language();
|
||||
|
||||
$locale = $language;
|
||||
$_TARGET_LANG = $idLanguage;
|
||||
$_BASE_LANG = 'en';
|
||||
|
||||
//setting headers
|
||||
$poFile->addHeader( 'Project-Id-Version', $plugin );
|
||||
$poFile->addHeader( 'POT-Creation-Date', '' );
|
||||
$poFile->addHeader( 'PO-Revision-Date', date( 'Y-m-d H:i:s' ) );
|
||||
$poFile->addHeader( 'Last-Translator', '' );
|
||||
$poFile->addHeader( 'Language-Team', 'Colosa Developers Team <developers@colosa.com>' );
|
||||
$poFile->addHeader( 'MIME-Version', '1.0' );
|
||||
$poFile->addHeader( 'Content-Type', 'text/plain; charset=utf-8' );
|
||||
$poFile->addHeader( 'Content-Transfer_Encoding', '8bit' );
|
||||
$poFile->addHeader( 'X-Poedit-Language', ucwords( $idLanguage ) );
|
||||
$poFile->addHeader( 'X-Poedit-SourceCharset', 'utf-8' );
|
||||
$poFile->addHeader( 'Content-Transfer-Encoding', '8bit' );
|
||||
|
||||
$aLabels = array ();
|
||||
$aMsgids = array ('' => true
|
||||
);
|
||||
//global $translations;
|
||||
include PATH_PLUGINS . $plugin . PATH_SEP . 'translations'. PATH_SEP . 'translation.php';
|
||||
|
||||
foreach ($translations as $id => $translation) {
|
||||
$msgid = trim( $translation);
|
||||
$msgstr = trim( $translation );
|
||||
$poFile->addTranslatorComment( 'TRANSLATION' );
|
||||
$poFile->addTranslatorComment( 'LABEL/' . $id );
|
||||
$poFile->addReference( 'LABEL/'. $id );
|
||||
|
||||
$poFile->addTranslation( stripcslashes( $msgid ), stripcslashes( $msgstr ) );
|
||||
$aMsgids[$msgid] = true;
|
||||
}
|
||||
|
||||
//now find labels in xmlforms
|
||||
$aExceptionFields = array ('','javascript','hidden','phpvariable','private','toolbar','xmlmenu','toolbutton','cellmark','grid','CheckboxTable'
|
||||
);
|
||||
$aXMLForms = glob( PATH_PLUGINS . $plugin . PATH_SEP . '*.xml' );
|
||||
$aXMLForms2 = glob( PATH_PLUGINS . $plugin . PATH_SEP . '*/*.xml' );
|
||||
$aXMLForms = array_merge( $aXMLForms, $aXMLForms2 );
|
||||
$aXMLForms3 = glob( PATH_PLUGINS . $plugin . PATH_SEP . '*/*/*.xml' );
|
||||
$aXMLForms = array_merge( $aXMLForms, $aXMLForms3 );
|
||||
$aEnglishLabel = array ();
|
||||
$aOptions = array ();
|
||||
$nodesNames = Array ();
|
||||
|
||||
G::loadSystem( 'dynaformhandler' );
|
||||
|
||||
foreach ($aXMLForms as $xmlFormPath) {
|
||||
$xmlFormFile = str_replace( chr( 92 ), '/', $xmlFormPath );
|
||||
$xmlFormFile = str_replace( PATH_PLUGINS . $plugin . PATH_SEP , '', $xmlFormPath );
|
||||
$dynaForm = new dynaFormHandler( $xmlFormPath );
|
||||
$dynaNodes = $dynaForm->getFields();
|
||||
//get all fields of each xmlform
|
||||
foreach ($dynaNodes as $oNode) {
|
||||
$sNodeName = $oNode->nodeName;
|
||||
$arrayNode = $dynaForm->getArray( $oNode );
|
||||
//if has not native language translation
|
||||
if (! isset( $arrayNode[$_BASE_LANG] ) || ! isset( $arrayNode['type'] ) || (isset( $arrayNode['type'] ) && in_array( $arrayNode['type'], $aExceptionFields ))) {
|
||||
continue; //just continue with the next node
|
||||
}
|
||||
// Getting the Base Origin Text
|
||||
if (! is_array( $arrayNode[$_BASE_LANG] )) {
|
||||
$originNodeText = trim( $arrayNode[$_BASE_LANG] );
|
||||
} else {
|
||||
$langNode = $arrayNode[$_BASE_LANG][0];
|
||||
$originNodeText = $langNode['__nodeText__'];
|
||||
}
|
||||
// Getting the Base Target Text
|
||||
if (isset( $arrayNode[$_TARGET_LANG] )) {
|
||||
if (! is_array( $arrayNode[$_TARGET_LANG] )) {
|
||||
$targetNodeText = trim( $arrayNode[$_TARGET_LANG] );
|
||||
} else {
|
||||
$langNode = $arrayNode[$_TARGET_LANG][0];
|
||||
$targetNodeText = $langNode['__nodeText__'];
|
||||
}
|
||||
} else {
|
||||
$targetNodeText = $originNodeText;
|
||||
}
|
||||
$nodeName = $arrayNode['__nodeName__'];
|
||||
$nodeType = $arrayNode['type'];
|
||||
$msgid = $originNodeText;
|
||||
// if the nodeName already exists in the po file, we need to create other msgid
|
||||
if (isset( $aMsgids[$msgid] )) {
|
||||
$msgid = '[' . $xmlFormFile . '?' . $nodeName . '] ' . $originNodeText;
|
||||
}
|
||||
$poFile->addTranslatorComment( $xmlFormFile . '?' . $nodeName );
|
||||
$poFile->addTranslatorComment( $xmlFormFile );
|
||||
$poFile->addReference( $nodeType . ' - ' . $nodeName );
|
||||
$poFile->addTranslation( stripslashes( $msgid ), stripslashes( $targetNodeText ) );
|
||||
|
||||
$aMsgids[$msgid] = true;
|
||||
//if this node has options child nodes
|
||||
if (isset( $arrayNode[$_BASE_LANG] ) && isset( $arrayNode[$_BASE_LANG][0] ) && isset( $arrayNode[$_BASE_LANG][0]['option'] )) {
|
||||
$originOptionNode = $arrayNode[$_BASE_LANG][0]['option']; //get the options
|
||||
$targetOptionExists = false;
|
||||
if (isset( $arrayNode[$_TARGET_LANG] ) && isset( $arrayNode[$_TARGET_LANG][0] ) && isset( $arrayNode[$_TARGET_LANG][0]['option'] )) {
|
||||
$targetOptionNode = $arrayNode[$_TARGET_LANG][0]['option'];
|
||||
$targetOptionExists = true;
|
||||
}
|
||||
if (! is_array( $originOptionNode )) {
|
||||
if (is_string( $originOptionNode )) {
|
||||
$poFile->addTranslatorComment( $xmlFormFile . '?' . $nodeName . '-' . $originOptionNode );
|
||||
$poFile->addTranslatorComment( $xmlFormFile );
|
||||
$poFile->addReference( $nodeType . ' - ' . $nodeName . ' - ' . $originOptionNode );
|
||||
$poFile->addTranslation( stripslashes( $msgid ), stripslashes( $originOptionNode ) );
|
||||
}
|
||||
} else {
|
||||
foreach ($originOptionNode as $optionNode) {
|
||||
$optionName = $optionNode['name'];
|
||||
$originOptionValue = $optionNode['__nodeText__'];
|
||||
if ($targetOptionExists) {
|
||||
$targetOptionValue = getMatchDropdownOptionValue( $optionName, $targetOptionNode );
|
||||
if ($targetOptionValue === false) {
|
||||
$targetOptionValue = $originOptionValue;
|
||||
}
|
||||
} else {
|
||||
$targetOptionValue = $originOptionValue;
|
||||
}
|
||||
$msgid = '[' . $xmlFormFile . '?' . $nodeName . '-' . $optionName . ']';
|
||||
$poFile->addTranslatorComment( $xmlFormFile . '?' . $nodeName . '-' . $optionName );
|
||||
$poFile->addTranslatorComment( $xmlFormFile );
|
||||
$poFile->addReference( $nodeType . ' - ' . $nodeName . ' - ' . $optionName );
|
||||
$poFile->addTranslation( $msgid, stripslashes( $targetOptionValue ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
} //end foreach
|
||||
}
|
||||
//G::streamFile( $sPOFile, true );
|
||||
}
|
||||
}
|
||||
// Language
|
||||
|
||||
|
||||
@@ -225,6 +225,81 @@ class Translation extends BaseTranslation
|
||||
//to do: uniform coderror structures for all classes
|
||||
}
|
||||
|
||||
/* Load strings from plugin translation.php .
|
||||
* @parameter $languageId (es|en|...).
|
||||
*/
|
||||
public function generateFileTranslationPlugin ($plugin, $languageId = '')
|
||||
{
|
||||
$translation = Array ();
|
||||
$translationJS = Array ();
|
||||
|
||||
if ($languageId === '') {
|
||||
$languageId = defined( 'SYS_LANG' ) ? SYS_LANG : 'en';
|
||||
}
|
||||
global $translations;
|
||||
include PATH_PLUGINS . $plugin . PATH_SEP . 'translations'. PATH_SEP . 'translation.php';
|
||||
|
||||
$cacheFile = PATH_LANGUAGECONT . $plugin . "." . $languageId;
|
||||
$cacheFileJS = PATH_CORE . 'js' . PATH_SEP . 'labels' . PATH_SEP . $languageId . ".js";
|
||||
|
||||
foreach ($translations as $key => $row) {
|
||||
$translation[$key] = $row;
|
||||
}
|
||||
|
||||
try {
|
||||
if (! is_dir( dirname( $cacheFile ) )) {
|
||||
G::mk_dir( dirname( $cacheFile ) );
|
||||
}
|
||||
if (! is_dir( dirname( $cacheFileJS ) )) {
|
||||
G::mk_dir( dirname( $cacheFileJS ) );
|
||||
}
|
||||
$f = fopen( $cacheFile, 'w+' );
|
||||
fwrite( $f, "<?php\n" );
|
||||
fwrite( $f, '$translation =' . 'unserialize(\'' . addcslashes( serialize( $translation ), '\\\'' ) . "');\n" );
|
||||
fwrite( $f, "?>" );
|
||||
fclose( $f );
|
||||
|
||||
$f = fopen( $cacheFileJS, 'w' );
|
||||
fwrite( $f, "var G_STRINGS =" . Bootstrap::json_encode( $translationJS ) . ";\n" );
|
||||
fclose( $f );
|
||||
|
||||
$res['cacheFile'] = $cacheFile;
|
||||
$res['cacheFileJS'] = $cacheFileJS;
|
||||
$res['rows'] = count( $translation );
|
||||
$res['rowsJS'] = count( $translationJS );
|
||||
return $res;
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function addTranslationEnvironmentPlugins ($plugin, $locale, $headers, $numRecords)
|
||||
{
|
||||
$filePath = PATH_DATA . "META-INF" . PATH_SEP . $plugin . ".env";
|
||||
$environments = Array ();
|
||||
|
||||
if (file_exists( $filePath )) {
|
||||
$environments = unserialize( file_get_contents( $filePath ) );
|
||||
}
|
||||
|
||||
$environment['LOCALE'] = $locale;
|
||||
$environment['HEADERS'] = $headers;
|
||||
$environment['DATE'] = date( 'Y-m-d H:i:s' );
|
||||
$environment['NUM_RECORDS'] = $numRecords;
|
||||
$environment['LANGUAGE'] = $headers['X-Poedit-Language'];
|
||||
|
||||
if (strpos( $locale, self::$localeSeparator ) !== false) {
|
||||
list ($environment['LAN_ID'], $environment['IC_UID']) = explode( self::$localeSeparator, strtoupper( $locale ) );
|
||||
$environments[$environment['LAN_ID']][$environment['IC_UID']] = $environment;
|
||||
} else {
|
||||
$environment['LAN_ID'] = strtoupper( $locale );
|
||||
$environment['IC_UID'] = '';
|
||||
$environments[$locale]['__INTERNATIONAL__'] = $environment;
|
||||
}
|
||||
|
||||
file_put_contents( $filePath, serialize( $environments ) );
|
||||
}
|
||||
|
||||
public function remove ($sCategory, $sId, $sLang)
|
||||
{
|
||||
$oTranslation = TranslationPeer::retrieveByPK( $sCategory, $sId, $sLang );
|
||||
|
||||
Reference in New Issue
Block a user