diff --git a/config/inc_projects_config.php b/config/inc_projects_config.php index 8bce3cc525bd8d9ce1a15daf473be2b4b94d531f..53c00fcc609fdb56ff667403baa17812da3beaa0 100644 --- a/config/inc_projects_config.php +++ b/config/inc_projects_config.php @@ -34,21 +34,21 @@ $aConfig = array( 'phases' => array( "preview" => array( 'css' => array( - 'bgdark' => 'background:#358; background: linear-gradient(#ddd,#358,#358); ', + 'bgdark' => 'background:#358; background: linear-gradient(#abf,#358,#358); background: linear-gradient(90deg, #358,#abf); ', 'bglight' => 'background:#f4f8ff; color:#333; background: rgba(210,220,255, 0.4);', 'bgbutton' => 'background:#ccf;', ), ), "stage" => array( 'css' => array( - 'bgdark' => 'background:#388; background: linear-gradient(#ddd,#388,#388); ', + 'bgdark' => 'background:#388; background: linear-gradient(#add,#388,#388); background: linear-gradient(90deg, #388,#add); ', 'bglight' => 'background:#f4ffff; color:#333; background: rgba(180,230,230, 0.4);', 'bgbutton' => 'background:#cff;', ), ), "live" => array( 'css' => array( - 'bgdark' => 'background:#3a3; background: linear-gradient(#ddd,#3a3,#3a3);', + 'bgdark' => 'background:#383; background: linear-gradient(#aea,#383,#383);background: linear-gradient(90deg, #383,#aea); ', 'bglight' => 'background:#f0fff0; color:#333; background: rgba(180,255,180, 0.4);', 'bgbutton' => 'background:#cfc;', ), diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php index ff99cabfba82cc6c990723ebb5b287ea3af8b634..fb2f3bd435cbdf2eb76da3b37a3d7895206b5030 100644 --- a/public_html/deployment/classes/project.class.php +++ b/public_html/deployment/classes/project.class.php @@ -755,6 +755,10 @@ class project { public function canAcceptPhase($sPhase = false) { if (!$sPhase) { + $aRepodata = $this->getRepoRevision(); + if (!array_key_exists("revision", $aRepodata)) { + return false; + } $sNext = $this->getNextPhase($sPhase); return $sNext > ''; } @@ -768,9 +772,10 @@ class project { return false; } $sNext = $this->getNextPhase($sPhase); - if (!$sNext) + if (!$sNext){ return false; - + } + // ensure that _aData is filled $this->getPhaseInfos($sPhase); @@ -1993,18 +1998,17 @@ class project { $sReturn.= '<i class="icon-tag"></i> ' . t('revision') . ': ' . $sRevision; $sReturn.="<pre>" . strip_tags($aRepodata["message"], '<br>') . "</pre>"; } else { - return $this->getBox("error", sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"])) + $sReturn .= $this->getBox("error", sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"])) . $this->renderLink("setup"); } - if (array_key_exists("webaccess", $this->_aPrjConfig["build"])) { - $sReturn.='<br>' . t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>'; - } - break; default: - return $this->getBox("error", sprintf(t('class-project-error-wrong-buildtype'), $this->_aPrjConfig["build"]["type"])); + $sReturn .= $this->getBox("error", sprintf(t('class-project-error-wrong-buildtype'), $this->_aPrjConfig["build"]["type"])); + } + if (array_key_exists("webaccess", $this->_aPrjConfig["build"])) { + $sReturn.='<br>' . t('repository-access-browser') . ':<br><a href="' . $this->_aPrjConfig["build"]["webaccess"] . '">' . $this->_aPrjConfig["build"]["webaccess"] . '</a><br>'; } return $sReturn; } diff --git a/public_html/deployment/classes/sws.class.php b/public_html/deployment/classes/sws.class.php index 6b943953501762b01b05b5af1b825e80ddae1f27..21b9f8f53fa746b68dacc9c19e2e0d915e1b60ce 100644 --- a/public_html/deployment/classes/sws.class.php +++ b/public_html/deployment/classes/sws.class.php @@ -14,6 +14,8 @@ * <br> * * --- HISTORY:<br> + * 2014-04-30 0.5 gui enhancements: input field for each param of all methods + * 2014-04-29 0.4 abstract all data before displaying them * 2014-04-06 0.3 enable/ disable gui; detect class parameters * 2014-04-05 0.2 * 2014-04-05 0.1 first public beta @@ -32,7 +34,7 @@ * - configuration: option area * - configuration: examples of a class + of actions * - * @version 0.03 + * @version 0.05 * @author Axel Hahn * @link http://www.axel-hahn.de/php_sws * @license GPL @@ -59,6 +61,12 @@ class sws { * @var string */ private $_sClass = false; + + /** + * name of the detected init arguments for the class in the http request + * @var string + */ + private $_aInit = array(); /** * name of the detected method in the http request @@ -95,7 +103,7 @@ class sws { * version * @var string */ - private $_sVersion = "0.03 (beta)"; + private $_sVersion = "0.05 (beta)"; /** * title @@ -104,7 +112,8 @@ class sws { private $_sTitle = "SWS :: simple web service"; private $_aOptions = array( - 'enableGui'=>true + 'enableGui'=>true, + 'enableDump'=>false ); /** @@ -158,7 +167,11 @@ class sws { } /** - * parse parameters (given by setParams) + * parse parameters (given GET/ POST is in by _aParams @see setParams) + * class - class to initialize + * init - parameters for constructor + * action - public method to call + * args - arguments for the method * @return bool */ private function _parseParams() { @@ -168,6 +181,7 @@ class sws { // set defaults $this->_sClass = false; + $this->_aInit = array(); $this->_sAction = false; $this->_aArgs = array(); @@ -189,23 +203,44 @@ class sws { } } // TODO: checkMaxParams + // check if classname and action exist in configuration if (array_key_exists("class", $this->_aParams)) { if (!array_key_exists($this->_aParams["class"], $this->_aKnownClasses["classes"])) { - $this->_quit('ERROR: parameter <em>class = ' . $this->_aParams["class"] . '</em> is invalid. I cannot handle this class.', $this->showClasshelp()); + $this->_quit('ERROR: parameter <em>class = ' . $this->_aParams["class"] . '</em> is invalid. I cannot handle this class.', $this->_showClasshelp()); } else { - // set internal vars + // set internal vars: classname $this->_sClass = $this->_aParams["class"]; $this->_sClassfile = $this->_aKnownClasses["classes"][$this->_aParams["class"]]["file"]; + + // get arguments for the method + if (array_key_exists("init", $this->_aParams)) { + try { + $aTmp = json_decode($this->_aParams["init"], 1); + } catch (Exception $e) { + // nop + } + if (!is_array($aTmp)) { + $this->_quit( + 'ERROR: wrong request - init value must be a json string<br>' + . 'examples:<br>' + . '- one arg <code>(...)&init=["my string"]</code><br>' + . '- two args <code>(...)&init=["my string", 123]</code> ' + , $this->_showClasshelp()); + } + $this->_aInit = $aTmp; + } } + // get method name to call if (array_key_exists("action", $this->_aParams)) { if (!array_key_exists($this->_aParams["action"], $this->_aKnownClasses["classes"][$this->_aParams["class"]]["actions"])) { - $this->_quit('ERROR: class ' . $this->_aParams["class"] . ' exists but it has no <em>action = ' . $this->_aParams["action"] . '</em>.', $this->showClasshelp()); + $this->_quit('ERROR: class ' . $this->_aParams["class"] . ' exists but it has no <em>action = ' . $this->_aParams["action"] . '</em>.', $this->_showClasshelp()); } else { // set internal vars $this->_sAction = $this->_aParams["action"]; } } + // get arguments for the method if (array_key_exists("args", $this->_aParams)) { try { $aTmp = json_decode($this->_aParams["args"], 1); @@ -218,7 +253,7 @@ class sws { . 'examples:<br>' . '- one arg <code>(...)&args=["my string"]</code><br>' . '- two args <code>(...)&args=["my string", 123]</code> ' - , $this->showClasshelp()); + , $this->_showClasshelp()); } $this->_aArgs = $aTmp; } @@ -229,7 +264,7 @@ class sws { $this->setOutputType($this->_aParams["type"]); } if ($sErrors) { - $this->_quit('ERROR: wrong request - a required parameter was not found:<br>' . $sErrors, $this->showClasshelp()); + $this->_quit('ERROR: wrong request - a required parameter was not found:<br>' . $sErrors, $this->_showClasshelp()); } return true; } @@ -284,159 +319,298 @@ class sws { * @param type $sError */ private function _quit($sError, $sMore = "") { - header("Status: 404 Not Found"); + header("Status: 400 Bad Request"); echo $this->_wrapAsWebpage( $sMore, '<div class="error">' . $sError . '</div>' ); die(); } + + /** - * show help - return html with list of allowed classes - * @return string + * read a class and fetch information about its methods and parameters */ - private function showClasshelp() { - $sReturn = ''; - - - $sReturn .= '<h2>Explore</h2>' - . '<p>allowed classes are:</p><ul class="classes">'; + private function _collectClassData(){ + // loop classes of the given config foreach (array_keys($this->_aKnownClasses["classes"]) as $sMyClass) { - require_once($this->_sClassDir . $this->_aKnownClasses["classes"][$sMyClass]["file"]); + $RefClass=&$this->_aKnownClasses["classes"][$sMyClass]; + + require_once($this->_sClassDir . $RefClass["file"]); $oRefClass = new ReflectionClass($sMyClass); - $sComment = $this->_parseComment($oRefClass->getDocComment()); - $sComment2 = $this->_parseComment($oRefClass->getMethod("__construct")->getDocComment()); + + $RefClass=&$this->_aKnownClasses["classes"][$sMyClass]; + $RefClass['phpdoc-class']=$this->_parseComment($oRefClass->getDocComment()); + $RefClass['active']=(array_key_exists("class", $this->_aParams) && $sMyClass===$this->_aParams["class"])?true:false; + + // loop configured methods of a class + // foreach (array_keys($this->_aKnownClasses["classes"][$sMyClass]["actions"]) as $sAction) { + foreach (array_merge(array("__construct"), array_keys($this->_aKnownClasses["classes"][$sMyClass]["actions"])) as $sAction) { + // foreach (array_keys($this->_aKnownClasses["classes"][$sMyClass]["actions"]) as $sAction) { + $oMethod = false; + try { + $oMethod = $oRefClass->getMethod($sAction); + } catch (Exception $e) { + // nop + echo $e->getMessage(); + } + if ($oMethod) { + $bActive=(array_key_exists("action", $this->_aParams) && $sAction===$this->_aParams["action"])?true:false; + $sComment = $this->_parseComment($oRefClass->getMethod($sAction)->getDocComment()); + + $sActionKey=($sAction==="__construct")?"init":"args"; + $aGivenParams=false; + if (array_key_exists($sActionKey, $this->_aParams)){ + $aGivenParams=json_decode($this->_aParams[$sActionKey]); + } + + if (!$aGivenParams){ + $aGivenParams=array(); + } + + $aParams=array(); + $iRequired=$oMethod->getNumberOfRequiredParameters(); + + // loop params of the method + $iCount=0; + foreach($oMethod->getParameters() as $oParam){ + + preg_match('@Parameter\ \#.*\[\ (.*)\ \]@', $oParam->__toString(), $aTmp); + preg_match('@(.*)=\ (.*)@', $aTmp[1], $aTmp1); + $aParams[$iCount]["orig"]=$oParam->__toString(); + $sValue=false; + if (count($aTmp1)){ + $aParams[$iCount]["varname"]=trim($aTmp1[1]); + $sType=$aTmp1[2]; + $sValue=$aTmp1[2]; + + $sValue=str_replace(array("'", '"'), array('', ''), $sValue); + if ($sValue=="Array"){ + $sValue='{ }'; + } + if ($sValue=="false"){ + $sValue=''; + } + + $aParams[$iCount]["defaultvalue"]=$aTmp1[2]; + } + /* + $aParams[$iCount]["required"]=false; + } else { + $aParams[$iCount]["required"]=true; + } + */ + $sValue=(array_key_exists($iCount, $aGivenParams) && $aGivenParams[$iCount])?json_encode($aGivenParams[$iCount]):$sValue; + $aParams[$iCount]["value"]=$sValue; + + $aParams[$iCount]["required"]=$iCount<$iRequired ? true:false; + $iCount++; + } + $RefClass["actions"][$sAction]['active']=$bActive; + $RefClass["actions"][$sAction]['phpdoc']=$sComment; + $RefClass["actions"][$sAction]['params']=$aParams; + $RefClass["actions"][$sAction]['value']=($bActive && count($this->_aArgs))?$this->_aParams["args"]:false; + + if($sAction==="__construct"){ + $RefClass["actions"][$sAction]['value']=(array_key_exists("init", $this->_aParams))?$this->_aParams["init"]:''; + } + } else { + // '' . $sAction . ' <<< ERROR in configuration: this method does not exist' + } + } + + } + } + + /** + * get html code for input fields of the parameters of a class + * @param string $sMyClass name of the class + * @param string $sAction name of the method to render + * @return string + */ + private function _showMethodInputForm($sMyClass, $sAction, $sIdPrefixBase){ + $sHtml=''; + $iCount=0; + $aParams=array(); - $sIdDescription = "help-" . $sMyClass . ""; - $sStyle = ' style="display: none;"'; - $sClass = ''; - $sBtnValue = '+'; - if (array_key_exists("class", $this->_aParams) && $this->_aParams["class"] == $sMyClass) { - $sClass = 'active'; - $sStyle = ''; - $sBtnValue = '-'; + $aRefMethod=$this->_aKnownClasses['classes'][$sMyClass]['actions'][$sAction]; + + $sHtml.=$aRefMethod["phpdoc"]; + $iCount=count($aRefMethod["params"]); + if ($iCount) { + + $sHtml.='<fieldset><legend>Enter each parameter params to generate json: </legend>'; + foreach($aRefMethod["params"] as $sKey=>$aParam){ + $sIdInput=$sIdPrefixBase.$sKey; + $sFkt='updateMethodVar(\''.$sIdPrefixBase.'\', '.$iCount.')'; + $sChanges='onchange="'.$sFkt.'" ' + . 'onkeypress="'.$sFkt.'" ' + . 'onkeyup="'.$sFkt.'" ' + ; + $sHtml.='<label for="'.$sIdInput.'">'.$aParam["varname"].' = </label>' + .'<input type="text" id="'.$sIdInput.'" size="30" '.$sChanges.' value="'.str_replace('"', '"', $aParam["value"]).'"/>' + ; + if ($aParam["required"]){ + $sHtml.=' (*)'; + } else { + $sHtml.=' « optional; default is <span class="defaultvalue">'.$aParam["defaultvalue"].'</span><br>'; + } } - $sReturn .= '<li class="classname ' . $sClass . ' ">' - . '<h3>' + $sHtml.='</fieldset><br>'; + } else { + $sHtml.='(no parameters)<br>'; + } + + return $sHtml; + } + + + /** + * show help - return html code for gui of the given method + * called in _showClasshelp() + * @param string $sMyClass name of the class + * @param string $sAction name of the method to render + * @return string + */ + private function _showActionHelp($sMyClass, $sAction){ + $sReturn = ''; + $RefClass=&$this->_aKnownClasses["classes"][$sMyClass]; + + $sStyle = ' style="display: none;"'; + $sBtnValue = '+'; + $sCssClass = ''; + if ($RefClass["actions"][$sAction]["active"]) { + $sCssClass = 'active'; + $sStyle = ''; + $sBtnValue = '-'; + } + $sValInit=array_key_exists('value', $RefClass['actions']['__construct'])?$RefClass['actions']['__construct']['value']:''; + $sValInit=str_replace('"', '"', $sValInit); + if (array_key_exists("params", $RefClass["actions"][$sAction])) { + $sIdDescription = "help-" . $sMyClass . "-" . $sAction; + $sValArgs=array_key_exists('value', $RefClass['actions'][$sAction])?$RefClass['actions'][$sAction]['value']:''; + $sValArgs=str_replace('"', '"', $sValArgs); + $sIdPrefix=md5($sMyClass.$sAction); + $sChanges='onchange="update(\''.$sIdPrefix.'\')" onkeypress="update(\''.$sIdPrefix.'\')" onkeyup="update(\''.$sIdPrefix.'\')" '; + $sReturn .= '<li class="actionname ' . $sCssClass . '">' + . '<h4>' . '<button onclick="toggleDesciption(\'' . $sIdDescription . '\', this)">' . $sBtnValue . '</button> ' - . '<a href="?class=' . $sMyClass . '">' . $sMyClass . '</a>' - . '</h3>' + . $sAction + . '</h4>' . '<div id="' . $sIdDescription . '"' . $sStyle . '>' - . $sComment - . '<p>__constructor:</p>' - . $sComment2 - . $this->showActionhelp($sMyClass) + + . '<input type="hidden" id="'.$sIdPrefix.'class" value="'.$sMyClass.'" />' + . '<input type="hidden" id="'.$sIdPrefix.'action" value="'.$sAction.'" />' + + . '<blockquote>' + + . '<h5>init parameters of class "'.$sMyClass.'"</h5>' + . '<code>$o = new '.$sMyClass.' ( ... )</code><br>' + . '<blockquote>' + . $this->_showMethodInputForm($sMyClass, "__construct", $sIdPrefix."init") + ; + if (count($RefClass['actions']["__construct"]['params'])){ + $sReturn .='OR<br><fieldset><legend>json</legend>' + . '<label for="'.$sIdPrefix.'init">init=</label>' + . '<input type="text" id="'.$sIdPrefix.'init" size="80" class="einit" name="init" value="'.$sValInit.'" '.$sChanges.'/><br>' + . '</fieldset>'; + } + $sReturn .= '</blockquote>' + + . '<h5>parameters of method "'.$sAction.'"</h5>' + . '<code>$o ->' . $sAction . ' ( ... )</code><br>' + . '<blockquote>' + . $this->_showMethodInputForm($sMyClass, $sAction, $sIdPrefix."args"); + if (count($RefClass['actions'][$sAction]['params'])){ + $sReturn .='OR<br><fieldset><legend>json</legend>' + . '<label for="'.$sIdPrefix.'args">args=</label>' + . '<input type="text" id="'.$sIdPrefix.'args" size="80" name="args" value="'.$sValArgs.'" '.$sChanges.'/><br>' + . '</fieldset>'; + } + $sReturn .='</blockquote>' + + . '<h5>select output type</h5>' + . '<blockquote>' + . '<select id="'.$sIdPrefix.'type" '.$sChanges.'>'; + foreach (array("raw", "json") as $sType) { + $sReturn .= '<option value="'.$sType.'"'; + if (array_key_exists("type", $this->_aParams) && $sType === $this->_aParams["type"]){ + $sReturn .= ' selected="selected"'; + } + $sReturn .= '>'.$sType.'</option>'; + } + $sReturn .= '</select>' + . '</blockquote>' + + . '<h5>preview:</h5>' + . '<blockquote>' + . '<textarea id="'.$sIdPrefix.'url" cols="120" rows="2" disabled="disabled"></textarea><br><br>' + . '<div id="'.$sIdPrefix.'code"></div>' + . '</blockquote>' + . '<button onclick="run(\''.$sIdPrefix.'\');">go</button>' + . '</blockquote>' . '</div>' + . '</li>' + ; + } else { + $sReturn .= '<li class="actionname error">' + . '' . $sAction . ' <<< ERROR in configuration: this method does not exist' . '</li>'; } - $sReturn .= '</ul>'; return $sReturn; } - + + /** - * show help - return html with list allowed methods of a given class - * @param string $sClass classname you get the methods from + * show help - return html gui with list of allowed classes * @return string */ - private function showActionhelp($sClass) { - $sReturn = '<p>For the class <em>' . $sClass . '</em> these methods are configured:</p><ul>'; - require_once($this->_sClassDir . $this->_aKnownClasses["classes"][$sClass]["file"]); - $oRefClass = new ReflectionClass($sClass); + private function _showClasshelp() { + $sReturn = ''; - foreach (array_keys($this->_aKnownClasses["classes"][$sClass]["actions"]) as $sAction) { + $this->_collectClassData(); + $sReturn .= '<h2>Explore</h2>' + . '<p>allowed classes are:</p>' + . '<ul class="classes">'; + foreach (array_keys($this->_aKnownClasses["classes"]) as $sMyClass) { + $RefClass=&$this->_aKnownClasses["classes"][$sMyClass]; + + $sIdDescription = "help-" . $sMyClass . ""; + $sClass = ''; $sStyle = ' style="display: none;"'; $sBtnValue = '+'; - $sCssClass = ''; - if ( - array_key_exists("class", $this->_aParams) && $this->_aParams["class"] == $sClass && array_key_exists("action", $this->_aParams) && $this->_aParams["action"] == $sAction) { - $sCssClass = 'active'; + if ($RefClass["active"]) { + $sClass = 'active'; $sStyle = ''; $sBtnValue = '-'; } - try { - $oMethod = false; - $oMethod = $oRefClass->getMethod($sAction); - } catch (Exception $e) { - // nop - } - if ($oMethod) { - $sComment = $this->_parseComment($oRefClass->getMethod($sAction)->getDocComment()); - $sIdDescription = "help-" . $sClass . "-" . $sAction; - $sReturn .= '<li class="actionname ' . $sCssClass . '">' - . '<h4>' - . '<button onclick="toggleDesciption(\'' . $sIdDescription . '\', this)">' . $sBtnValue . '</button> ' - . $sAction - . '</h4>' - . '<div id="' . $sIdDescription . '"' . $sStyle . '>' - . $sComment - . $this->_showMethodInputForm($oMethod) - . '<br>try it ... ' - . '' . $sClass . '->' . $sAction . '() ... <br><br>as '; - foreach (array("raw", "json") as $sType) { - $sReturn .= '<a href="?class=' . $sClass . '&action=' . $sAction . '&type=' . $sType . '"' - . ' class="button try"' - . '>' . $sType . '</a> '; - } - $sReturn .= '<br>' - . '</div>' - . '</li>'; - } else { - $sReturn .= '<li class="actionname error">' - . '' . $sAction . ' <<< ERROR in configuration: this method does not exist' - . '</li>'; + $sReturn .= '<li class="classname ' . $sClass . ' ">' + . '<h3>' + . '<button onclick="toggleDesciption(\'' . $sIdDescription . '\', this)">' . $sBtnValue . '</button> ' + . '<a href="?class=' . $sMyClass . '">' . $sMyClass . '</a>' + . '</h3>' + . '<div id="' . $sIdDescription . '"' . $sStyle . '>' + . $RefClass["phpdoc-class"] + . '<p>allowed methods:</p><ul>'; + foreach (array_keys($RefClass["actions"]) as $sAction) { + if ($sAction=="__construct"){ + continue; + } + $sReturn.=$this->_showActionHelp($sMyClass, $sAction); + } + foreach($RefClass["actions"] as $sAction){ + // nop } + $sReturn .= '</div>' + . '</li>'; } $sReturn .= '</ul>'; return $sReturn; } - private function _showMethodInputForm($oMethod){ - $sHtml=''; - $iCount=0; - $aParams=array(); - $iRequired=$oMethod->getNumberOfRequiredParameters(); - foreach($oMethod->getParameters() as $oParam){ - preg_match('@Parameter\ \#.*\[\ (.*)\ \]@', $oParam->__toString(), $aTmp); - preg_match('@(.*)=\ (.*)@', $aTmp[1], $aTmp1); - if (count($aTmp1)){ - $aParams[$iCount]["varname"]=$aTmp1[1]; - $aParams[$iCount]["value"]=$aTmp1[2]; - } else { - $aParams[$iCount]["varname"]=$aTmp[1]; - $aParams[$iCount]["value"]=false; - } - $aParams[$iCount]["required"]=$iCount<$iRequired ? true:false; - $iCount++; - } - - // - if (count($aParams )) { - $sHtml.='<br>parameters (<span class="error">not active yet - this feature to enter parameter values is coming soon</span>):<br><br>'; - if ($iRequired){ - if ($iCount==$iRequired) { - $sHtml.=' ... all param(s) required<br>'; - } else { - $sHtml.=' ... '.$iRequired . ' of '.$iCount.' param(s) required<br>'; - } - } - foreach($aParams as $aParam){ - $sHtml.='<label for="">'.$aParam["varname"].' = </label>'; - $sHtml.='<input type="text" name="" size="30" value="'.$aParam["value"].'"/>'; - if ($aParam["required"]){ - $sHtml.=' (*)'; - } else { - $sHtml.=' « optional; default is <span class="defaultvalue">'.$aParam["value"].'</span>'; - } - $sHtml.='<br>'; - } - } else { - $sHtml.='(no parameters)<br>'; - } - - return $sHtml; - } - + + /** * render output as html page * @param string $sBody html body @@ -446,12 +620,19 @@ class sws { private function _wrapAsWebpage($sBody = "", $sError = "") { $sClassSelect = '<span class="urlvalue">[class]</span>'; + $sClassInit = '<span class="urlvalue">[initparams]</span>'; $sActionSelect = '<span class="urlvalue">[action]</span>'; $sParamSelect = '<span class="urlvalue">[parameters]</span>'; $sTypeSelect = '<span class="urlvalue">[type: raw|json]</span>'; $sSyntax = sprintf( - '<pre>?<span class="urlvar">class</span>=%s&<span class="urlvar">action</span>=%s&<span class="urlvar">args</span>=%s&<span class="urlvar">type</span>=%s</pre>', $sClassSelect, $sActionSelect, $sParamSelect, $sTypeSelect + '<pre>?' + . '<span class="urlvar">class</span>=%s' + . '&<span class="urlvar">init</span>=%s' + . '&<span class="urlvar">action</span>=%s' + . '&<span class="urlvar">args</span>=%s' + . '&<span class="urlvar">type</span>=%s' + . '</pre>', $sClassSelect, $sClassInit, $sActionSelect, $sParamSelect, $sTypeSelect ); /* @@ -496,6 +677,8 @@ class sws { . 'h1 a span{color:#666; font-size: 45%;}' . 'h2{margin: 3em 0 1em; }' . 'h3,h4{margin: 0;}' + . 'fieldset{border: 1px solid rgba(0,0,0,0.2); background: rgba(0,0,0,0.05); }' + . 'input {border: 2px solid #ddd; padding: 0.3em; border-radius: 0.5em; color: #348; font-size: 100%;}' . 'label{width: 10em; float: left; text-align: right;}' . 'ul{padding-left: 0; margin: 0; border-radius: 0.5em;}' . 'ul ul{margin: 1em;}' @@ -503,12 +686,15 @@ class sws { . 'li{border-left: 5px solid #aaa; }' . 'li.active{border-left: 5px solid #aaa; }' . 'li li.active{border-left: 5px solid #c00; background: #fcc;}' - . 'pre{margin: 0; border: #ddd solid 1px; border-radius: 0.5em; padding: 0.5em; background: #fff;}' + . 'pre{margin: 0; border: #ddd solid 1px; border-radius: 0.5em; padding: 0.5em; background: #fff; opacity: 0.7;}' . 'pre .urlvar{color: #480; font-weight: bold;}' . 'pre .urlvalue{color: #8c0;}' + . 'pre pre{display: inline; padding: 0; border: 0;}' + . 'select {border: 2px solid #ddd; padding: 0.3em; border-radius: 0.5em; color: #348; font-size: 100%;}' + . 'td{color:#444;}' . '.classname{ background:#eee; }' . '.actionname{background:#ddd; background: rgba(0,0,0,0.1);}' - . '.phpdoctitle{background:#ccc; color:#fff;float: right; margin-right: 0.5em; padding: 0 1em; border-radius: 0.5em; border-top-left-radius: 0;border-top-right-radius: 0;}' + . '.phpdoctitle{display: none; background:#ccc; color:#fff;float: right; margin-right: 0.5em; padding: 0 1em; border-radius: 0.5em; border-top-left-radius: 0;border-top-right-radius: 0;}' . '.phpdoc{background:#f0f4f8;}' . '.doctag{ color:#080; }' . '.error{ color:#800; background:#fcc; padding: 0.5em; margin-bottom: 2em; border-left: 4px solid;}' @@ -526,6 +712,70 @@ class sws { . 'a.innerHTML=(a.innerHTML=="+")?"-":"+";' . '}' . '}' + .' + function updateMethodVar(sIdPrefix, iCount){ + var sOut=\'\'; + var sVal=false; + var aParams=[]; + if (!document.getElementById(sIdPrefix)){ + return false; + } + for (var i=0; i<iCount; i++) { + sVal=document.getElementById(sIdPrefix+""+i).value; + if(!sVal){ + sVal=""; + } else { + if (sVal % 1 == 0){ + sVal=sVal/1; + } else { + if( sVal === "true" || sVal === "false" ){ + sVal=sVal || sVal; + } else { + if ( + sVal.indexOf(\'"\')<0 + && sVal.indexOf("\'")<0 + ){ + sVal=\'"\'+sVal+\'"\'; + } + } + } + } + if (sOut){ + sOut+=", "; + } + sOut+=sVal; + aParams[i]=sVal; + } + document.getElementById(sIdPrefix).value="[" + sOut + "]"; + // document.getElementById(sIdPrefix).value=JSON.stringify(aParams); + document.getElementById(sIdPrefix).onchange(); + } + + function update(sIdPrefix){ + if (!document.getElementById(sIdPrefix+"class")){ + return false; + } + var sUrl="?"; + var arguments=["class", "init", "action", "args", "type"]; + for (var i=0; i<arguments.length; i++){ + if (document.getElementById(sIdPrefix+arguments[i]) + && document.getElementById(sIdPrefix+arguments[i]).value + ){ + sUrl+="&"+arguments[i]+"="+escape(document.getElementById(sIdPrefix+arguments[i]).value); + } + } + document.getElementById(sIdPrefix+"url").value=sUrl; + return true; + } + + function run(sIdPrefix){ + if (update(sIdPrefix)) { + location.href=document.getElementById(sIdPrefix+"url").value; + } + return true; + } + + ' . '</script>' . '</head>' . '<body>'; @@ -534,8 +784,14 @@ class sws { $sReturn.= '<h1><a href="?">' . $this->_sTitle . ' <span>'.$this->_sVersion.'</span></a></h1>' . '<div id="content">' - . $sError - . $sBody + . $sError; + if($this->_aOptions["enableDump"]){ + $sReturn.= '<h2>Debug</h2>' + . '_aParams:<pre>'.print_r($this->_aParams, true).'</pre>' + . '_aKnownClasses:<pre>'.print_r($this->_aKnownClasses, true).'</pre>' + ; + } + $sReturn.= $sBody . '<h2>Syntax</h2>' . $sSyntax . '</div><div id="footer">' @@ -547,7 +803,7 @@ class sws { . 'The shown information is parsed by reading phpdoc.' . '</p>' . '<p>' - . 'GNU 3.0;<br>'; + . 'GNU GPL 3.0;<br>'; if ($this->_sUrlDoc) { $sReturn.='<a href="' . $this->_sUrlDoc . '">' . $this->_sUrlDoc . '</a> '; } @@ -614,15 +870,33 @@ class sws { * @param type $sOutputType */ public function run($sOutputType = false) { - if (!count($this->_aParams)) + if (!count($this->_aParams)){ $this->setParams(); + } $this->_parseParams(); require_once($this->_sClassDir . $this->_sClassfile); if (!class_exists($this->_sClass)) { $this->_quit("ERROR: class does not exist: " . $this->_sClass); } - $o = new $this->_sClass; + + // ------------------------------------------------------------ + // init object + // ------------------------------------------------------------ + switch (count($this->_aInit)) { + case 0: $o = new $this->_sClass; + break; + case 1: $o = new $this->_sClass($this->_aInit[0]); + break; + case 2: $o = new $this->_sClass($this->_aInit[0], $this->_aInit[1]); + break; + case 3: $o = new $this->_sClass($this->_aInit[0], $this->_aInit[1], $this->_aInit[2]); + break; + case 4: $o = new $this->_sClass($this->_aInit[0], $this->_aInit[1], $this->_aInit[2], $this->_aInit[3]); + break; + default: die("internal ERROR in run(): need to set a new case with up to " . count($this->_aInit) . " arguments in " . __FILE__); + } + if (!method_exists($o, $this->_sAction)) { $this->_quit("ERROR: method does not exist: " . $this->_sClass . " -> " . $this->_sAction . "()"); } @@ -633,24 +907,22 @@ class sws { switch (count($this->_aArgs)) { case 0: $return = call_user_func(array($o, $this->_sAction)); break; - ; case 1: $return = call_user_func(array($o, $this->_sAction), $this->_aArgs[0]); break; - ; case 2: $return = call_user_func(array($o, $this->_sAction), $this->_aArgs[0], $this->_aArgs[1]); break; - ; case 3: $return = call_user_func(array($o, $this->_sAction), $this->_aArgs[0], $this->_aArgs[1], $this->_aArgs[2]); break; - ; case 4: $return = call_user_func(array($o, $this->_sAction), $this->_aArgs[0], $this->_aArgs[1], $this->_aArgs[2], $this->_aArgs[3]); break; - ; - default: die("internal ERROR: need to set a new case with up to " . count($this->_aArgs) . " arguments in " . __FILE__); + default: die("internal ERROR in run(): need to set a new case with up to " . count($this->_aArgs) . " arguments in " . __FILE__); } + /* if (!$return) { $this->_quit("ERROR: no output"); } + * + */ // ------------------------------------------------------------ // output @@ -662,12 +934,12 @@ class sws { break; case "raw": if (is_array($return)) { - $this->_quit("ERROR: Wrong output type for that method. Return of " . $this->_sClass . '->' . $this->_sAction . "() is an array", $this->showClasshelp()); + $this->_quit("ERROR: Wrong output type for that method. Return of " . $this->_sClass . '->' . $this->_sAction . "() is an array", $this->_showClasshelp()); } echo $return; break; default: - $this->_quit("ERROR in " . __FUNCTION__ . ": outputtype </em>" . $this->_sOutputType . "</em> is unknown", $this->showClasshelp()); + $this->_quit("ERROR in " . __FUNCTION__ . ": outputtype </em>" . $this->_sOutputType . "</em> is unknown", $this->_showClasshelp()); } } diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php index eba6c0cf3d501cc6dcab6578db2afc74c09ef485..894dbf137f4b415caa4a28bbf7c8f71d575aaf3b 100644 --- a/public_html/deployment/classes/vcs.git.class.php +++ b/public_html/deployment/classes/vcs.git.class.php @@ -12,16 +12,44 @@ require_once("vcs.interface.php"); class vcs implements iVcs { // class vcs { + /** + * configuration + * @var type + */ private $_aCfg=array(); - private $_sTempDir= false; // temp dir to fetch repo version and ommit message + /** + * temp dir to fetch repo version and ommit message; its value will be + * generated in set_config() + * @var type + */ + private $_sTempDir= false; // + + /** + * filename of ssh key file with complete path + * @var type + */ private $_sKeyfile = false; - private $_sWrapper = false; + /** + * filename of ssh wrapper script with complete path + * @var type + */ + private $_sWrapper = false; + + /** + * constructor + * @param type $aRepoConfig + */ public function __construct($aRepoConfig=array()) { $this->setConfig($aRepoConfig); } + /** + * set a config and update internal (private) variables + * @param array $aRepoConfig + * @return boolean + */ public function setConfig($aRepoConfig=array()){ // checks @@ -50,6 +78,10 @@ class vcs implements iVcs { return $this->_aCfg=$aRepoConfig; } + /** + * helper: dump values + * @return boolean + */ public function dump(){ echo "<h3>Dump class ".__CLASS__."</h3>"; echo "config array: <pre>" . print_r($this->_aCfg, true) . "</pre>"; diff --git a/public_html/deployment/main.css b/public_html/deployment/main.css index 3f5333a4a0306e4c17b5bd34cb5601b3ae4d4c2d..705a23b9ccd558b5edf826104ae8946f42fca6dc 100644 --- a/public_html/deployment/main.css +++ b/public_html/deployment/main.css @@ -78,7 +78,9 @@ h2.deploy{background-image: url("/deployment/images/nuvola64x64/apps/iconthemes. h2.prjhome{background-image: url("/deployment/images/nuvola64x64/apps/kdict.png");} h2.phase{background-image: url("/deployment/images/nuvola64x64/apps/kreversi.png");} h2.setup{background-image: url("/deployment/images/nuvola64x64/apps/kcmsystem.png");} -h3{color:#444;} +h3{color:#444; margin-top: 3em;} +h3:first-child{margin-top: 0;} + h4{color:#666;} #imgtop{float:left; margin: 0 20px 40px 0;} @@ -108,13 +110,14 @@ thead{font-size: 130%;} #tbloverview th{} #tbloverview td{} +th{border-radius: 0.7em 0.7em 0 0;} th.prj{background:#f8f8f8;} -th.versioncontrol{background: #ccc;} +th.versioncontrol{background: #ccc; background: linear-gradient(90deg, #ccc,#eee); } th.preview{color:#eee; } th.stage{color:#eee; } th.live{color:#eee; } -tr{background: linear-gradient(#fff,#fff,#fff,#fff,#eee);} -tr:hover{background:#ddd; background: linear-gradient(#ddd,#eee,#ddd);} +tr{/* background: linear-gradient(#fff,#fff,#fff,#fff,#eee); */} +tr:hover{background:#ddd; background: linear-gradient(#eee,#fff,#eee);} td.preview{} td.stage{} diff --git a/public_html/deployment/pages/act_overview.php b/public_html/deployment/pages/act_overview.php index 261bb3a239ff847d30de872cebe7cc2631f15df8..02bc1f6b6ea490e8c790b476af076cbccb98b925 100644 --- a/public_html/deployment/pages/act_overview.php +++ b/public_html/deployment/pages/act_overview.php @@ -32,25 +32,23 @@ if (!array_key_exists("prj", $aParams)) { $oPrj = new project($aParams["prj"]); $sOut = ' ' . $oPrj->renderVisual() . ' - <div style="clear: both;"></div><br><br><br> + <div style="clear: both;"></div> <h3 id="h3repo">' . t("repositoryinfos") . '</h3> <div style="max-width: 40em;"> ' . $oPrj->renderRepoInfo() . ' - ' . ($oPrj->canAcceptPhase() ? $oPrj->renderLink("build") : '') . '<br> + ' . ($oPrj->canAcceptPhase() ? $oPrj->renderLink("build") : '') . ' </div> - <br><br> <h3 id="h3versions">' . t("packages") . '</h3> - ' . $oPrj->renderVersionUsage() . '<br><br>'; + ' . $oPrj->renderVersionUsage(); if ($oPrj->getActivePhases()) { $sOut.=' <h3 id="h3phases">' . t("phases") . '</h3> <p>' . t("page-overview-phase-infos") . '</p> - ' . $oPrj->renderPhaseInfo() . '<br> - <br><br> + ' . $oPrj->renderPhaseInfo() . ' '; } else { $sOut.='<h3 id="h3phases">' . t("phases") . '</h3>' diff --git a/public_html/webservice/sws-config_example.json b/public_html/webservice/sws-config_example.json new file mode 100644 index 0000000000000000000000000000000000000000..0048074041f605b3c320c8f40a4b0b5a27a5ccb3 --- /dev/null +++ b/public_html/webservice/sws-config_example.json @@ -0,0 +1,13 @@ +{ + "options": { + "enableGui": 0 + }, + "classes": { + "Actionlog": { + "file": "actionlog.class.php", + "actions": { + "getLogs": {} + } + } + } +} \ No newline at end of file