From 4304abc2a6b0cd2a5f1490ff8fae30df24f55071 Mon Sep 17 00:00:00 2001 From: davidcallizaya Date: Wed, 24 May 2017 14:04:07 -0400 Subject: [PATCH] HOR-3208 Web Entry 2.0 Rest - Skin EP ACCEPTANCE CRITERIAS: 1. Get list of global and installed skins. 2. Verify that the list includes skins available only for the workspace. --- phpunit.xml | 13 +- tests/WorkflowTestCase.php | 23 +++ tests/bootstrap.php | 2 +- .../ProcessMaker/BusinessModel/SkinsTest.php | 77 ++++++++ .../src/ProcessMaker/BusinessModel/Skins.php | 181 ++++++++++++++++++ .../src/ProcessMaker/Services/Api/System.php | 16 ++ 6 files changed, 299 insertions(+), 13 deletions(-) create mode 100644 tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/SkinsTest.php create mode 100644 workflow/engine/src/ProcessMaker/BusinessModel/Skins.php diff --git a/phpunit.xml b/phpunit.xml index bdec9bbb5..3012d70ef 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,17 +12,6 @@ bootstrap="tests/bootstrap.php" > - ./tests/workflow/engine/src/ @@ -55,7 +44,7 @@ - + diff --git a/tests/WorkflowTestCase.php b/tests/WorkflowTestCase.php index aecfbd5a1..b5eb3dfa2 100644 --- a/tests/WorkflowTestCase.php +++ b/tests/WorkflowTestCase.php @@ -66,6 +66,16 @@ class WorkflowTestCase extends TestCase 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. * @@ -91,4 +101,17 @@ class WorkflowTestCase extends TestCase 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); + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 0930c334a..cbc3605bd 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -33,7 +33,6 @@ define('PATH_DATA', realpath($GLOBALS['PATH_DATA']).'/'); define('PATH_C', PATH_TRUNK.'tmp/'); define('PATH_SMARTY_C', PATH_TRUNK.'tmp/'); define('PATH_SMARTY_CACHE', PATH_TRUNK.'tmp/'); - define('PATH_DATA_SITE', PATH_DATA.'sites/'.SYS_SYS.'/'); define('PATH_DOCUMENT', PATH_DATA_SITE.'files/'); 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_USERS', 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'; diff --git a/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/SkinsTest.php b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/SkinsTest.php new file mode 100644 index 000000000..b151acb44 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/SkinsTest.php @@ -0,0 +1,77 @@ +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 defaut 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); + } +} diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Skins.php b/workflow/engine/src/ProcessMaker/BusinessModel/Skins.php new file mode 100644 index 000000000..6c84f8df5 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Skins.php @@ -0,0 +1,181 @@ +copy_skin_folder(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->copy_skin_folder(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->copy_skin_folder(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->copy_skin_folder(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>)/i', + ''.G::generateUniqueID().'', + $xmlConfiguration); + + if (isset($skinInformationArray["workspace"]["__VALUE__"])) { + $workspace = ($workspace != "" && !empty($skinInformationArray["workspace"]["__VALUE__"])) + ? $skinInformationArray["workspace"]["__VALUE__"]."|".$workspace + : $workspace; + + $xmlConfiguration = preg_replace("/()(.*)(<\/workspace>)/i", + "".$workspace."", + $xmlConfiguration); + $xmlConfiguration = preg_replace("/()(.*)(<\/name>)/i", + "".$skinName."", + $xmlConfiguration); + } else { + $xmlConfiguration = preg_replace("/()(.*)(<\/name>)/i", + "".$skinName."\n".$workspace."", + $xmlConfiguration); + } + + $xmlConfiguration = preg_replace("/()(.+?)(<\/description>)/i", + "".$skinDescription."", + $xmlConfiguration); + $xmlConfiguration = preg_replace("/()(.+?)(<\/author>)/i", + "".$skinAuthor."", + $xmlConfiguration); + $xmlConfiguration = preg_replace("/()(.+?)(<\/createDate>)/i", + "".date("Y-m-d H:i:s")."", + $xmlConfiguration); + $xmlConfiguration = preg_replace("/()(.+?)(<\/modifiedDate>)/i", + "".date("Y-m-d H:i:s")."", + $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 copy_skin_folder($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->copy_skin_folder($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; + } + } +} diff --git a/workflow/engine/src/ProcessMaker/Services/Api/System.php b/workflow/engine/src/ProcessMaker/Services/Api/System.php index f2e84c6bd..d2355ab29 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/System.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/System.php @@ -102,4 +102,20 @@ class System extends Api throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); } } + + /** + * @url GET /skins + * @return array + */ + 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())); + } + } + }