From ef5ed8f9307918b765a05dd72df3468dc31f298e Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch>
Date: Thu, 23 Nov 2023 16:16:42 +0100
Subject: [PATCH] update getProjects method

---
 .../deployment/classes/project.class.php      | 808 ++++++++++--------
 .../deployment/classes/projectlist.class.php  | 234 +++--
 public_html/deployment/inc_functions.php      |   9 +-
 3 files changed, 566 insertions(+), 485 deletions(-)

diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php
index c9f50b5b..7af763ac 100644
--- a/public_html/deployment/classes/project.class.php
+++ b/public_html/deployment/classes/project.class.php
@@ -3,7 +3,7 @@
 define("OPTION_DEFAULT", -999);
 define("OPTION_NONE", -1);
 
-require_once __DIR__.'/../inc_functions.php';
+require_once __DIR__ . '/../inc_functions.php';
 require_once 'base.class.php';
 
 require_once 'messenger.class.php';
@@ -31,7 +31,8 @@ require_once 'htmlguielements.class.php';
  * class for single project
  */
 // class project {
-class project extends base {
+class project extends base
+{
     // ----------------------------------------------------------------------
     // CONFIG
     // ----------------------------------------------------------------------
@@ -82,27 +83,27 @@ class project extends base {
      */
     protected $_iRcAll = 0;
 
-        
+
     /**
      * reference to html renderer class to draw output items
      * @var object
      */
     protected $_oHtml = false;
-    
+
     /**
      * object to access a version control, .e. git
      * @var object
      */
     protected $_oVcs = false;
-    
+
     /**
      * object for rollout
      * @var type
      */
     public $oRolloutPlugin = false;
-    
+
     protected $_sBranchname = false;
-    
+
     /**
      * send messages
      * @var messengerobject
@@ -123,7 +124,8 @@ class project extends base {
      * constructor
      * @param string $sId  id of the project
      */
-    public function __construct($sId = false) {
+    public function __construct($sId = false)
+    {
         $this->oUser = new user();
         $this->_oHtml = new htmlguielements();
         $this->_readConfig();
@@ -142,7 +144,8 @@ class project extends base {
      * @param  string $sLevel    warnlevel of the given message
      * @return bool
      */
-    protected function log($sMessage, $sLevel = "info") {
+    protected function log($sMessage, $sLevel = "info")
+    {
         global $oCLog;
         return $oCLog->add(basename(__FILE__) . " class " . __CLASS__ . " - " . $sMessage, $sLevel);
     }
@@ -152,44 +155,46 @@ class project extends base {
      * @param string $sMessage
      * @return boolean
      */
-    protected function _sendMessage($sMessage){
-        $aConfig=array();
-        
-        if (array_key_exists('messenger', $this->_aPrjConfig)
-           && array_key_exists('slack', $this->_aPrjConfig['messenger'])
-        ){
-            $sSlack=$this->_aPrjConfig['messenger']['slack'];
-            $aConfig['slack']=array('incomingurl'=>$sSlack);
-            foreach(array('user', 'icon') as $sKey){
-                if (isset($this->_aConfig['messenger']['slack']['presets'][$sSlack][$sKey])){
-                    $aConfig['slack'][$sKey]=$this->_aConfig['messenger']['slack']['presets'][$sSlack][$sKey];
+    protected function _sendMessage($sMessage)
+    {
+        $aConfig = array();
+
+        if (
+            array_key_exists('messenger', $this->_aPrjConfig)
+            && array_key_exists('slack', $this->_aPrjConfig['messenger'])
+        ) {
+            $sSlack = $this->_aPrjConfig['messenger']['slack'];
+            $aConfig['slack'] = array('incomingurl' => $sSlack);
+            foreach (array('user', 'icon') as $sKey) {
+                if (isset($this->_aConfig['messenger']['slack']['presets'][$sSlack][$sKey])) {
+                    $aConfig['slack'][$sKey] = $this->_aConfig['messenger']['slack']['presets'][$sSlack][$sKey];
                 }
             }
         }
-        
-        if (array_key_exists('messenger', $this->_aPrjConfig)
-           && array_key_exists('email', $this->_aPrjConfig['messenger'])
-           && $this->_aPrjConfig['messenger']['email']
-        ){
-            $aConfig['email']=$this->_aConfig['messenger']['email'];
-            $aConfig['email']['to']=$this->_aPrjConfig['messenger']['email'];
+
+        if (
+            array_key_exists('messenger', $this->_aPrjConfig)
+            && array_key_exists('email', $this->_aPrjConfig['messenger'])
+            && $this->_aPrjConfig['messenger']['email']
+        ) {
+            $aConfig['email'] = $this->_aConfig['messenger']['email'];
+            $aConfig['email']['to'] = $this->_aPrjConfig['messenger']['email'];
         }
-        if(!count($aConfig)){
+        if (!count($aConfig)) {
             return false;
         }
-        
+
         // init on first usage
-        if (!$this->oMessenger){
-            $this->oMessenger=new messenger($aConfig);
+        if (!$this->oMessenger) {
+            $this->oMessenger = new messenger($aConfig);
         }
 
         // add some metadata to the message body
-        $sText=$this->getLabel().': '.html_entity_decode($sMessage)."\n" 
-                . t('page-login-username'). ": ".$this->oUser->getUsername()."\n"
-                ;
+        $sText = $this->getLabel() . ': ' . html_entity_decode($sMessage) . "\n"
+            . t('page-login-username') . ": " . $this->oUser->getUsername() . "\n";
         if (isset($_SERVER) && is_array($_SERVER)) {
-            if(array_key_exists('HTTP_HOST', $_SERVER)){
-                $sText.= t('project-home').': '.$_SERVER['REQUEST_SCHEME'].'://'. $_SERVER['HTTP_HOST'].'/deployment/'.$this->getId()."\n";
+            if (array_key_exists('HTTP_HOST', $_SERVER)) {
+                $sText .= t('project-home') . ': ' . $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . '/deployment/' . $this->getId() . "\n";
             }
             /*
             if(array_key_exists('HTTP_ORIGIN', $_SERVER)){
@@ -203,7 +208,8 @@ class project extends base {
      * read default config file
      * @return boolean
      */
-    protected function _readConfig() {
+    protected function _readConfig()
+    {
         global $aConfig;
         $this->_aConfig = $aConfig;
         return true;
@@ -213,8 +219,9 @@ class project extends base {
      * validate config data
      * @return boolean
      */
-    protected function _verifyConfig() {
-        if (!is_array($this->_aPrjConfig) || !count($this->_aPrjConfig)){
+    protected function _verifyConfig()
+    {
+        if (!is_array($this->_aPrjConfig) || !count($this->_aPrjConfig)) {
             // die(t("class-project-error-no-config"));
             throw new Exception(t("class-project-error-no-config"));
         }
@@ -269,7 +276,8 @@ class project extends base {
      * @param string $sCommand
      * @return string
      */
-    protected function _execAndSend($sCommand, $bFlush = false) {
+    protected function _execAndSend($sCommand, $bFlush = false)
+    {
         $this->log(__FUNCTION__ . " start");
         $sReturn = '';
         $bUseHtml = $_SERVER ? true : false;
@@ -279,16 +287,16 @@ class project extends base {
         }
         // ob_end_flush();
         // stderr ausgeben
-        $sCommand.=' 2>&1';
-        $sReturn.="[" . date("H:i:s d.m.Y") . "] ";
-        $sReturn.=$bUseHtml ? "<strong>$sCommand</strong>" : "$sCommand";
-        $sReturn.=$bUseHtml ? "<br>" : "\n";
+        $sCommand .= ' 2>&1';
+        $sReturn .= "[" . date("H:i:s d.m.Y") . "] ";
+        $sReturn .= $bUseHtml ? "<strong>$sCommand</strong>" : "$sCommand";
+        $sReturn .= $bUseHtml ? "<br>" : "\n";
 
         $sOutput = false;
         $this->log(__FUNCTION__ . " start $sCommand");
         exec($sCommand, $aOutput, $iRc);
         $this->log(__FUNCTION__ . " ended command $sCommand");
-        $sReturn.=(count($aOutput)) ? htmlentities(implode("\n", $aOutput)) . "\n" : "";
+        $sReturn .= (count($aOutput)) ? htmlentities(implode("\n", $aOutput)) . "\n" : "";
         /*
           $descriptorspec = array(
           0 => array("pipe", "r"), // stdin is a pipe that the child will read from
@@ -328,14 +336,14 @@ class project extends base {
         }
 
         $this->_iRcAll += $iRc;
-        $sReturn.="[" . date("H:i:s d.m.Y") . "] " . t("exitcode") . " " . $iRc;
+        $sReturn .= "[" . date("H:i:s d.m.Y") . "] " . t("exitcode") . " " . $iRc;
         if ($bUseHtml) {
             if ($iRc == 0) {
                 $sReturn = '<pre class="cli">' . $sReturn;
             } else {
                 $sReturn = '<pre class="cli error">' . $sReturn;
             }
-            $sReturn.='</pre>';
+            $sReturn .= '</pre>';
         }
 
         if ($bFlush) {
@@ -350,7 +358,8 @@ class project extends base {
      * @param string $sAction     project action
      * @param string $sLoglevel   loglevel
      */
-    protected function _logaction($sMessage, $sAction = "", $sLoglevel = "info") {
+    protected function _logaction($sMessage, $sAction = "", $sLoglevel = "info")
+    {
         require_once("actionlog.class.php");
         $oLog = new Actionlog($this->_aConfig["id"]);
         $oLog->add($sMessage, (__CLASS__ . "->" . $sAction), $sLoglevel);
@@ -360,7 +369,8 @@ class project extends base {
     // GETTER
     // ----------------------------------------------------------------------
 
-    protected function _getConfigFile($sId) {
+    protected function _getConfigFile($sId)
+    {
         if (!$sId) {
             die(t("class-project-error-_getConfigFile-requires-id"));
         }
@@ -371,7 +381,8 @@ class project extends base {
      * get a full ath for temp directory (for a build)
      * @return string
      */
-    protected function _getTempDir() {
+    protected function _getTempDir()
+    {
         return $s = $this->_getBuildDir() . '/' . $this->_aPrjConfig["fileprefix"] . "_" . date("Ymd-His");
     }
 
@@ -379,7 +390,8 @@ class project extends base {
      * get full path where the project builds are (a build setes a subdir)
      * @return string
      */
-    protected function _getBuildDir() {
+    protected function _getBuildDir()
+    {
         return $this->_aConfig['buildDir'] . '/' . $this->_aConfig["id"];
     }
 
@@ -387,7 +399,8 @@ class project extends base {
      * get full path where the project default files are
      * @return type
      */
-    protected function _getDefaultsDir() {
+    protected function _getDefaultsDir()
+    {
         $s = $this->_aConfig['buildDefaultsDir'] . '/' . $this->_aConfig["id"];
         return file_exists($s) ? $s : false;
     }
@@ -398,7 +411,8 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    protected function _getFileBase($sPhase, $sPlace) {
+    protected function _getFileBase($sPhase, $sPlace)
+    {
         if (!array_key_exists($sPhase, $this->_aConfig["phases"])) {
             die(sprintf(t("class-project-error-wrong-phase"), $sPhase));
         }
@@ -413,8 +427,8 @@ class project extends base {
             mkdir($this->_aConfig['packageDir'] . "/" . $sPhase);
         }
 
-        if ($sPlace == "onhold"){
-            $sBase.="_onhold";
+        if ($sPlace == "onhold") {
+            $sBase .= "_onhold";
         }
         // $sBase .= "/" . $this->_aPrjConfig["fileprefix"];
         // url for deployed
@@ -437,7 +451,8 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    protected function _getInfofile($sPhase, $sPlace) {
+    protected function _getInfofile($sPhase, $sPlace)
+    {
         $sBase = $this->_getFileBase($sPhase, $sPlace);
         return $sBase ? $sBase . '/' . $this->_aPrjConfig["fileprefix"] . '.json' : false;
     }
@@ -448,7 +463,8 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return string
      */
-    protected function _getPackagefile($sPhase, $sPlace) {
+    protected function _getPackagefile($sPhase, $sPlace)
+    {
         $sBase = $this->_getFileBase($sPhase, $sPlace);
         return $sBase ? $sBase . '/' . $this->_aPrjConfig["fileprefix"] : false;
     }
@@ -459,7 +475,8 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return array
      */
-    public function _getBuildfilesByDir($sBase) {
+    public function _getBuildfilesByDir($sBase)
+    {
         $aReturn = array();
         if (!$sBase || !is_dir($sBase)) {
             return false;
@@ -495,7 +512,7 @@ class project extends base {
                     $sIcon = 'file-any';
                     break;
             }
-            $iTotalSize+=$aStat['size'];
+            $iTotalSize += $aStat['size'];
             $aReturn['files'][$sFileBase] = array(
                 'type' => $sType,
                 'icon' => $this->_oHtml->getIcon($sIcon),
@@ -517,7 +534,8 @@ class project extends base {
      * @param string $sPlace  one of onhold|ready2install|deployed
      * @return array
      */
-    public function getBuildfilesByPlace($sPhase, $sPlace) {
+    public function getBuildfilesByPlace($sPhase, $sPlace)
+    {
         $sBase = $this->_getFileBase($sPhase, $sPlace);
         return $this->_getBuildfilesByDir($sBase);
     }
@@ -527,7 +545,8 @@ class project extends base {
      * @param string $sVersion  name of version 
      * @return array
      */
-    public function getBuildfilesByVersion($sVersion) {
+    public function getBuildfilesByVersion($sVersion)
+    {
         return $this->_getBuildfilesByDir($this->_getProjectArchiveDir() . '/' . $sVersion);
     }
 
@@ -535,15 +554,17 @@ class project extends base {
      * get the group id of the project
      * @return string
      */
-    public function getProjectGroup() {
-        return isset($this->_aPrjConfig["projectgroup"]) && $this->_aPrjConfig["projectgroup"]!='-1' ? $this->_aPrjConfig["projectgroup"] : false;
+    public function getProjectGroup()
+    {
+        return isset($this->_aPrjConfig["projectgroup"]) && $this->_aPrjConfig["projectgroup"] != '-1' ? $this->_aPrjConfig["projectgroup"] : false;
     }
     /**
      * get the group label of the project
      * @return string
      */
-    public function getProjectGroupLabel() {
-        $sGroupid=$this->getProjectGroup();
+    public function getProjectGroupLabel()
+    {
+        $sGroupid = $this->getProjectGroup();
         return isset($this->_aConfig["projectgroups"][$sGroupid]) ? $this->_aConfig["projectgroups"][$sGroupid] : false;
     }
 
@@ -552,7 +573,8 @@ class project extends base {
      * @param string $sVersion  version number of the build
      * @return string
      */
-    protected function _getArchiveDir($sVersion) {
+    protected function _getArchiveDir($sVersion)
+    {
         if (!$sVersion) {
             die(t("class-project-error-_getArchiveDir-requires-id"));
         }
@@ -567,7 +589,8 @@ class project extends base {
      * @param type $sTimestamp
      * @return array
      */
-    protected function _getArchiveInfos($sTimestamp) {
+    protected function _getArchiveInfos($sTimestamp)
+    {
         if (!$sTimestamp) {
             die(t("class-project-error-_getArchiveInfos-requires-id"));
         }
@@ -601,7 +624,8 @@ class project extends base {
      * get the directory for archive files of this project
      * @return string
      */
-    public function _getProjectArchiveDir() {
+    public function _getProjectArchiveDir()
+    {
         return $this->_aConfig["archiveDir"] . '/' . $this->_aConfig["id"];
     }
 
@@ -611,7 +635,8 @@ class project extends base {
      * @param string $url
      * @return string
      */
-    private function _httpGet($url, $iTimeout = 5) {
+    private function _httpGet($url, $iTimeout = 5)
+    {
         $this->log(__FUNCTION__ . " start");
         if (!function_exists("curl_init")) {
             die("ERROR: PHP CURL module is not installed.");
@@ -633,7 +658,8 @@ class project extends base {
      * versions are array keys; where they are used is written in values
      * @return array
      */
-    public function getVersions() {
+    public function getVersions()
+    {
 
         // --- read all file entries
         $aReturn = array();
@@ -662,14 +688,15 @@ class project extends base {
      * get an array with all existing build error output files (html)
      * @return array
      */
-    public function getBuildErrors($sProject=false) {
+    public function getBuildErrors($sProject = false)
+    {
         // --- read all file entries
         $aReturn = array();
-        if(!$sProject){
-            $sProject=$this->_aPrjConfig["fileprefix"].'_*';
+        if (!$sProject) {
+            $sProject = $this->_aPrjConfig["fileprefix"] . '_*';
         }
-        foreach( glob($this->_getBuildDir() . '/' . $sProject . "/_output.html" ) as $sBuildDir){
-            $aReturn[] = basename(dirname($sBuildDir)).'/'.basename($sBuildDir);
+        foreach (glob($this->_getBuildDir() . '/' . $sProject . "/_output.html") as $sBuildDir) {
+            $aReturn[] = basename(dirname($sBuildDir)) . '/' . basename($sBuildDir);
         }
         return $aReturn;
     }
@@ -677,12 +704,13 @@ class project extends base {
      * get an array with all existing build error output files (html)
      * @return array
      */
-    public function getBuildErrorContent($sLogfile) {
-        if (!strpos('..', $sLogfile)===false){
+    public function getBuildErrorContent($sLogfile)
+    {
+        if (!strpos('..', $sLogfile) === false) {
             return false;
         }
-        $sFilename=$this->_getBuildDir() . '/' . $sLogfile;
-        if(file_exists($sFilename)){
+        $sFilename = $this->_getBuildDir() . '/' . $sLogfile;
+        if (file_exists($sFilename)) {
             return file_get_contents($sFilename);
         }
         return false;
@@ -693,7 +721,8 @@ class project extends base {
      * and a rollback ist possible or not
      * return array
      */
-    protected function _getVersionUsage() {
+    protected function _getVersionUsage()
+    {
         $aVersionData = array();
         $sLastVersion = false;
         if (!count($this->getVersions())) {
@@ -709,7 +738,8 @@ class project extends base {
                     $bFound = false;
                     if (is_array($aData) && count($aData)) {
                         foreach ($aData as $i => $aPhaseUsage) {
-                            if ($aPhaseUsage["phase"] == $sPhase && $aPhaseUsage["place"] == $sPlace
+                            if (
+                                $aPhaseUsage["phase"] == $sPhase && $aPhaseUsage["place"] == $sPlace
                             )
                                 $bFound = true;
                         }
@@ -720,7 +750,7 @@ class project extends base {
                     } else {
                         $bCanRollback = true;
                         if (
-                                $sLastVersion && !$aVersionData[$sLastVersion]["rollback"][$sPhase]
+                            $sLastVersion && !$aVersionData[$sLastVersion]["rollback"][$sPhase]
                         ) {
                             $bCanRollback = false;
                         }
@@ -743,7 +773,8 @@ class project extends base {
      * @param string $dir  directory to delete
      * @return type
      */
-    protected function _rmdir($dir) {
+    protected function _rmdir($dir)
+    {
         foreach (scandir($dir) as $sEntry) {
             if (is_dir($dir . '/' . $sEntry) && $sEntry != '.' && $sEntry != '..') {
                 $this->_rmdir($dir . '/' . $sEntry);
@@ -758,7 +789,8 @@ class project extends base {
      * directories as array
      * @return array
      */
-    public function cleanupArchive($bDeleteAll = false) {
+    public function cleanupArchive($bDeleteAll = false)
+    {
         if (!$this->oUser->hasPermission("project-action-cleanup")) {
             return $this->oUser->showDenied();
         }
@@ -809,7 +841,8 @@ class project extends base {
      * directories as array
      * @return array
      */
-    public function cleanupBuilds() {
+    public function cleanupBuilds()
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-cleanup")) {
             return $this->oUser->showDenied();
@@ -842,7 +875,8 @@ class project extends base {
      * cleanup cache of vcs
      * @param type $iAge
      */
-    public function cleanupVcsCache($iAge = 0) {
+    public function cleanupVcsCache($iAge = 0)
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-cleanup")) {
             return $this->oUser->showDenied();
@@ -862,7 +896,8 @@ class project extends base {
      * get conmplete config of the project
      * @return array
      */
-    public function getConfig() {
+    public function getConfig()
+    {
         return $this->_aPrjConfig;
     }
 
@@ -870,7 +905,8 @@ class project extends base {
      * get name/ label of the project
      * @return string
      */
-    public function getLabel() {
+    public function getLabel()
+    {
         return isset($this->_aPrjConfig["label"]) ? $this->_aPrjConfig["label"] : '';
     }
 
@@ -878,7 +914,8 @@ class project extends base {
      * get description of the project
      * @return string
      */
-    public function getDescription() {
+    public function getDescription()
+    {
         return isset($this->_aPrjConfig["description"]) ? $this->_aPrjConfig["description"] : '';
     }
 
@@ -886,7 +923,8 @@ class project extends base {
      * get the id of the current project
      * @return string
      */
-    public function getId(){
+    public function getId()
+    {
         return isset($this->_aConfig["id"]) ? $this->_aConfig["id"] : '';
     }
     /**
@@ -895,16 +933,17 @@ class project extends base {
      * or an installation of a new package is going on
      * @return array
      */
-    public function getAllPhaseInfos() {
+    public function getAllPhaseInfos()
+    {
 
-        $bHasQueue=false;
-        $bHasDifferentVersions=false;
-        $bFirstVersion=false;
+        $bHasQueue = false;
+        $bHasDifferentVersions = false;
+        $bFirstVersion = false;
 
-        if (!array_key_exists("phases", $this->_aData)){
+        if (!array_key_exists("phases", $this->_aData)) {
             $this->_aData["phases"] = array();
         }
-        if (!array_key_exists("progress", $this->_aData)){
+        if (!array_key_exists("progress", $this->_aData)) {
             $this->_aData["progress"] = array();
         }
 
@@ -916,25 +955,25 @@ class project extends base {
             $aDataPhase = $this->_aData["phases"][$sPhase];
             foreach (array_keys($this->getPlaces()) as $sPlace) {
                 if (
-                    $sPlace!=='onhold'
+                    $sPlace !== 'onhold'
                     && isset($aDataPhase[$sPlace]['version'])
                 ) {
-                    if($bFirstVersion && !$bHasDifferentVersions && $bFirstVersion!==$aDataPhase[$sPlace]['version']){
-                        $bHasDifferentVersions=true;
+                    if ($bFirstVersion && !$bHasDifferentVersions && $bFirstVersion !== $aDataPhase[$sPlace]['version']) {
+                        $bHasDifferentVersions = true;
                     }
-                    if (!$bFirstVersion){
+                    if (!$bFirstVersion) {
                         $bFirstVersion = $aDataPhase[$sPlace]['version'];
                     }
                 }
             }
             // check queue
-            if (!$bHasQueue && isset($aDataPhase['onhold']['version']) && $aDataPhase['onhold']['version']){
-                $bHasQueue=true;
+            if (!$bHasQueue && isset($aDataPhase['onhold']['version']) && $aDataPhase['onhold']['version']) {
+                $bHasQueue = true;
             }
         }
-        $this->_aData["progress"]=array(
-            'inprogress'=>$bHasDifferentVersions,
-            'hasQueue'=>$bHasQueue,
+        $this->_aData["progress"] = array(
+            'inprogress' => $bHasDifferentVersions,
+            'hasQueue' => $bHasQueue,
         );
         return $this->_aData["phases"];
     }
@@ -944,7 +983,8 @@ class project extends base {
      * @param string $sPhase name of the phase; one of preview|stage|live
      * @return array
      */
-    public function getPhaseInfos($sPhase) {
+    public function getPhaseInfos($sPhase)
+    {
         if (!$sPhase) {
             die(t("class-project-error-getPhaseInfos-requires-phase"));
         }
@@ -982,15 +1022,15 @@ class project extends base {
                 if (file_exists($sJsonfile)) {
                     // $sPkgfile = $this->_getPackagefile($sPhase, $sKey);
                     // if (file_exists($sPkgfile)) {
-                        $aJson = json_decode(file_get_contents($sJsonfile), true);
-                        if (is_array($aJson) && array_key_exists("version", $aJson)) {
-                            $aTmp[$sKey] = $aJson;
-                            $aTmp[$sKey]["infofile"] = $sJsonfile;
-                            // $aTmp[$sKey]["packagefile"] = $sPkgfile;
-                            $aTmp[$sKey]["ok"] = 1;
-                        } else {
-                            $aTmp[$sKey]["error"] = sprintf(t("class-project-error-metafile-has-no-version"), $sJsonfile, print_r($aJson, true));
-                        }
+                    $aJson = json_decode(file_get_contents($sJsonfile), true);
+                    if (is_array($aJson) && array_key_exists("version", $aJson)) {
+                        $aTmp[$sKey] = $aJson;
+                        $aTmp[$sKey]["infofile"] = $sJsonfile;
+                        // $aTmp[$sKey]["packagefile"] = $sPkgfile;
+                        $aTmp[$sKey]["ok"] = 1;
+                    } else {
+                        $aTmp[$sKey]["error"] = sprintf(t("class-project-error-metafile-has-no-version"), $sJsonfile, print_r($aJson, true));
+                    }
                     // } else {
                     //    $aTmp[$sKey]["error"] = sprintf(t("class-project-error-getPhaseInfos-package-not-found"), $sPkgfile);
                     // }
@@ -1010,7 +1050,7 @@ class project extends base {
                 $aVersions = $oVersion->getVersion();
                 // echo "Place: <pre>" . print_r($oVersion->whereiam(), 1) . "</pre>";
                 // echo "Versionen: <pre>" . print_r($aVersions, 1) . "</pre>";
-                if (count($aVersions)){
+                if (count($aVersions)) {
                     $aTmp[$sKey] = array();
                     $aTmp[$sKey] = $aVersions[0]['_data'];
                     $aTmp[$sKey]["infofile"] = '[versioncache]';
@@ -1052,20 +1092,38 @@ class project extends base {
     }
 
     /**
-     * get a list of all existing projects as a flat array
+     * get a list of all existing projects as a flat array;
+     * it can be ordered by "id" or "label"
      * <code>
-     * print_r($oPrj->getProjects());
+     * print_r($oPrj->getProjects("label"));
      * </code>
      * returns<br>
      * Array ( [0] => project1 [1] => project2 ) 
+     * @param string $sort sort by "id" (default) or "label"
      * @return array
      */
-    public function getProjects() {
+    public function getProjects($sort = 'id')
+    {
         $aReturn = array();
         foreach (glob(dirname($this->_getConfigFile("dummy")) . "/*.json") as $filename) {
             $aReturn[] = str_replace(".json", "", basename($filename));
         }
-        sort($aReturn);
+        if ($sort == "label") {
+            $aProjectLabels = [];
+            foreach ($aReturn as $sPrj) {
+                $oPrj = new project($sPrj);
+                $aProjectLabels[strtolower($oPrj->getLabel() . '-' . $sPrj)] = [
+                    'id' => $sPrj,
+                    'label' => $oPrj->getLabel(),
+                    'description' => $oPrj->getDescription(),
+                ];
+            }
+            ksort($aProjectLabels);
+            return array_values($aProjectLabels);
+        }
+        if ($sort == "id") {
+            sort($aReturn);
+        }
         return $aReturn;
     }
 
@@ -1074,19 +1132,21 @@ class project extends base {
      * @param type $sPhase
      * @return type
      */
-    public function isActivePhase($sPhase) {
+    public function isActivePhase($sPhase)
+    {
         return (
-                $this->_aPrjConfig && isset($this->_aPrjConfig["phases"][$sPhase]["active"][0])
-                    ? $this->_aPrjConfig["phases"][$sPhase]["active"][0] 
-                    : false
-                );
+            $this->_aPrjConfig && isset($this->_aPrjConfig["phases"][$sPhase]["active"][0])
+            ? $this->_aPrjConfig["phases"][$sPhase]["active"][0]
+            : false
+        );
     }
 
     /**
      * return array of all (active and inactive) phases
      * @return array
      */
-    public function getPhases() {
+    public function getPhases()
+    {
         return $this->_aConfig["phases"];
     }
 
@@ -1094,14 +1154,16 @@ class project extends base {
      * return array of all (active and inactive) phases
      * @return array
      */
-    public function getPlaces() {
+    public function getPlaces()
+    {
         return $this->_aPlaces;
     }
     /**
      * get a flat array with active phases of the project
      * @return array
      */
-    public function getActivePhases() {
+    public function getActivePhases()
+    {
         $aReturn = array();
         foreach (array_keys($this->_aConfig["phases"]) as $s) {
             if ($this->isActivePhase($s)) {
@@ -1115,7 +1177,8 @@ class project extends base {
      * find the next active phase of a project
      * @param string $sPhase current phase; if empty the function sends back the first phase
      */
-    public function getNextPhase($sPhase = false) {
+    public function getNextPhase($sPhase = false)
+    {
         if ($sPhase) {
             if (!array_key_exists($sPhase, $this->_aConfig["phases"])) {
                 die(sprintf(t("class-project-error-wrong-phase"), $sPhase));
@@ -1146,7 +1209,8 @@ class project extends base {
           'hasQueue'=>is there a package in a queue (waiting for deployment time to get ready to be installed)
      * @return array
      */
-    public function getProgress(){
+    public function getProgress()
+    {
         $this->getAllPhaseInfos();
         return $this->_aData['progress'];
     }
@@ -1154,8 +1218,10 @@ class project extends base {
      * check: is the deployment to the next phase enabled for this phase?
      * @param type $sPhase  current phase
      */
-    public function canAcceptPhase($sPhase = false) {
-        if (!$this->oUser->hasPermission("project-action-accept") && !$this->oUser->hasPermission("project-action-accept-$sPhase")
+    public function canAcceptPhase($sPhase = false)
+    {
+        if (
+            !$this->oUser->hasPermission("project-action-accept") && !$this->oUser->hasPermission("project-action-accept-$sPhase")
         ) {
             // echo $this->oUser->showDenied();
             return '<span class="btn" title="no permission [project-action-accept] for user [' . $this->oUser->getUsername() . ']">' . $sPhase . '</span>';
@@ -1192,7 +1258,7 @@ class project extends base {
         // array key "ok" must be in the ready2install and deployed info
         // and a version must be installed
         if (
-                array_key_exists($sPhase, $this->_aData["phases"]) && array_key_exists("onhold", $this->_aData["phases"][$sPhase]) && array_key_exists("ready2install", $this->_aData["phases"][$sPhase]) && array_key_exists("deployed", $this->_aData["phases"][$sPhase]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["onhold"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["ready2install"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["deployed"]) && array_key_exists("version", $this->_aData["phases"][$sPhase]["deployed"])
+            array_key_exists($sPhase, $this->_aData["phases"]) && array_key_exists("onhold", $this->_aData["phases"][$sPhase]) && array_key_exists("ready2install", $this->_aData["phases"][$sPhase]) && array_key_exists("deployed", $this->_aData["phases"][$sPhase]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["onhold"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["ready2install"]) && array_key_exists("ok", $this->_aData["phases"][$sPhase]["deployed"]) && array_key_exists("version", $this->_aData["phases"][$sPhase]["deployed"])
         ) {
             return true;
         }
@@ -1204,7 +1270,8 @@ class project extends base {
      * @param bool $bIgnoreCache  flag to ignore exiting cached data
      * @return array|boolean
      */
-    public function getRemoteBranches($bIgnoreCache=false) {
+    public function getRemoteBranches($bIgnoreCache = false)
+    {
         $this->log(__FUNCTION__ . "($bIgnoreCache) start");
         $this->_initVcs();
         if ($this->_oVcs) {
@@ -1224,7 +1291,8 @@ class project extends base {
      * @param boolean  $bRefresh  optional: refresh data; default: use cache
      * @return array
      */
-    public function getRepoRevision($bRefresh = false) {
+    public function getRepoRevision($bRefresh = false)
+    {
         $this->log(__FUNCTION__ . "($bRefresh) start");
 
         if (!$this->_aPrjConfig["build"]["type"]) {
@@ -1239,7 +1307,7 @@ class project extends base {
                 );
             }
         }
-        $this->log(__FUNCTION__ . " result:<pre>".print_r($this->_aData, 1)."</pre>");
+        $this->log(__FUNCTION__ . " result:<pre>" . print_r($this->_aData, 1) . "</pre>");
         return $this->_aData["phases"]["source"];
     }
 
@@ -1247,7 +1315,8 @@ class project extends base {
      * init version control system (git, ...)
      * @return vcs-object
      */
-    protected function _initVcs() {
+    protected function _initVcs()
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->_oVcs) {
             if (!$this->_aPrjConfig["build"]["type"]) {
@@ -1280,33 +1349,36 @@ class project extends base {
      * @param string  $sSection  one of false|"rollout"|...
      * @return array
      */
-    public function getConfiguredPlugins($sSection=false){
-        $aReturn=array();
-        if(!$sSection){
-            $aReturn=$this->_aConfig["plugins"];
+    public function getConfiguredPlugins($sSection = false)
+    {
+        $aReturn = array();
+        if (!$sSection) {
+            $aReturn = $this->_aConfig["plugins"];
         } else {
-            foreach ($this->_aConfig["plugins"][$sSection] as $sPluginName=>$aItem) {
+            foreach ($this->_aConfig["plugins"][$sSection] as $sPluginName => $aItem) {
                 $aReturn[$sPluginName] = $aItem;
             }
         }
         return $aReturn;
     }
-    
+
     /**
      * get a location of a plugin file with full path
      * @param string  $sType         type of plugin, i.e. "rollout"
      * @param string  $sPluginName   Name of plugin
      * @return string
      */
-    protected function _getPluginFilename($sType, $sPluginName){
-        return __DIR__.'/../plugins/'.$sType.'/'.$sPluginName.'/'.$sType.'_'.$sPluginName.'.php';
+    protected function _getPluginFilename($sType, $sPluginName)
+    {
+        return __DIR__ . '/../plugins/' . $sType . '/' . $sPluginName . '/' . $sType . '_' . $sPluginName . '.php';
     }
-    
+
     /**
      * get a flat array of all existing ssh keys
      * @return array
      */
-    protected function _getSshKeys() {
+    protected function _getSshKeys()
+    {
         $aReturn = array();
         foreach (glob($this->_aConfig["dataDir"] . "/sshkeys/*.pub") as $filename) {
             $aReturn[] = str_replace(".pub", "", basename($filename));
@@ -1320,7 +1392,8 @@ class project extends base {
      * @param string $sPhase  phase
      * @return array
      */
-    protected function _getDeploytimes($sPhase) {
+    protected function _getDeploytimes($sPhase)
+    {
         if (!$this->isActivePhase($sPhase)) {
             $sError = sprintf(t("class-project-warning-phase-not-active"), $sPhase);
             $this->_logaction($sError, __FUNCTION__, "error");
@@ -1330,7 +1403,8 @@ class project extends base {
         if (array_key_exists("deploytimes", $this->_aConfig["phases"][$sPhase])) {
             $aDeploytimes = $this->_aConfig["phases"][$sPhase]["deploytimes"];
         }
-        if (array_key_exists("deploytimes", $this->_aPrjConfig["phases"][$sPhase]) && $this->_aPrjConfig["phases"][$sPhase]["deploytimes"]
+        if (
+            array_key_exists("deploytimes", $this->_aPrjConfig["phases"][$sPhase]) && $this->_aPrjConfig["phases"][$sPhase]["deploytimes"]
         ) {
             $aDeploytimes = array($this->_aPrjConfig["phases"][$sPhase]["deploytimes"]);
         }
@@ -1341,7 +1415,8 @@ class project extends base {
     // SETTER
     // ----------------------------------------------------------------------
 
-    protected function _setProcessOutFile($sNewTempfile = false) {
+    protected function _setProcessOutFile($sNewTempfile = false)
+    {
         if ($this->_sProcessTempOut && file_exists($this->_sProcessTempOut)) {
             unlink($this->_sProcessTempOut);
         }
@@ -1356,13 +1431,16 @@ class project extends base {
      * 
      * @return array
      */
-    protected function _ldapProjectSearch($sSearchFilter) {
+    protected function _ldapProjectSearch($sSearchFilter)
+    {
         $aReturn = array();
         require_once("ldap.class.php");
         $oLdapIML = new imlldap($this->_aConfig['projects']['ldap']);
         // $oLdapIML->debugOn();
         $aResultsIml = $oLdapIML->searchDn(
-                $this->_aConfig['projects']['ldap']['DnProjects'], $sSearchFilter, array("*")
+            $this->_aConfig['projects']['ldap']['DnProjects'],
+            $sSearchFilter,
+            array("*")
         );
         if (!$aResultsIml['count']) {
             return false;
@@ -1392,9 +1470,10 @@ class project extends base {
      * load config of a project
      * @return boolean
      */
-    public function setProjectById($sId) {
+    public function setProjectById($sId)
+    {
         if ($sId !== preg_replace('/[^a-z0-9\-\_]/i', '', $sId)) {
-            $this->_errors[]=sprintf(t("class-project-error-config-wrongid"), htmlentities($sId));
+            $this->_errors[] = sprintf(t("class-project-error-config-wrongid"), htmlentities($sId));
             return false;
         }
         $this->_aPrjConfig = [];
@@ -1402,13 +1481,13 @@ class project extends base {
         $this->_errors = [];
 
         if (isset($this->_aConfig['projects']['json']['active']) && $this->_aConfig['projects']['json']['active']) {
-            $sCfgfile=$this->_getConfigFile($sId);
-            if (!$sCfgfile || !file_exists($sCfgfile)){
+            $sCfgfile = $this->_getConfigFile($sId);
+            if (!$sCfgfile || !file_exists($sCfgfile)) {
                 return false;
             }
-            $_aPrjConfigTmp=json_decode(file_get_contents($this->_getConfigFile($sId)), true);
-            if(!$_aPrjConfigTmp){
-                $this->_errors[]=sprintf(t("class-project-error-config-invalid"), $sId, $this->_getConfigFile($sId));
+            $_aPrjConfigTmp = json_decode(file_get_contents($this->_getConfigFile($sId)), true);
+            if (!$_aPrjConfigTmp) {
+                $this->_errors[] = sprintf(t("class-project-error-config-invalid"), $sId, $this->_getConfigFile($sId));
                 return false;
             }
             $this->_aPrjConfig = $_aPrjConfigTmp;
@@ -1418,7 +1497,8 @@ class project extends base {
             $sQuery = '(&(objectclass=hieraSource)(documentIdentifier=' . $sId . '))';
             $aResult = $this->_ldapProjectSearch($sQuery);
             // echo '<pre>$aResult = ' . print_r($aResult, 1) . '</pre>';
-            if (is_array($aResult) && $aResult[0] && array_key_exists('hieradata', $aResult[0])
+            if (
+                is_array($aResult) && $aResult[0] && array_key_exists('hieradata', $aResult[0])
             ) {
                 foreach ($aResult[0]['hieradata'] as $sLine) {
                     // echo $sLine.'<br>';
@@ -1436,27 +1516,25 @@ class project extends base {
         // echo "<pre>" . print_r($aData, true) . "</pre>";
 
         $this->_verifyConfig();
-        
+
         // ----- init rollout plugin
         // set name of the activated plugin for this project
-        $sPluginName=(isset($this->_aPrjConfig['deploy']['enabled_rollout_plugin']) && $this->_aPrjConfig['deploy']['enabled_rollout_plugin']) 
-                ? $this->_aPrjConfig['deploy']['enabled_rollout_plugin']
-                : 'default'
-            ;
+        $sPluginName = (isset($this->_aPrjConfig['deploy']['enabled_rollout_plugin']) && $this->_aPrjConfig['deploy']['enabled_rollout_plugin'])
+            ? $this->_aPrjConfig['deploy']['enabled_rollout_plugin']
+            : 'default';
         $this->oRolloutPlugin = false;
-        try{
+        try {
             require_once $this->_getPluginFilename('rollout', $sPluginName);
-            $sPluginClassname='rollout_'.$sPluginName;
+            $sPluginClassname = 'rollout_' . $sPluginName;
             $this->oRolloutPlugin = new $sPluginClassname(array(
-                'lang'=>$this->_aConfig['lang'],
-                'phase'=>false,
-                'globalcfg'=>isset($this->_aConfig['plugins']['rollout'][$sPluginName]) ? $this->_aConfig['plugins']['rollout'][$sPluginName] : [],
-                'projectcfg'=>$this->_aPrjConfig,
+                'lang' => $this->_aConfig['lang'],
+                'phase' => false,
+                'globalcfg' => isset($this->_aConfig['plugins']['rollout'][$sPluginName]) ? $this->_aConfig['plugins']['rollout'][$sPluginName] : [],
+                'projectcfg' => $this->_aPrjConfig,
             ));
             // print_r($this->_oRolloutPlugin->getPluginfos());
             // print_r($this->_oRolloutPlugin->getName());
         } catch (Exception $ex) {
-            
         }
         return true;
     }
@@ -1466,7 +1544,8 @@ class project extends base {
      * @param string $sBranchname name of the branch, i.e. "origin/master"
      * @return bool
      */
-    public function setBranchname($sBranchname) {
+    public function setBranchname($sBranchname)
+    {
         $this->_sBranchname = $sBranchname;
         if ($this->_oVcs) {
             if (method_exists($this->_oVcs, "setCurrentBranch")) {
@@ -1475,7 +1554,7 @@ class project extends base {
         }
         return $this->_sBranchname;
     }
-        
+
     // ----------------------------------------------------------------------
     // ACTIONS
     // ----------------------------------------------------------------------
@@ -1486,26 +1565,27 @@ class project extends base {
      * @param type $sData
      * @return boolean
      */
-    protected function _TempFill($sData, $aActions = array()) {
+    protected function _TempFill($sData, $aActions = array())
+    {
         if (!$this->_sProcessTempOut) {
             return false;
         }
         $sActions = '';
         if (count($aActions)) {
             for ($i = 0; $i < count($aActions["actions"]); $i++) {
-                $sActions.='<li';
+                $sActions .= '<li';
                 if ($i == $aActions["iActive"]) {
-                    $sActions.=' class="active"';
+                    $sActions .= ' class="active"';
                 }
-                $sActions.='>' . $aActions["actions"][$i]['label'] . '</li>';
+                $sActions .= '>' . $aActions["actions"][$i]['label'] . '</li>';
             }
             if ($sActions) {
                 $sData = '<div style="float: right; background: #f8f8f8; padding: 1em;">'
-                        . '<strong>' . $aActions["label"] . '</strong>'
-                        . '<ol class="actions">'
-                        . $sActions
-                        . '</ol></div>'
-                        . $sData;
+                    . '<strong>' . $aActions["label"] . '</strong>'
+                    . '<ol class="actions">'
+                    . $sActions
+                    . '</ol></div>'
+                    . $sData;
             }
         }
         return file_put_contents($this->_sProcessTempOut, $sData);
@@ -1517,13 +1597,14 @@ class project extends base {
      * @param string  $sTempDir  optional; target dir to copy; default=false (=delete file)
      * @return boolean
      */
-    protected function _TempDelete($sTempDir=false) {
-        if (!$this->_sProcessTempOut){
+    protected function _TempDelete($sTempDir = false)
+    {
+        if (!$this->_sProcessTempOut) {
             return false;
         }
         if (file_exists($this->_sProcessTempOut)) {
-            if ($sTempDir && is_dir($sTempDir)){
-                $sKeepOutfile=$sTempDir.'/_output.html';
+            if ($sTempDir && is_dir($sTempDir)) {
+                $sKeepOutfile = $sTempDir . '/_output.html';
                 copy($this->_sProcessTempOut, $sKeepOutfile);
             }
             unlink($this->_sProcessTempOut);
@@ -1536,13 +1617,14 @@ class project extends base {
      * @param bool  $bReturnMasterIfEmpty  flag: if there is no current branch then detect a master branch
      * @return string
      */
-    public function getBranchname($bReturnMasterIfEmpty=false) {
+    public function getBranchname($bReturnMasterIfEmpty = false)
+    {
         $this->log(__FUNCTION__ . " start");
         $this->_initVcs();
         if ($this->_oVcs) {
             if (method_exists($this->_oVcs, "getCurrentBranch")) {
-                $sCurrentBranch=$this->_oVcs->getCurrentBranch(true); // true means search for master branch if empty
-                if($sCurrentBranch){
+                $sCurrentBranch = $this->_oVcs->getCurrentBranch(true); // true means search for master branch if empty
+                if ($sCurrentBranch) {
                     $this->setBranchname($sCurrentBranch);
                     return $sCurrentBranch;
                 }
@@ -1558,7 +1640,8 @@ class project extends base {
      * @global type $aParams
      * @return boolean|string
      */
-    public function build($sTmpFile = false) {
+    public function build($sTmpFile = false)
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-build")) {
             return $this->oUser->showDenied();
@@ -1595,9 +1678,9 @@ class project extends base {
         // --------------------------------------------------
         $aDirs = $this->cleanupBuilds();
         if (count($aDirs)) {
-            $sReturn.='<h3>' . t('class-project-build-label-cleanup-builds') . '</h3><pre>' . print_r($aDirs, true) . '</pre>';
+            $sReturn .= '<h3>' . t('class-project-build-label-cleanup-builds') . '</h3><pre>' . print_r($aDirs, true) . '</pre>';
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         $this->_initVcs();
@@ -1618,11 +1701,11 @@ class project extends base {
             return false;
         }
 
-        $sReturn.='<h3>' . t('class-project-build-label-create-workdir') . '</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-create-workdir') . '</h3>';
         if (!file_exists($sTempBuildDir)) {
-            $sReturn.=$this->_execAndSend("mkdir -p " . $sTempBuildDir);
+            $sReturn .= $this->_execAndSend("mkdir -p " . $sTempBuildDir);
         }
-        $sReturn.=$this->_execAndSend("ls -ld " . $sTempBuildDir);
+        $sReturn .= $this->_execAndSend("ls -ld " . $sTempBuildDir);
         if (!file_exists($sTempBuildDir)) {
             $this->_TempDelete();
             $sError = sprintf(t('"class-project-error-build-dir-was-not-created"'), $sTempBuildDir);
@@ -1630,58 +1713,58 @@ class project extends base {
             return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
         // $this->_iRcAll = 0;
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         // --------------------------------------------------
         // checkout
         // --------------------------------------------------
-        $sReturn.='<h3>' . t('class-project-build-label-get-sources-from-version-control') . '</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-get-sources-from-version-control') . '</h3>';
 
-        $sReturn.='<pre>' . $this->_oVcs->getSources($sTempBuildDir) . '</pre>';
+        $sReturn .= '<pre>' . $this->_oVcs->getSources($sTempBuildDir) . '</pre>';
 
         $aVersion = $this->_oVcs->getRevision($sTempBuildDir);
         $sRevision = $aVersion["revision"];
         $sCommitMsg = $aVersion["message"];
         $sCommitMsg = str_replace("\n", "<br>", $sCommitMsg);
         $sCommitMsg = str_replace('"', "&quot;", $sCommitMsg);
-        $sReturn.=$this->_oHtml->getBox("info", $sCommitMsg);
+        $sReturn .= $this->_oHtml->getBox("info", $sCommitMsg);
 
-        $sReturn.=$this->_execAndSend("ls -lisa $sTempBuildDir");
+        $sReturn .= $this->_execAndSend("ls -lisa $sTempBuildDir");
 
         if (!$this->_iRcAll == 0) {
             $sError = sprintf(t('class-project-error-command-failed'), $sTempBuildDir);
             $this->_logaction($sError, __FUNCTION__, "error");
-            $this->_TempFill($sError.$sReturn, $aActionList);
+            $this->_TempFill($sError . $sReturn, $aActionList);
             $this->_TempDelete($sTempBuildDir);
-            return $this->_oHtml->getBox("error", $sError.$sReturn);
+            return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
 
         // --------------------------------------------------
         foreach (glob($sTempBuildDir . '/hooks/on*') as $filename) {
-            $sReturn.='chmod 755 ' . $filename . '<br>';
-            $sReturn.=$this->_execAndSend('chmod 755 ' . $filename);
-            $sReturn.=$this->_execAndSend('ls -l ' . $filename);
+            $sReturn .= 'chmod 755 ' . $filename . '<br>';
+            $sReturn .= $this->_execAndSend('chmod 755 ' . $filename);
+            $sReturn .= $this->_execAndSend('ls -l ' . $filename);
         }
         // --------------------------------------------------
-        $sCfgout=$sTempBuildDir . '/ci-custom-vars';
-        if (isset($this->_aPrjConfig['deploy']["configfile"]) && $this->_aPrjConfig['deploy']["configfile"]){
-                        
+        $sCfgout = $sTempBuildDir . '/ci-custom-vars';
+        if (isset($this->_aPrjConfig['deploy']["configfile"]) && $this->_aPrjConfig['deploy']["configfile"]) {
+
             # task#5047 - FIX EOL
-            $sCfgContent=$this->_aPrjConfig['deploy']["configfile"];
+            $sCfgContent = $this->_aPrjConfig['deploy']["configfile"];
             // detect unix, linux, mac
             if (DIRECTORY_SEPARATOR === '/') {
-                $sCfgContent=str_replace("\r\n", "\n", $sCfgContent);
+                $sCfgContent = str_replace("\r\n", "\n", $sCfgContent);
             }
             # /task#5047
-            
+
             file_put_contents($sCfgout, $sCfgContent);
-            $sReturn.=$this->_execAndSend('ls -l ' . $sCfgout);
-            $sReturn.=$this->_execAndSend('cat ' . $sCfgout);
+            $sReturn .= $this->_execAndSend('ls -l ' . $sCfgout);
+            $sReturn .= $this->_execAndSend('cat ' . $sCfgout);
         }
 
-        $sReturn.=$this->_oHtml->getBox("success", t('class-project-info-build-checkout-ok'));
-        $aActionList['iActive'] ++;
+        $sReturn .= $this->_oHtml->getBox("success", t('class-project-info-build-checkout-ok'));
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
@@ -1689,76 +1772,75 @@ class project extends base {
         // execute hook postclone
         // --------------------------------------------------
         // task#1726 - add environment
-        $sSetEnv=''
-                . 'export GIT_SSH="'.$this->_aConfig['appRootDir'].'/shellscripts/gitsshwrapper.sh";'
-                . 'export DIR_SSH_KEYS="'.$this->_aConfig['dataDir'].'/sshkeys";'
-                . 'export DIR_APPROOT="'.$sTempBuildDir.'";'
-                . 'export NVMINIT="'.$this->_aConfig['appRootDir'].'/shellscripts/nvm_init.sh";'
-                . (isset($this->_aConfig['build']['env']) ? $this->_aConfig['build']['env'] : '')
-                ;
-        
+        $sSetEnv = ''
+            . 'export GIT_SSH="' . $this->_aConfig['appRootDir'] . '/shellscripts/gitsshwrapper.sh";'
+            . 'export DIR_SSH_KEYS="' . $this->_aConfig['dataDir'] . '/sshkeys";'
+            . 'export DIR_APPROOT="' . $sTempBuildDir . '";'
+            . 'export NVMINIT="' . $this->_aConfig['appRootDir'] . '/shellscripts/nvm_init.sh";'
+            . (isset($this->_aConfig['build']['env']) ? $this->_aConfig['build']['env'] : '');
+
         $sHookfile = $this->_aConfig['build']['hooks']['build-postclone'];
-        $sReturn.='<h3>' . t('class-project-build-label-execute-hook-postclone') . ' (' . $sHookfile . ')</h3>';
-        
+        $sReturn .= '<h3>' . t('class-project-build-label-execute-hook-postclone') . ' (' . $sHookfile . ')</h3>';
+
         if (file_exists($sTempBuildDir . '/' . $sHookfile)) {
             // $sReturn.=$this->_execAndSend('chmod 755 ' . $sTempDir . '/hooks/on*');
             // $this->_iRcAll = 0;
-            $sReturn.=$this->_execAndSend('bash --login -c \'' . $sSetEnv.' '.$sTempBuildDir . '/' . $sHookfile . '\'');
+            $sReturn .= $this->_execAndSend('bash --login -c \'' . $sSetEnv . ' ' . $sTempBuildDir . '/' . $sHookfile . '\'');
             if (!$this->_iRcAll == 0) {
                 $sError = sprintf(t('class-project-error-command-failed'), $sTempBuildDir);
                 $this->_logaction($sError, __FUNCTION__, "error");
-                $this->_TempFill($sError.$sReturn, $aActionList);
+                $this->_TempFill($sError . $sReturn, $aActionList);
                 $this->_TempDelete($sTempBuildDir);
                 return $this->_oHtml->getBox("error", $sError . $sReturn);
             }
         } else {
-            $sReturn.=t('skip') . '<br>';
+            $sReturn .= t('skip') . '<br>';
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
         // --------------------------------------------------
         // copy default structure
         // --------------------------------------------------
-        $sReturn.='<h3>' . t('class-project-build-label-copy-default-structure') . '</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-copy-default-structure') . '</h3>';
         if ($this->_getDefaultsDir()) {
-            $sReturn.=$this->_execAndSend("find " . $this->_getDefaultsDir() . " | head -15");
-            $sReturn.=$this->_execAndSend("rsync -r " . $this->_getDefaultsDir() . "/* $sTempBuildDir");
+            $sReturn .= $this->_execAndSend("find " . $this->_getDefaultsDir() . " | head -15");
+            $sReturn .= $this->_execAndSend("rsync -r " . $this->_getDefaultsDir() . "/* $sTempBuildDir");
             // $sReturn.=$this->_execAndSend("find $sTempDir");
         } else {
-            $sReturn.=t('skip') . '<br>';
+            $sReturn .= t('skip') . '<br>';
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         // --------------------------------------------------
         // execute hook
         // --------------------------------------------------
         $sHookfile = $this->_aConfig['build']['hooks']['build-precompress'];
-        $sReturn.='<h3>' . t('class-project-build-label-execute-hook-precompress') . ' (' . $sHookfile . ')</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-execute-hook-precompress') . ' (' . $sHookfile . ')</h3>';
         if (file_exists($sTempBuildDir . '/' . $sHookfile)) {
             // $sReturn.=$this->_execAndSend('chmod 755 ' . $sTempDir . '/hooks/on*');
             // $this->_iRcAll = 0;
-            $sReturn.=$this->_execAndSend('bash --login -c \'' . $sSetEnv.' '.$sTempBuildDir . '/' . $sHookfile . '\'');
+            $sReturn .= $this->_execAndSend('bash --login -c \'' . $sSetEnv . ' ' . $sTempBuildDir . '/' . $sHookfile . '\'');
             if (!$this->_iRcAll == 0) {
                 $sError = sprintf(t('class-project-error-command-failed'), $sTempBuildDir);
                 $this->_logaction($sError, __FUNCTION__, "error");
-                $this->_TempFill($sError.$sReturn, $aActionList);
+                $this->_TempFill($sError . $sReturn, $aActionList);
                 $this->_TempDelete($sTempBuildDir);
                 return $this->_oHtml->getBox("error", $sError . $sReturn);
             }
         } else {
-            $sReturn.=t('skip') . '<br>';
+            $sReturn .= t('skip') . '<br>';
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
         // --------------------------------------------------
         // cleanup .git, .svn, ...
         // --------------------------------------------------
-        $sReturn.='<h3>' . t('class-project-build-label-cleanup-project') . '</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-cleanup-project') . '</h3>';
         if ($this->_oVcs) {
             $this->_oVcs->cleanupWorkdir($sTempBuildDir);
         }
@@ -1766,17 +1848,18 @@ class project extends base {
         // $sReturn.=$this->_execAndSend("cd $sTempDir && rm -rf .git");
         // $sReturn.=$this->_execAndSend("cd $sTempDir && rm -rf .svn");
         // $sReturn.=$this->_execAndSend("find  $sTempDir -type d -name '.svn' -exec rm -rf {} \;");
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         // --------------------------------------------------
         // create package
         // --------------------------------------------------
-        $sReturn.='<h3>' . t('class-project-build-label-create-package') . '</h3>';
+        $sReturn .= '<h3>' . t('class-project-build-label-create-package') . '</h3>';
         // public_html must exist
-        if (array_key_exists('haspublic', $this->_aPrjConfig["build"])
-                && $this->_aPrjConfig["build"]["haspublic"][0]
-        ){
+        if (
+            array_key_exists('haspublic', $this->_aPrjConfig["build"])
+            && $this->_aPrjConfig["build"]["haspublic"][0]
+        ) {
             $sWebroot = false;
             $sWebroot1 = $sTempBuildDir . '/public_html';
             $sWebroot2 = $sTempBuildDir . '/public';
@@ -1790,7 +1873,7 @@ class project extends base {
             if (!$sWebroot) {
                 $sError = t('class-project-error-build-docroot-not-found');
                 $this->_logaction($sError, __FUNCTION__, "error");
-                $this->_TempFill($sError.$sReturn, $aActionList);
+                $this->_TempFill($sError . $sReturn, $aActionList);
                 $this->_TempDelete($sTempBuildDir);
                 return $this->_oHtml->getBox("error", $sError . $sReturn . $sError);
             }
@@ -1798,7 +1881,7 @@ class project extends base {
         if (!$this->_iRcAll == 0) {
             $sError = sprintf(t('class-project-error-command-failed'), $sTempBuildDir);
             $this->_logaction($sError, __FUNCTION__, "error");
-            $this->_TempFill($sError.$sReturn, $aActionList);
+            $this->_TempFill($sError . $sReturn, $aActionList);
             $this->_TempDelete($sTempBuildDir);
             return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
@@ -1833,22 +1916,22 @@ class project extends base {
           "remark": "' . $aParams["inputComment"] . '"
          */
 
-        $sReturn.=t("class-project-info-build-write-meta-to-webroot") . "<br>";
+        $sReturn .= t("class-project-info-build-write-meta-to-webroot") . "<br>";
         // file_put_contents($sInfoFileWebroot, $sInfos);
         file_put_contents($sInfoFileWebroot, json_encode($aInfos));
-        $sReturn.=$this->_execAndSend("ls -l $sInfoFileWebroot");
-        $sReturn.=$this->_execAndSend("cat $sInfoFileWebroot");
+        $sReturn .= $this->_execAndSend("ls -l $sInfoFileWebroot");
+        $sReturn .= $this->_execAndSend("cat $sInfoFileWebroot");
 
         if (!file_exists(dirname($sPackageFileArchiv))) {
-            $sReturn.=sprintf(t("creating-directory"), dirname($sPackageFileArchiv)) . "<br>";
+            $sReturn .= sprintf(t("creating-directory"), dirname($sPackageFileArchiv)) . "<br>";
             mkdir(dirname($sPackageFileArchiv), 0775, true);
         }
-        $sReturn.=$this->_execAndSend("ls -ld " . dirname($sPackageFileArchiv));
+        $sReturn .= $this->_execAndSend("ls -ld " . dirname($sPackageFileArchiv));
         if (!file_exists(dirname($sPackageFileArchiv))) {
-            
+
             $sError = sprintf(t('"class-project-error-build-dir-was-not-created"'), $sTempBuildDir);
             $this->_logaction($sError, __FUNCTION__, "error");
-            $this->_TempFill($sError.$sReturn, $aActionList);
+            $this->_TempFill($sError . $sReturn, $aActionList);
             $this->_TempDelete($sTempBuildDir);
             return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
@@ -1857,81 +1940,81 @@ class project extends base {
         // ----- loop over enabled build plugins
         // WIP
         // set name of the activated plugin for this project
-        $aPlugins=(isset($this->_aPrjConfig['build']['enabled_build_plugins']) && $this->_aPrjConfig['build']['enabled_build_plugins']) 
-                ? $this->_aPrjConfig['build']['enabled_build_plugins']
-                : ['tgz']
-            ;
-        foreach($aPlugins as $sPluginName){
+        $aPlugins = (isset($this->_aPrjConfig['build']['enabled_build_plugins']) && $this->_aPrjConfig['build']['enabled_build_plugins'])
+            ? $this->_aPrjConfig['build']['enabled_build_plugins']
+            : ['tgz'];
+        foreach ($aPlugins as $sPluginName) {
             $oPlugin = false;
-            $sReturn.='<h4>'.$sPluginName.'</h4>';
-            try{
+            $sReturn .= '<h4>' . $sPluginName . '</h4>';
+            try {
                 include_once $this->_getPluginFilename('build', $sPluginName);
-                $sPluginClassname='build_'.$sPluginName;
+                $sPluginClassname = 'build_' . $sPluginName;
                 $oPlugin = new $sPluginClassname(array(
-                    'lang'=>$this->_aConfig['lang'],
-                    'workdir'=>$sTempBuildDir,
-                    'outfile'=>$sPackageFileArchiv,
+                    'lang' => $this->_aConfig['lang'],
+                    'workdir' => $sTempBuildDir,
+                    'outfile' => $sPackageFileArchiv,
                 ));
             } catch (Exception $ex) {
-                return $this->_oHtml->getBox("error", 
-                    "FAILED to initialize build plugin " .$sPluginName .'<br>'
-                    . $sReturn
-                );                
+                return $this->_oHtml->getBox(
+                    "error",
+                    "FAILED to initialize build plugin " . $sPluginName . '<br>'
+                        . $sReturn
+                );
             }
-            
-            $sReturn.=sprintf(t("creating-file"), $oPlugin->getOutfile()) . "<br>";
-            foreach($oPlugin->checkRequirements() as $sCommand){
-                $sReturn.=$this->_execAndSend($sCommand);
+
+            $sReturn .= sprintf(t("creating-file"), $oPlugin->getOutfile()) . "<br>";
+            foreach ($oPlugin->checkRequirements() as $sCommand) {
+                $sReturn .= $this->_execAndSend($sCommand);
                 $this->_TempFill($sReturn, $aActionList);
             }
-            
-            foreach($oPlugin->getBuildCommands() as $sCommand){
-                $sReturn.=$this->_execAndSend($sCommand);
+
+            foreach ($oPlugin->getBuildCommands() as $sCommand) {
+                $sReturn .= $this->_execAndSend($sCommand);
                 $this->_TempFill($sReturn, $aActionList);
             }
         }
 
         // write info file (.json)
-        $sReturn.=sprintf(t("creating-file"), $sInfoFileArchiv) . "<br>";
+        $sReturn .= sprintf(t("creating-file"), $sInfoFileArchiv) . "<br>";
         // file_put_contents($sInfoFileArchiv, $sInfos);
         file_put_contents($sInfoFileArchiv, json_encode($aInfos));
 
         // copy template files
         if (file_exists($sTempBuildDir . '/hooks/templates/')) {
-            $sReturn.=t("class-project-info-build-write-templatefiles-to-archive") . "<br>";
-            $sReturn.=$this->_execAndSend("cp $sTempBuildDir/hooks/templates/* " . $this->_getArchiveDir($sTs2));
+            $sReturn .= t("class-project-info-build-write-templatefiles-to-archive") . "<br>";
+            $sReturn .= $this->_execAndSend("cp $sTempBuildDir/hooks/templates/* " . $this->_getArchiveDir($sTs2));
         } else {
-            $sReturn.=t("class-project-info-build-write-templatefiles-to-archive-skipped") . "<br>";
+            $sReturn .= t("class-project-info-build-write-templatefiles-to-archive-skipped") . "<br>";
         }
         $this->_TempFill($sReturn, $aActionList);
 
-        $sReturn.="<br>" . t("info") . ":<br>";
-        $sReturn.=$this->_execAndSend("ls -l " . $this->_getArchiveDir($sTs2));
+        $sReturn .= "<br>" . t("info") . ":<br>";
+        $sReturn .= $this->_execAndSend("ls -l " . $this->_getArchiveDir($sTs2));
 
         // TEST
         // $this->_iRcAll=1;
         if (!$this->_iRcAll == 0) {
             $sError = t('class-project-error-build-packaging-failed');
             $this->_logaction($sError, __FUNCTION__, "error");
-            $this->_TempFill($sError.$sReturn, $aActionList);
+            $this->_TempFill($sError . $sReturn, $aActionList);
             $this->_TempDelete($sTempBuildDir);
             return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
-        $sReturn.='<h3>' . t("class-project-build-label-remove-workdir") . '</h3>';
-        $sReturn.=$this->_execAndSend("rm -rf $sTempBuildDir");
-        $sReturn.=t("class-project-info-build-remove-oldest-archives");
-        $sReturn.='<pre>' . print_r($this->cleanupArchive(), true) . '</pre>';
+        $sReturn .= '<h3>' . t("class-project-build-label-remove-workdir") . '</h3>';
+        $sReturn .= $this->_execAndSend("rm -rf $sTempBuildDir");
+        $sReturn .= t("class-project-info-build-remove-oldest-archives");
+        $sReturn .= '<pre>' . print_r($this->cleanupArchive(), true) . '</pre>';
 
         $sInfo = t("class-project-info-build-successful");
         $this->_logaction(t('finished') . ' ' . $sInfo, __FUNCTION__, "success");
-        $sReturn.=$this->_oHtml->getBox("success", $sInfo);
-        $aActionList['iActive'] ++;
+        $sReturn .= $this->_oHtml->getBox("success", $sInfo);
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
-        $sReturn.=$this->queue($sFirstLevel, $sTs2);
+        $sReturn .= $this->queue($sFirstLevel, $sTs2);
         $this->_TempDelete();
         $this->_setProcessOutFile(false);
 
@@ -1945,7 +2028,8 @@ class project extends base {
      * @param string $sVersion  version 
      * @return string
      */
-    public function queue($sPhase, $sVersion) {
+    public function queue($sPhase, $sVersion)
+    {
         $aActionList = array(
             'iActive' => 0,
             'label' => t("queue"),
@@ -1983,7 +2067,7 @@ class project extends base {
         if (!file_exists($sLinkTarget)) {
             die(sprintf(t("class-project-error-queue-wrong-version"), $sVersion, $sLinkTarget));
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         // --------------------------------------------------
@@ -1991,20 +2075,20 @@ class project extends base {
         // --------------------------------------------------
         $this->_iRcAll = 0;
         if (file_exists($sLinkName)) {
-            $sReturn.=t("class-project-queue-label-remove-existing-version") . "<br>";
-            $sReturn.=$this->_execAndSend("rm -f $sLinkName");
+            $sReturn .= t("class-project-queue-label-remove-existing-version") . "<br>";
+            $sReturn .= $this->_execAndSend("rm -f $sLinkName");
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
         // --------------------------------------------------
         // create the new link
         // --------------------------------------------------
-        $sReturn.=t("class-project-queue-label-link-new-version") . "<br>";
+        $sReturn .= t("class-project-queue-label-link-new-version") . "<br>";
 
-        $sReturn.=$this->_execAndSend("ln -s $sLinkTarget $sLinkName");
-        $sReturn.=$this->_execAndSend("ls -l $sLinkName | fgrep $sLinkTarget");
-        $aActionList['iActive'] ++;
+        $sReturn .= $this->_execAndSend("ln -s $sLinkTarget $sLinkName");
+        $sReturn .= $this->_execAndSend("ls -l $sLinkName | fgrep $sLinkTarget");
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
@@ -2015,8 +2099,8 @@ class project extends base {
             return $this->_oHtml->getBox("error", $sError . $sReturn);
         }
         $this->_logaction(t('finished') . " queue($sPhase, $sVersion) " . t("class-project-info-queue-successful"), __FUNCTION__);
-        $sReturn.=$this->_oHtml->getBox("success", t("class-project-info-queue-successful"));
-        $sReturn.=$this->deploy($sPhase);
+        $sReturn .= $this->_oHtml->getBox("success", t("class-project-info-queue-successful"));
+        $sReturn .= $this->deploy($sPhase);
         $this->_TempDelete();
 
         return $sReturn;
@@ -2030,9 +2114,11 @@ class project extends base {
      * @param bool   $bIgnoreDeploytimes  flag; if true it will override time windows
      * @return boolean|string
      */
-    public function deploy($sPhase, $bIgnoreDeploytimes = false) {
+    public function deploy($sPhase, $bIgnoreDeploytimes = false)
+    {
         $this->log(__FUNCTION__ . " start");
-        if (!$this->oUser->hasPermission("project-action-deploy") && !$this->oUser->hasPermission("project-action-deploy-$sPhase")
+        if (
+            !$this->oUser->hasPermission("project-action-deploy") && !$this->oUser->hasPermission("project-action-deploy-$sPhase")
         ) {
             return $this->oUser->showDenied();
         }
@@ -2061,39 +2147,39 @@ class project extends base {
         // --------------------------------------------------
         // checks
         // --------------------------------------------------
-        $sReturn.="<h3>" . t("class-project-deploy-label-checks") . "</h3>";
+        $sReturn .= "<h3>" . t("class-project-deploy-label-checks") . "</h3>";
 
         $aDeploytimes = $this->_getDeploytimes($sPhase);
         if (count($aDeploytimes)) {
             // check if the a deploy time is reached
             $sNow = date("D H:i:s");
-            $sReturn.=sprintf(t("class-project-info-deploy-check-deployment-times"), $sNow) . "<br>";
+            $sReturn .= sprintf(t("class-project-info-deploy-check-deployment-times"), $sNow) . "<br>";
             $bCanDeploy = false;
             foreach ($aDeploytimes as $sRegex) {
-                $sReturn.=sprintf(t("class-project-info-deploy-test-regex"), $sRegex);
+                $sReturn .= sprintf(t("class-project-info-deploy-test-regex"), $sRegex);
 
                 if (preg_match($sRegex, $sNow)) {
-                    $sReturn.=t("ok");
+                    $sReturn .= t("ok");
                     $bCanDeploy = true;
                 } else {
-                    $sReturn.=t("no");
+                    $sReturn .= t("no");
                 }
-                $sReturn.="<br>";
+                $sReturn .= "<br>";
             }
             if (!$bCanDeploy) {
                 if (!$bIgnoreDeploytimes) {
                     $sError = t("class-project-info-deploy-time-not-reached");
                     // $this->_logaction($sError, __FUNCTION__);
-                    $sReturn.=$this->_oHtml->getBox("info", $sError);
+                    $sReturn .= $this->_oHtml->getBox("info", $sError);
                     $this->_TempDelete();
                     // removed: cronjob sends this message too
                     // $this->_sendMessage($sError."\n".t('phase').': '.$sPhase);
                     return $sReturn;
                 } else {
-                    $sReturn.=t("class-project-info-deploy-time-not-reached-and-ignored") . "<br>";
+                    $sReturn .= t("class-project-info-deploy-time-not-reached-and-ignored") . "<br>";
                 }
             } else {
-                $sReturn.=t("class-project-info-deploy-time-ok") . "<br>";
+                $sReturn .= t("class-project-info-deploy-time-ok") . "<br>";
             }
             // if ()
         }
@@ -2101,13 +2187,13 @@ class project extends base {
         if (!file_exists($sQueueLink)) {
             $sError = sprintf(t("class-project-info-deploy-nothing-in-queue"), $sQueueLink);
             $this->_logaction($sError, __FUNCTION__, "error");
-            $sReturn.=$this->_oHtml->getBox("info", $sError);
+            $sReturn .= $this->_oHtml->getBox("info", $sError);
             $this->_TempDelete();
-            $this->_sendMessage($sError."\n".t('phase').': '.$sPhase);
+            $this->_sendMessage($sError . "\n" . t('phase') . ': ' . $sPhase);
             return $sReturn;
         }
         $this->_TempFill($sReturn);
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
@@ -2116,24 +2202,24 @@ class project extends base {
         // --------------------------------------------------
         $this->_iRcAll = 0;
         if (file_exists($sRepoLink)) {
-            $sReturn.=t("class-project-info-deploy-removing-existing-version") . "<br>";
-            $sReturn.=$this->_execAndSend("rm -f $sRepoLink");
+            $sReturn .= t("class-project-info-deploy-removing-existing-version") . "<br>";
+            $sReturn .= $this->_execAndSend("rm -f $sRepoLink");
         }
         $this->_TempFill($sReturn);
-        $sReturn.=t("class-project-info-deploy-moving-queue-to-repo") . "<br>";
-        $sReturn.=$this->_execAndSend("mv $sQueueLink $sRepoLink");
+        $sReturn .= t("class-project-info-deploy-moving-queue-to-repo") . "<br>";
+        $sReturn .= $this->_execAndSend("mv $sQueueLink $sRepoLink");
 
 
         if (!$this->_iRcAll == 0) {
             $this->_TempDelete();
             $sError = t("class-project-error-command-failed");
             $this->_logaction($sError, __FUNCTION__, "error");
-            $sReturn.=$this->_oHtml->getBox("error", $sError . $sReturn);
-            $this->_sendMessage($sError."\n".t('phase').': '.$sPhase);
+            $sReturn .= $this->_oHtml->getBox("error", $sError . $sReturn);
+            $this->_sendMessage($sError . "\n" . t('phase') . ': ' . $sPhase);
             return $sReturn;
         }
 
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
@@ -2143,7 +2229,7 @@ class project extends base {
         // $sReturn.=$this->_execAndSend("ln -s $sLinkTarget $sLinkName");
         if (array_key_exists('mirrorPackages', $this->_aConfig) && count($this->_aConfig['mirrorPackages'])) {
             foreach ($this->_aConfig['mirrorPackages'] as $sLabel => $aTarget) {
-                $sReturn.='<h3>' . sprintf(t("class-project-info-deploy-synching-package"), $sLabel) . "</h3>";
+                $sReturn .= '<h3>' . sprintf(t("class-project-info-deploy-synching-package"), $sLabel) . "</h3>";
                 if (array_key_exists('type', $aTarget)) {
                     $sCmd = false;
                     // $sSource=$this->_aConfig["packageDir"]."/$sPhase/*";
@@ -2154,7 +2240,7 @@ class project extends base {
                             $sCmd = "ls -l $sSource 2>/dev/null && /usr/bin/rsync --delete -rLvt  $sSource $sTarget";
                             break;
                         default:
-                            $sReturn.=sprintf(t("class-project-info-deploy-skip-sync"), $aTarget['type']) . "<br>";
+                            $sReturn .= sprintf(t("class-project-info-deploy-skip-sync"), $aTarget['type']) . "<br>";
                             break;
                     } // switch
                     if ($sCmd) {
@@ -2164,13 +2250,13 @@ class project extends base {
                           }
                          * 
                          */
-                        $sReturn.=$this->_execAndSend($sCmd);
+                        $sReturn .= $this->_execAndSend($sCmd);
                         $this->_TempFill($sReturn);
                     }
                 }
             } // foreach
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
 
@@ -2180,20 +2266,19 @@ class project extends base {
         $sDeploymethod = array_key_exists("deploymethod", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["deploymethod"] : "none";
         // $sTargethosts = array_key_exists("hosts", $this->_aPrjConfig["phases"][$sPhase]) ? $this->_aPrjConfig["phases"][$sPhase]["hosts"] : '';
 
-        $sReturn.='<h3>' . t("class-project-info-deploy-start-by-method") . ' :: ' . $sDeploymethod . '</h3>'
-                . '<p>'
-                . t("deploymethod-$sDeploymethod") . '<br>'
-                // . t("phase-targethosts") . ': ' . ($sTargethosts ? $sTargethosts : t("none"))
-                . '</p>'
-        ;
+        $sReturn .= '<h3>' . t("class-project-info-deploy-start-by-method") . ' :: ' . $sDeploymethod . '</h3>'
+            . '<p>'
+            . t("deploymethod-$sDeploymethod") . '<br>'
+            // . t("phase-targethosts") . ': ' . ($sTargethosts ? $sTargethosts : t("none"))
+            . '</p>';
         if ($sDeploymethod === "none") {
-            $sReturn.=t("class-project-info-deploy-start-by-method-skip") . "<br>";
+            $sReturn .= t("class-project-info-deploy-start-by-method-skip") . "<br>";
         } else {
-            
-            $sReturn.='<p>Plugin: '.$this->oRolloutPlugin->getId().'</p>';
 
-            foreach($this->oRolloutPlugin->getDeployCommands($sPhase) as $sCmd){
-                $sReturn.=$this->_execAndSend("$sCmd");
+            $sReturn .= '<p>Plugin: ' . $this->oRolloutPlugin->getId() . '</p>';
+
+            foreach ($this->oRolloutPlugin->getDeployCommands($sPhase) as $sCmd) {
+                $sReturn .= $this->_execAndSend("$sCmd");
             }
 
             /*
@@ -2224,22 +2309,22 @@ class project extends base {
              * 
              */
         }
-        $aActionList['iActive'] ++;
+        $aActionList['iActive']++;
         $this->_TempFill($sReturn, $aActionList);
 
-        $sReturn.="<br>";
-        
+        $sReturn .= "<br>";
+
         if (!$this->_iRcAll == 0) {
-            $sWarnlevel='error';
+            $sWarnlevel = 'error';
             $sMessage = sprintf(t('class-project-info-deploy-failed'), $sPhase);
         } else {
-            $sWarnlevel='success';
-            $sMessage=sprintf(t("class-project-info-deploy-successful"), $sPhase);
+            $sWarnlevel = 'success';
+            $sMessage = sprintf(t("class-project-info-deploy-successful"), $sPhase);
         }
-        $sReturn.=$this->_oHtml->getBox($sWarnlevel, $sMessage);
+        $sReturn .= $this->_oHtml->getBox($sWarnlevel, $sMessage);
         $this->_sendMessage($sMessage);
         $this->_logaction(t('finished') . " deploy($sPhase, $bIgnoreDeploytimes) " . $sMessage, __FUNCTION__, $sWarnlevel);
-        
+
         $this->_TempDelete();
         return $sReturn;
     }
@@ -2250,9 +2335,11 @@ class project extends base {
      * @param string $sPhase which queue of which phase we want to install in server
      * @return type
      */
-    public function accept($sPhase) {
+    public function accept($sPhase)
+    {
         $this->log(__FUNCTION__ . " start");
-        if (!$this->oUser->hasPermission("project-action-accept") && !$this->oUser->hasPermission("project-action-accept-$sPhase")
+        if (
+            !$this->oUser->hasPermission("project-action-accept") && !$this->oUser->hasPermission("project-action-accept-$sPhase")
         ) {
             return $this->oUser->showDenied();
         }
@@ -2266,7 +2353,7 @@ class project extends base {
             return $sReturn . $this->_oHtml->getBox("error", $sError);
         }
 
-        $sReturn.="<h3>" . sprintf(t("class-project-info-accept-overview"), $sPhase) . "</h3>";
+        $sReturn .= "<h3>" . sprintf(t("class-project-info-accept-overview"), $sPhase) . "</h3>";
         $this->_TempFill($sReturn);
         $aInfos = $this->getPhaseInfos($sPhase);
         $sVersion = $aInfos["deployed"]["version"];
@@ -2274,9 +2361,9 @@ class project extends base {
 
 
         // $sReturn.='<pre>' . print_r($aInfos["deployed"], true) . '</pre>';
-        $sReturn.=$this->_oHtml->getBox("info", sprintf(t("class-project-info-accept-version-and-next-phase"), $sVersion, $sNext));
+        $sReturn .= $this->_oHtml->getBox("info", sprintf(t("class-project-info-accept-version-and-next-phase"), $sVersion, $sNext));
         $this->_logaction(t('finished') . " accept($sPhase) " . sprintf(t("class-project-info-accept-version-and-next-phase"), $sVersion, $sNext), __FUNCTION__, "success");
-        $sReturn.=$this->queue($sNext, $sVersion);
+        $sReturn .= $this->queue($sNext, $sVersion);
         $this->_TempFill($sReturn);
         $this->_TempDelete();
 
@@ -2287,7 +2374,8 @@ class project extends base {
      * save POSTed data as project config
      * @return boolean
      */
-    public function saveConfig($aData = false) {
+    public function saveConfig($aData = false)
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-setup")) {
             return $this->oUser->showDenied();
@@ -2368,9 +2456,9 @@ class project extends base {
         $this->_logaction(t('finished') . " saveConfig(...)", __FUNCTION__, "success");
         $this->setProjectById($sId);
 
-        $sMessage=($bReturn 
-                ? t("page-setup-info-settings-were-saved")
-                : t("page-setup-error-settings-were-not-saved")
+        $sMessage = ($bReturn
+            ? t("page-setup-info-settings-were-saved")
+            : t("page-setup-error-settings-were-not-saved")
         );
         $this->_sendMessage($sMessage);
         return $bReturn;
@@ -2382,7 +2470,8 @@ class project extends base {
      * @param string  $sId  id
      * @return string
      */
-    public function create($sId) {
+    public function create($sId)
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-create")) {
             return $this->oUser->showDenied();
@@ -2450,7 +2539,8 @@ class project extends base {
      * @param array $aOptions
      * @return boolean|string
      */
-    public function delete($aOptions = array()) {
+    public function delete($aOptions = array())
+    {
         $this->log(__FUNCTION__ . " start");
         if (!$this->oUser->hasPermission("project-action-delete")) {
             return $this->oUser->showDenied();
@@ -2504,6 +2594,4 @@ class project extends base {
         $this->_logaction(t('finished') . " delete()", __FUNCTION__, "success");
         return false;
     }
-
-
 }
diff --git a/public_html/deployment/classes/projectlist.class.php b/public_html/deployment/classes/projectlist.class.php
index fb051774..48442219 100644
--- a/public_html/deployment/classes/projectlist.class.php
+++ b/public_html/deployment/classes/projectlist.class.php
@@ -16,7 +16,8 @@ require_once 'project_gui.class.php';
 /**
  * class for project overview
  */
-class projectlist extends base{
+class projectlist extends base
+{
     // ----------------------------------------------------------------------
     // CONFIG
     // ----------------------------------------------------------------------    
@@ -27,8 +28,9 @@ class projectlist extends base{
     /**
      * constructor2 called from constructor of base class
      */
-    public function __construct() {
-        $this->oUser=new user();
+    public function __construct()
+    {
+        $this->oUser = new user();
     }
 
     // ----------------------------------------------------------------------
@@ -48,7 +50,8 @@ class projectlist extends base{
      * render html for overview table
      * @return string
      */
-    public function renderOverview() {
+    public function renderOverview()
+    {
         global $renderAdminLTE;
 
         $sOut = '';  // table
@@ -57,87 +60,81 @@ class projectlist extends base{
         $sTrClass = "trproject";
         $sColClass = "tdphase";
 
-        $sNone='none';
+        $sNone = 'none';
         $oPrj1 = new projectgui();
-        $oHtml=new htmlguielements();
+        $oHtml = new htmlguielements();
 
         $sPrjFilter = '';
         $sPrjGroupFilter = '';
         $sPhaseFilter = '';
-        $sPrjFilter.='<option value="">' . t("all") . '</option>';
-        $sPrjGroupFilter.='<option value="">' . t("all") . '</option>';
+        $sPrjFilter .= '<option value="">' . t("all") . '</option>';
+        $sPrjGroupFilter .= '<option value="">' . t("all") . '</option>';
 
-        $sPhaseFilter.='<option value="' . $sColClass . '">' . t("all") . '</option>';
-        
-        $iInprogress=0;
-        $iHasqueue=0;
-        $aPrjGroups=[];
+        $sPhaseFilter .= '<option value="' . $sColClass . '">' . t("all") . '</option>';
 
-        $sDivInprogress='<div class="progressinprogress" title="'.t("progress-inprogress").'">'.$oHtml->getIcon('refresh').t("progress-inprogress").'</div>';
-        $sDivHasqueue='<div class="progresshasqueue" title="'.t("progress-hasqueue").'">'.$oHtml->getIcon('waiting').t("progress-hasqueue").'</div>';
-        
-        $sErrors='';
+        $iInprogress = 0;
+        $iHasqueue = 0;
+        $aPrjGroups = [];
+
+        $sDivInprogress = '<div class="progressinprogress" title="' . t("progress-inprogress") . '">' . $oHtml->getIcon('refresh') . t("progress-inprogress") . '</div>';
+        $sDivHasqueue = '<div class="progresshasqueue" title="' . t("progress-hasqueue") . '">' . $oHtml->getIcon('waiting') . t("progress-hasqueue") . '</div>';
+
+        $sErrors = '';
 
         // foreach (array_keys($this->_aPhases) as $sPhase) {
         foreach (array_keys($oPrj1->getPhases()) as $sPhase) {
-            $sPhaseFilter.='<option value="' . $sPhase . '" >' . $sPhase . '</option>';
+            $sPhaseFilter .= '<option value="' . $sPhase . '" >' . $sPhase . '</option>';
         }
 
         // #6611 Übersichtsseite nach Project Name sortieren
         // foreach ($oPrj1->getProjects() as $sPrj) {
 
-        $aProjectLabels=[];
-        foreach ($oPrj1->getProjects() as $sPrj) {
-            $oPrj = new project($sPrj);
-            $aProjectLabels[$oPrj->getLabel().'-'.$sPrj]=$sPrj;
-        }
-        ksort($aProjectLabels);
-        
-        foreach (array_values($aProjectLabels) as $sPrj) {
-            $oPrj = new projectgui($sPrj);
-            $sPrjFilter.='<option value="' . $sPrj . '">' . $oPrj->getLabel() . '</option>';
+        $oPrj = new projectgui();
+        $aProjectByLabel = $oPrj->getProjects("label");
+        foreach ($aProjectByLabel as $aProject) {
+            $oPrj = new projectgui($aProject['id']);
+            $sPrjFilter .= '<option value="' . $aProject['id'] . '">' . $aProject['label'] . '</option>';
 
             $sOutPhases = '';
             $sOutPhases2 = '';
-            $sProgress='';
+            $sProgress = '';
 
             // loop over phases ...
             foreach (array_keys($oPrj->getPhases()) as $sPhase) {
-                $sOutPhases.=$oPrj->renderAllPhaseDetails($sPhase, true, false);
+                $sOutPhases .= $oPrj->renderAllPhaseDetails($sPhase, true, false);
                 if ($oPrj->canAcceptPhase($sPhase)) {
                     // $sOutPhases2.=' <span class="'.$sPhase.'" style="padding: 1em 0.5em 0.5em;">'.$oPrj->renderLink("accept", $sPhase).'</span>';
-                    $sOutPhases2.=' ' . $oPrj->renderLink("accept", $sPhase);
+                    $sOutPhases2 .= ' ' . $oPrj->renderLink("accept", $sPhase);
                 }
             }
-            $aProgress=$oPrj->getProgress();
-            $sPrjGroup=$oPrj->getProjectGroup();
-            $sPrjGroup=$sPrjGroup?$sPrjGroup:$sNone;
+            $aProgress = $oPrj->getProgress();
+            $sPrjGroup = $oPrj->getProjectGroup();
+            $sPrjGroup = $sPrjGroup ? $sPrjGroup : $sNone;
 
-            $sClasses=$sPrj . ' ' . $sTrClass
+            $sClasses = $sPrj . ' ' . $sTrClass
                 . ' trprogress'
-                .($aProgress['inprogress'] ? ' progressinprogress' : '')
-                .($aProgress['hasQueue'] ? ' progresshasqueue' : '')
-                . ' group-'.$sPrjGroup
-                ;
+                . ($aProgress['inprogress'] ? ' progressinprogress' : '')
+                . ($aProgress['hasQueue'] ? ' progresshasqueue' : '')
+                . ' group-' . $sPrjGroup;
 
-            if($aProgress['inprogress']){
+            if ($aProgress['inprogress']) {
                 $iInprogress++;
 
-                $sProgress.=$sDivInprogress;
+                $sProgress .= $sDivInprogress;
             }
-            if($aProgress['hasQueue']){
+            if ($aProgress['hasQueue']) {
                 $iHasqueue++;
-                $sProgress.=$sDivHasqueue;
+                $sProgress .= $sDivHasqueue;
             }
 
 
-            if($sPrjGroup){
-                $sPrjLabel=$oPrj->getProjectGroupLabel();
-                $sPrjLabel=$sPrjLabel ? $sPrjLabel : $sNone;
-                if(!isset($aPrjGroups[$sPrjLabel])){
-                    $aPrjGroups[$sPrjLabel]=[
-                        'id'=>$sPrjGroup,
-                        'count'=>1
+            if ($sPrjGroup) {
+                $sPrjLabel = $oPrj->getProjectGroupLabel();
+                $sPrjLabel = $sPrjLabel ? $sPrjLabel : $sNone;
+                if (!isset($aPrjGroups[$sPrjLabel])) {
+                    $aPrjGroups[$sPrjLabel] = [
+                        'id' => $sPrjGroup,
+                        'count' => 1
                     ];
                 } else {
                     $aPrjGroups[$sPrjLabel]['count']++;
@@ -145,7 +142,7 @@ class projectlist extends base{
             }
 
 
-            $sErrors.=$oPrj->renderErrorBoxes();
+            $sErrors .= $oPrj->renderErrorBoxes();
 
             /*
             $sOut2 .= '<div class="' . $sClasses . ' prjbox"><div class="title">'
@@ -177,41 +174,41 @@ class projectlist extends base{
 
 
             // render output
-            $sOut.='
+            $sOut .= '
                 <tr class="' . $sClasses . '" '
-                    . 'ondblclick="location.href=\'/deployment/' . $sPrj . '/\'" '
-                    . 'title="'.sprintf(t("overview-hint-dblclick"),$sPrj).'">
+                . 'ondblclick="location.href=\'/deployment/' . $sPrj . '/\'" '
+                . 'title="' . sprintf(t("overview-hint-dblclick"), $sPrj) . '">
                     <td class="prj">
-                        <span class="float-right"><i class="fa-solid fa-tag"></i> '.$sPrjGroup.'</span>
+                        <span class="float-right"><i class="fa-solid fa-tag"></i> ' . $sPrjGroup . '</span>
                         <strong>'
-                        .$oHtml->getLink(array(
-                            'href'=>'/deployment/' . $sPrj . '/',
-                            'title'=>$oPrj->getDescription(),
-                            'icon'=>'project',
-                            'label'=>$oPrj->getLabel()
-                        ))
-                        .'</strong>'
-                    . '<div class="descr">'.$oPrj->getDescription() .'</div>'
-                    . ($sProgress ? '<div class="deployprogress">'.$sProgress.'</div>' : '')
-                    // . '    <br>'
-                    . '</td>'
-                    . '<td class="prj">'
-                    . $oHtml->getLinkButton(array(
-                        'href'=>'#',
-                        'onclick'=>'setProjectFilter(\'' . $sPrj . '\'); return false;',
-                        'style'=>'float: right',
-                        'title'=>t("overview-filter-hint"),
-                        'icon'=>'filter',
-                        'label'=>t("overview-filter"),
-                      ))
-                    . '</td>'
-                    . '<td class="prj">';
+                . $oHtml->getLink(array(
+                    'href' => '/deployment/' . $sPrj . '/',
+                    'title' => $oPrj->getDescription(),
+                    'icon' => 'project',
+                    'label' => $oPrj->getLabel()
+                ))
+                . '</strong>'
+                . '<div class="descr">' . $oPrj->getDescription() . '</div>'
+                . ($sProgress ? '<div class="deployprogress">' . $sProgress . '</div>' : '')
+                // . '    <br>'
+                . '</td>'
+                . '<td class="prj">'
+                . $oHtml->getLinkButton(array(
+                    'href' => '#',
+                    'onclick' => 'setProjectFilter(\'' . $sPrj . '\'); return false;',
+                    'style' => 'float: right',
+                    'title' => t("overview-filter-hint"),
+                    'icon' => 'filter',
+                    'label' => t("overview-filter"),
+                ))
+                . '</td>'
+                . '<td class="prj">';
             if ($oPrj->canAcceptPhase()) {
-                $sOut .=$oPrj->renderLink("build");
+                $sOut .= $oPrj->renderLink("build");
                 // $sOut2.=$oPrj->renderLink("build");
                 // $sOut.='<a href="/deployment/'.$sPrj.'/build/" class="btn btn-default '.$sNext.'"><i class=" icon-forward"></i> Build f&uuml;r ['.$sNext.']</a><br>';
             }
-            $sOut.='</td>
+            $sOut .= '</td>
                 ' . $sOutPhases . '
                 </tr>';
             // $sOut2.=$sOutPhases2 . '</div></div>';
@@ -220,24 +217,23 @@ class projectlist extends base{
             $sRowHead1 = '';
             $sRowHead2 = '';
 
-            $aGrouplist=array_keys($aPrjGroups);
+            $aGrouplist = array_keys($aPrjGroups);
             sort($aGrouplist);
 
-            $iNone=isset($aPrjGroups[$sNone]['count']) && $aPrjGroups[$sNone]['count'] ? $aPrjGroups[$sNone]['count'] : 0;
-            $sPrjGroupFilter.= ($iNone ? '<option value="none">'.t("none").' ('.$iNone.')</option>' : '')
-                . '<option value="">-----</option>'
-            ;
-            foreach ($aGrouplist as $sLabel){
-                $sId=$aPrjGroups[$sLabel]['id'];
-                $iCount=$aPrjGroups[$sLabel]['count'];
-                
-                $sPrjGroupFilter.=($sLabel!=$sNone) ? '<option value="' . $sId . '">' . $sLabel . ' ('.$iCount.')</option>' : '';
+            $iNone = isset($aPrjGroups[$sNone]['count']) && $aPrjGroups[$sNone]['count'] ? $aPrjGroups[$sNone]['count'] : 0;
+            $sPrjGroupFilter .= ($iNone ? '<option value="none">' . t("none") . ' (' . $iNone . ')</option>' : '')
+                . '<option value="">-----</option>';
+            foreach ($aGrouplist as $sLabel) {
+                $sId = $aPrjGroups[$sLabel]['id'];
+                $iCount = $aPrjGroups[$sLabel]['count'];
+
+                $sPrjGroupFilter .= ($sLabel != $sNone) ? '<option value="' . $sId . '">' . $sLabel . ' (' . $iCount . ')</option>' : '';
             }
 
             foreach (array_keys($oPrj1->getPhases()) as $sPhase) {
                 // Anzahl colspan ist hartcodiert :-/
-                $sRowHead1.='<th class="' . $sPhase . ' ' . $sColClass . '" colspan="3">' . $oHtml->getIcon('phase').$sPhase . '</th>';
-                $sRowHead2.=$oPrj->renderPlacesAsTd($sPhase);
+                $sRowHead1 .= '<th class="' . $sPhase . ' ' . $sColClass . '" colspan="3">' . $oHtml->getIcon('phase') . $sPhase . '</th>';
+                $sRowHead2 .= $oPrj->renderPlacesAsTd($sPhase);
             }
             $sOutTop = '
                 <script>
@@ -466,7 +462,7 @@ class projectlist extends base{
                         
 
                         <label for="efilter">
-                            '.$oHtml->getIcon('filter').'
+                            ' . $oHtml->getIcon('filter') . '
                             ' . t("overview-textsearch") . ':
                         </label>
                         <input type="text" id="efilter" name="efilter" 
@@ -477,11 +473,11 @@ class projectlist extends base{
                             onKeyup="filterTableByTyping(); "
                             title="' . t("overview-textsearch-hint") . '"
                             >
-                        <button class="btn btn-default" onclick="$(\'#efilter\').val(\''.$this->oUser->getUsername().'\'); filterTableByTyping(); return false;">
-                            '.$oHtml->getIcon('user').$this->oUser->getUsername().'
+                        <button class="btn btn-default" onclick="$(\'#efilter\').val(\'' . $this->oUser->getUsername() . '\'); filterTableByTyping(); return false;">
+                            ' . $oHtml->getIcon('user') . $this->oUser->getUsername() . '
                         </button>
                         <button id="btnresetefilter" class="btn btn-default" onclick="$(\'#efilter\').val(\'\'); filterTableByTyping(); return false;">
-                            '.$oHtml->getIcon('close').'
+                            ' . $oHtml->getIcon('close') . '
                         </button>
                         
 
@@ -497,9 +493,9 @@ class projectlist extends base{
                             </select>
                         </span>
                         <div class="btn-group">
-                            <button id="btnProgress"           class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'\'); return setprogress();" >'.t("overview-projectcount").'<br><span>'.count($oPrj1->getProjects()).'</span></button>
-                            <button id="btnProgressinprogress" class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'inprogress\'); return setprogress();" >'.$sDivInprogress.'<span>'.$iInprogress.'</span></button>
-                            <button id="btnProgresshasqueue"   class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'hasqueue\'); return setprogress();" >'.$sDivHasqueue .'<span>'.$iHasqueue.'</span></button>
+                            <button id="btnProgress"           class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'\'); return setprogress();" >' . t("overview-projectcount") . '<br><span>' . count($oPrj1->getProjects()) . '</span></button>
+                            <button id="btnProgressinprogress" class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'inprogress\'); return setprogress();" >' . $sDivInprogress . '<span>' . $iInprogress . '</span></button>
+                            <button id="btnProgresshasqueue"   class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'hasqueue\'); return setprogress();" >' . $sDivHasqueue . '<span>' . $iHasqueue . '</span></button>
                         </div>
                         &nbsp;&nbsp;&nbsp;
                         <label for="prjgroupfilter">
@@ -548,12 +544,12 @@ class projectlist extends base{
 
                         <a href="#" class="btn btn-danger" id="btnresetfilter" 
                             title="' . t("overview-filterreset-hint") . '"
-                            onclick="resetFilter();">'.$oHtml->getIcon('close').t("overview-filterreset") . '</a>
+                            onclick="resetFilter();">' . $oHtml->getIcon('close') . t("overview-filterreset") . '</a>
                     </form>
                     <div style="clear: both; margin-bottom: 1em"></div>
                 </div>';
-            $sOut=$sErrors
-                
+            $sOut = $sErrors
+
                 /*
                 .'
                 <div class="view viewsimple">
@@ -562,7 +558,7 @@ class projectlist extends base{
                     <br>
                 </div>'
                 */
-                .'
+                . '
 
 		<table class="table view viewextended" id="tbloverview">
 			<thead>
@@ -578,28 +574,26 @@ class projectlist extends base{
 			</thead>
 			<tbody>
 		' . $sOut . '</tbody></table>'
-                    . '<script>window.setTimeout("setDefaultView();", 50); window.setTimeout("window.location.replace(window.location.pathname + window.location.search + window.location.hash);", 60000);</script>';
+                . '<script>window.setTimeout("setDefaultView();", 50); window.setTimeout("window.location.replace(window.location.pathname + window.location.search + window.location.hash);", 60000);</script>';
         } else {
             $sOut = t("class-pl-error-no-project") . '<br><br>'
-                    . $oPrj1->renderLink("new")
-            ;
+                . $oPrj1->renderLink("new");
         }
-        
-        $sOut=''
-        .$renderAdminLTE->addRow(
-            $renderAdminLTE->addCol($sOutTop, 12)
-        )
-        .$renderAdminLTE->addRow(
-            $renderAdminLTE->addCol(
-                $renderAdminLTE->getCard([
-                    'type'=>'',
-                    'variant'=>'outline',
-                    'text'=>$sOut,
-                ]),
-                12
+
+        $sOut = ''
+            . $renderAdminLTE->addRow(
+                $renderAdminLTE->addCol($sOutTop, 12)
             )
-        );
+            . $renderAdminLTE->addRow(
+                $renderAdminLTE->addCol(
+                    $renderAdminLTE->getCard([
+                        'type' => '',
+                        'variant' => 'outline',
+                        'text' => $sOut,
+                    ]),
+                    12
+                )
+            );
         return $sOut;
     }
-
 }
diff --git a/public_html/deployment/inc_functions.php b/public_html/deployment/inc_functions.php
index 6f5e5ec3..3d60c582 100644
--- a/public_html/deployment/inc_functions.php
+++ b/public_html/deployment/inc_functions.php
@@ -158,12 +158,11 @@ function getTopNavLeft($aEmbed=[]) {
     if($oUser->getUsername()){
         $oPrj1 = new project();
         $aPrjItems=[];
-        foreach ($oPrj1->getProjects() as $sPrj) {
-            $oPrj = new project($sPrj);
+        foreach ($oPrj1->getProjects("label") as $aProject) {
             $aPrjItems[]=[
-                'href'=>$sBaseUrl . $sPrj .'/', 
-                'label'=>$oPrj->getLabel(), 
-                'class'=>$sCurrentProject===$oPrj->getId() ? 'active' : '', 
+                'href'=>$sBaseUrl . $aProject['id'] .'/', 
+                'label'=>$aProject['label'], 
+                'class'=>$sCurrentProject===$aProject['id'] ? 'active' : '', 
                 'icon'=>'fa-solid fa-book',
             ];
         }
-- 
GitLab