Merged in feature/HOR-3208 (pull request #5694)

Feature/HOR-3208

Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
David Callizaya
2017-06-03 18:29:03 +00:00
committed by Julio Cesar Laura Avendaño
6 changed files with 304 additions and 13 deletions

View File

@@ -12,17 +12,6 @@
bootstrap="tests/bootstrap.php" bootstrap="tests/bootstrap.php"
> >
<testsuites> <testsuites>
<!-- <testsuite name="automated">
<directory>./tests/automated/</directory>
</testsuite>
<testsuite name="unit">
<directory>./tests/unit/</directory>
</testsuite>
<testsuite name="api">
<directory>./workflow/engine/src/</directory>
</testsuite>-->
<testsuite name="workflow"> <testsuite name="workflow">
<directory>./tests/workflow/engine/src/</directory> <directory>./tests/workflow/engine/src/</directory>
</testsuite> </testsuite>
@@ -55,7 +44,7 @@
<var name="DB_USER" value="root" /> <var name="DB_USER" value="root" />
<var name="DB_PASS" value="" /> <var name="DB_PASS" value="" />
<var name="PATH_DB" value="./test_shared/workflow_data/sites/" /> <var name="PATH_DB" value="./test_shared/workflow_data/sites/" />
<var name="PATH_DATA" value="./test_shared/workflow_data/sites/" /> <var name="PATH_DATA" value="./test_shared/workflow_data/" />
<var name="APP_HOST" value="localhost" /> <var name="APP_HOST" value="localhost" />
<var name="HTTPS" value="off" /> <var name="HTTPS" value="off" />
</php> </php>

View File

@@ -66,6 +66,16 @@ class WorkflowTestCase extends TestCase
chdir($pwd); chdir($pwd);
} }
/**
* Clean the shared folder to only have the sites.
*/
protected function cleanShared()
{
$this->rrmdir(PATH_DATA.'skins');
mkdir(PATH_DATA.'skins');
clearstatcache();
}
/** /**
* Set the text of and specific translated message. * Set the text of and specific translated message.
* *
@@ -91,4 +101,17 @@ class WorkflowTestCase extends TestCase
unset($translation[$msgId]); unset($translation[$msgId]);
} }
} }
private function rrmdir($dir)
{
if (!is_dir($dir)) {
return;
}
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
(is_dir("$dir/$file") && !is_link($dir)) ? $this->rrmdir("$dir/$file")
: unlink("$dir/$file");
}
return rmdir($dir);
}
} }

View File

@@ -33,7 +33,6 @@ define('PATH_DATA', realpath($GLOBALS['PATH_DATA']).'/');
define('PATH_C', PATH_TRUNK.'tmp/'); define('PATH_C', PATH_TRUNK.'tmp/');
define('PATH_SMARTY_C', PATH_TRUNK.'tmp/'); define('PATH_SMARTY_C', PATH_TRUNK.'tmp/');
define('PATH_SMARTY_CACHE', PATH_TRUNK.'tmp/'); define('PATH_SMARTY_CACHE', PATH_TRUNK.'tmp/');
define('PATH_DATA_SITE', PATH_DATA.'sites/'.SYS_SYS.'/'); define('PATH_DATA_SITE', PATH_DATA.'sites/'.SYS_SYS.'/');
define('PATH_DOCUMENT', PATH_DATA_SITE.'files/'); define('PATH_DOCUMENT', PATH_DATA_SITE.'files/');
define('PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE.'mailTemplates/'); define('PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE.'mailTemplates/');
@@ -43,6 +42,7 @@ define('PATH_DYNAFORM', PATH_DATA_SITE.'xmlForms/');
define('PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE.'usersFiles'.PATH_SEP); define('PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE.'usersFiles'.PATH_SEP);
define('PATH_IMAGES_ENVIRONMENT_USERS', define('PATH_IMAGES_ENVIRONMENT_USERS',
PATH_DATA_SITE.'usersPhotographies'.PATH_SEP); PATH_DATA_SITE.'usersPhotographies'.PATH_SEP);
define( 'PATH_CUSTOM_SKINS', PATH_DATA . 'skins' . PATH_SEP );
//require PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php'; //require PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php';

View File

@@ -0,0 +1,77 @@
<?php
namespace ProcessMaker\BusinessModel;
/**
* Skins Tests
*/
class SkinsTest extends \WorkflowTestCase
{
/**
* @var Skins
*/
protected $object;
/**
* Sets up the unit test.
*/
protected function setUp()
{
$this->cleanShared();
$this->setupDB();
$this->object = new Skins;
}
/**
* Tears down the unit test.
*/
protected function tearDown()
{
$this->cleanShared();
$this->dropDB();
}
/**
* Get default skins and one custom global skin.
*
* @covers ProcessMaker\BusinessModel\Skins::getSkins
* @covers ProcessMaker\BusinessModel\Skins::createSkin
* @category HOR-3208:1
*/
public function testGetSkins()
{
$skins = $this->object->getSkins();
$this->assertCount(2, $skins);
$this->assertEquals($skins[0]['SKIN_FOLDER_ID'], 'classic');
$this->assertEquals($skins[1]['SKIN_FOLDER_ID'], 'neoclassic');
$this->object->createSkin('test', 'test');
$skins2 = $this->object->getSkins();
$this->assertCount(3, $skins2);
$this->assertEquals($skins2[2]['SKIN_FOLDER_ID'], 'test');
}
/**
* Get default skins, one custom global and one custom current workspace skin.
*
* @covers ProcessMaker\BusinessModel\Skins::getSkins
* @covers ProcessMaker\BusinessModel\Skins::createSkin
* @category HOR-3208:2
*/
public function testGetSkinsCurrentWorkspace()
{
$this->object->createSkin('test', 'test');
$this->object->createSkin(
'test2',
'test2',
'Second skin',
'ProcessMaker Team',
'current',
'neoclassic'
);
$skins = $this->object->getSkins();
$this->assertCount(4, $skins);
$this->assertEquals($skins[2]['SKIN_FOLDER_ID'], 'test');
$this->assertEquals($skins[3]['SKIN_FOLDER_ID'], 'test2');
$this->assertEquals($skins[3]['SKIN_WORKSPACE'], SYS_SYS);
}
}

View File

@@ -0,0 +1,181 @@
<?php
namespace ProcessMaker\BusinessModel;
use System;
use Exception;
use G;
/**
* Skins business model
*/
class Skins
{
/**
* Get a list of skins.
*
* @category HOR-3208,PROD-181
* @return array
*/
public function getSkins()
{
$list = System::getSkingList();
return $list['skins'];
}
/**
* Create a new skin.
*
* @param string $skinName
* @param string $skinFolder
* @param string $skinDescription
* @param string $skinAuthor
* @param string $skinWorkspace
* @param string $skinBase
* @return array
* @throws Exception
*/
public function createSkin(
$skinName,
$skinFolder,
$skinDescription = '',
$skinAuthor = 'ProcessMaker Team',
$skinWorkspace = 'global',
$skinBase = 'neoclassic'
) {
try {
if (!(isset($skinName))) {
throw (new Exception(G::LoadTranslation('ID_SKIN_NAME_REQUIRED')));
}
if (!(isset($skinFolder))) {
throw (new Exception(G::LoadTranslation('ID_SKIN_FOLDER_REQUIRED')));
}
if (is_dir(PATH_CUSTOM_SKINS.$skinFolder)) {
throw (new Exception(G::LoadTranslation('ID_SKIN_ALREADY_EXISTS')));
}
if (strtolower($skinFolder) == 'classic') {
throw (new Exception(G::LoadTranslation('ID_SKIN_ALREADY_EXISTS')));
}
//All validations OK then create skin
switch ($skinBase) {
//Validate skin base
case 'uxmodern':
$this->copySkinFolder(G::ExpandPath("skinEngine").'uxmodern'.PATH_SEP,
PATH_CUSTOM_SKINS.$skinFolder,
array("config.xml"
));
$pathBase = G::ExpandPath("skinEngine").'base'.PATH_SEP;
break;
case 'classic':
//Special Copy of this dir + xmlreplace
$this->copySkinFolder(G::ExpandPath("skinEngine").'base'.PATH_SEP,
PATH_CUSTOM_SKINS.$skinFolder,
array("config.xml", "baseCss"
));
$pathBase = G::ExpandPath("skinEngine").'base'.PATH_SEP;
break;
case 'neoclassic':
//Special Copy of this dir + xmlreplace
$this->copySkinFolder(G::ExpandPath("skinEngine").'neoclassic'.PATH_SEP,
PATH_CUSTOM_SKINS.$skinFolder,
array("config.xml", "baseCss"
));
$pathBase = G::ExpandPath("skinEngine").'neoclassic'.PATH_SEP;
break;
default:
//Commmon copy/paste of a folder + xmlrepalce
$this->copySkinFolder(PATH_CUSTOM_SKINS.$skinBase,
PATH_CUSTOM_SKINS.$skinFolder,
array("config.xml"
));
$pathBase = PATH_CUSTOM_SKINS.$skinBase.PATH_SEP;
break;
}
//@todo Improve this pre_replace lines
$configFileOriginal = $pathBase."config.xml";
$configFileFinal = PATH_CUSTOM_SKINS.$skinFolder.PATH_SEP.'config.xml';
$xmlConfiguration = file_get_contents($configFileOriginal);
$workspace = ($skinWorkspace == 'global') ? '' : SYS_SYS;
$xmlConfigurationObj = G::xmlParser($xmlConfiguration);
$skinInformationArray = $xmlConfigurationObj->result["skinConfiguration"]["__CONTENT__"]["information"]["__CONTENT__"];
$xmlConfiguration = preg_replace('/(<id>)(.+?)(<\/id>)/i',
'<id>'.G::generateUniqueID().'</id><!-- $2 -->',
$xmlConfiguration);
if (isset($skinInformationArray["workspace"]["__VALUE__"])) {
$workspace = ($workspace != "" && !empty($skinInformationArray["workspace"]["__VALUE__"]))
? $skinInformationArray["workspace"]["__VALUE__"]."|".$workspace
: $workspace;
$xmlConfiguration = preg_replace("/(<workspace>)(.*)(<\/workspace>)/i",
"<workspace>".$workspace."</workspace><!-- $2 -->",
$xmlConfiguration);
$xmlConfiguration = preg_replace("/(<name>)(.*)(<\/name>)/i",
"<name>".$skinName."</name><!-- $2 -->",
$xmlConfiguration);
} else {
$xmlConfiguration = preg_replace("/(<name>)(.*)(<\/name>)/i",
"<name>".$skinName."</name><!-- $2 -->\n<workspace>".$workspace."</workspace>",
$xmlConfiguration);
}
$xmlConfiguration = preg_replace("/(<description>)(.+?)(<\/description>)/i",
"<description>".$skinDescription."</description><!-- $2 -->",
$xmlConfiguration);
$xmlConfiguration = preg_replace("/(<author>)(.+?)(<\/author>)/i",
"<author>".$skinAuthor."</author><!-- $2 -->",
$xmlConfiguration);
$xmlConfiguration = preg_replace("/(<createDate>)(.+?)(<\/createDate>)/i",
"<createDate>".date("Y-m-d H:i:s")."</createDate><!-- $2 -->",
$xmlConfiguration);
$xmlConfiguration = preg_replace("/(<modifiedDate>)(.+?)(<\/modifiedDate>)/i",
"<modifiedDate>".date("Y-m-d H:i:s")."</modifiedDate><!-- $2 -->",
$xmlConfiguration);
file_put_contents($configFileFinal, $xmlConfiguration);
$response['success'] = true;
$response['message'] = G::LoadTranslation('ID_SKIN_SUCCESS_CREATE');
G::auditLog("CreateSkin", "Skin Name: ".$skinName);
return $response;
} catch (Exception $e) {
$response['success'] = false;
$response['message'] = $e->getMessage();
$response['error'] = $e->getMessage();
return $response;
}
}
private function copySkinFolder($path, $dest, $exclude = array())
{
$defaultExcluded = array(".", "..");
$excludedItems = array_merge($defaultExcluded, $exclude);
if (is_dir($path)) {
mkdir($dest);
$objects = scandir($path);
if (sizeof($objects) > 0) {
foreach ($objects as $file) {
if (in_array($file, $excludedItems)) {
continue;
}
if (is_dir($path.PATH_SEP.$file)) {
$this->copySkinFolder($path.PATH_SEP.$file,
$dest.PATH_SEP.$file, $exclude);
} else {
copy($path.PATH_SEP.$file, $dest.PATH_SEP.$file);
}
}
}
return true;
} elseif (is_file($path)) {
return copy($path, $dest);
} else {
return false;
}
}
}

View File

@@ -102,4 +102,25 @@ class System extends Api
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
} }
} }
/**
* Get the list of installed skins.
*
* @url GET /skins
* @return array
* @access protected
* @class AccessControl {@permission PM_FACTORY}
* @protected
*/
public function doGetSkins()
{
try {
$model = new \ProcessMaker\BusinessModel\Skins();
$response = $model->getSkins();
return ["data" => $response];
} catch (\Exception $e) {
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
}
}
} }