<?php
/**
 * Openbizx Framework
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @package   openbiz.bin.data.private
 * @copyright Copyright (c) 2005-2011, Rocky Swen
 * @license   http://www.opensource.org/licenses/bsd-license.php
 * @link      http://www.phpopenbiz.org/
 * @version   $Id: BizDataObj_SQLHelper.php 3994 2011-04-28 12:39:54Z jixian2003 $
 */

namespace Openbizx\Data\Tools;

use Openbizx\Openbizx;
use Openbizx\Data\BizDataSql;
use Openbizx\Core\Expression;

/**
 * Class BizDataObj_SQLHelper takes care of building sql for BizDataObj
 * BizDataObj_SQLHelper is singleton object
 *
 * @package openbiz.bin.data.private
 * @author Rocky Swen
 * @copyright Copyright (c) 2005-2009
 */
class BizDataObj_SQLHelper
{

    /**
     *
     * @var BizDataSql
     */
    private $_dataSqlObj = null;
    private $_dataSqlObjList;

    /**
     *
     * @var BizDataObj_SQLHelper
     */
    private static $_instance = null;
    private $_doRuleCache;

    /**
     * Get the singleton instance
     *
     * @return BizDataObj_SQLHelper BizDataObj_SQLHelper object
     */
    public static function instance()
    {
        if (self::$_instance == null)
            self::$_instance = new BizDataObj_SQLHelper();
        return self::$_instance;
    }

    /**
     * Get curent BizDataSql object, if object=null, create new object
     *
     * @return BizDataSql
     */
    protected function getDataSqlObj()
    {
        if (!$this->_dataSqlObj)
            $this->_dataSqlObj = new BizDataSql();
        return $this->_dataSqlObj;
    }

    /**
     * Get new BizDataSql object and store on internal variable (current object)
     *
     * @return BizDataSql
     */
    protected function getNewDataSqlObj($dataObj = null)
    {
        if ($dataObj) {
            $doName = $dataObj->objectName;
            if (!isset($this->_dataSqlObjList[$doName])) {
                $this->_dataSqlObjList[$doName] = new BizDataSql();
            }
            $this->_dataSqlObj = $this->_dataSqlObjList[$doName];
        } else {
            $this->_dataSqlObj = null;
            $this->_dataSqlObj = new BizDataSql();
        }
        return $this->_dataSqlObj;
    }

    /**
     * Build the Select SQL statement based on the fields and search/sort rule
     *
     * @param BizDataObj $dataObj
     * @return void
     */
    public function buildQuerySQL($dataObj)
    {
        //echo "buildQuerySQL ".$dataObj->objectName."\n";
        // TODO: the same dataobj re-uses the same datasqlobj ...
        // build the SQL statement based on the fields and search rule
        $dataSqlObj = $this->getNewDataSqlObj($dataObj);

        if ($dataSqlObj->isfresh()) {
            // add table
            $dataSqlObj->addMainTable($dataObj->mainTableName);
            // add join table
            if ($dataObj->tableJoins) {
                foreach ($dataObj->tableJoins as $tableJoin) {
                    $tbl_col = $dataSqlObj->addJoinTable($tableJoin, $this);
                }
            }
            // add columns
            foreach ($dataObj->bizRecord as $bizField) {
                if ($bizField->ignoreInQuery) // field to be ignore in query - save memory
                    continue;
                if ($bizField->column && $bizField->type == "Blob")   // ignore blob column
                    continue;
                if ($bizField->column && !$bizField->sqlExpression && (strpos($bizField->column, ',') == 0))
                    $dataSqlObj->addTableColumn($bizField->join, $bizField->column, $bizField->aliasName);
                if ($bizField->sqlExpression) {
                    $dataSqlObj->addSqlExpression($this->_convertSqlExpression($dataObj, $bizField->sqlExpression), $bizField->aliasName);
                }
            }
        }
        $dataSqlObj->resetSQL();

        // append DataPerm in the WHERE clause
        if ($dataObj->dataPermControl == 'Y') {
            $svcObj = Openbizx::getService(OPENBIZ_DATAPERM_SERVICE);
            $hasOwnerField = $this->_hasOwnerField($dataObj);
            $dataPermSQLRule = $svcObj->buildSqlRule($dataObj, 'select', $hasOwnerField);
            $sqlSearchRule = $this->_ruleToSql($dataObj, $dataPermSQLRule);
            $dataSqlObj->addSqlWhere($sqlSearchRule);
        }

        // append QueryPameters in the WHERE clause
        foreach ($dataObj->getQueryParameters() as $fieldName => $value) {
            $queryRule = queryParamToRule($fieldName, $value, $dataObj);
            $sqlSearchRule = $this->_ruleToSql($dataObj, $queryRule);
            $dataSqlObj->addSqlWhere($sqlSearchRule);
        }

        // append SearchRule in the WHERE clause
        $sqlSearchRule = $this->_ruleToSql($dataObj, $dataObj->searchRule);
        $dataSqlObj->addSqlWhere($sqlSearchRule);

        // append SearchRule in the ORDER BY clause
        $sqlSortRule = $this->_ruleToSql($dataObj, $dataObj->sortRule);
        $dataSqlObj->addOrderBy($sqlSortRule);

        // append SearchRule in the other SQL clause
        $sqlOtherSQLRule = $this->_ruleToSql($dataObj, $dataObj->otherSQLRule);
        $dataSqlObj->addOtherSQL($sqlOtherSQLRule);

        // append SearchRule in the AccessRule clause
        $sqlAccessSQLRule = $this->_ruleToSql($dataObj, $dataObj->accessRule);
        $dataSqlObj->addSqlWhere($sqlAccessSQLRule);

        // add association to SQL
        if ($dataObj->association["AsscObjName"] != "" && $dataObj->association["FieldRefVal"] == "") {
            $asscObj = Openbizx::getObject($dataObj->association["AsscObjName"]);
            $dataObj->association["FieldRefVal"] = $asscObj->getFieldValue($dataObj->association["FieldRef"]);
        }

        if ($dataObj->association["AsscObjName"] != "" && $dataObj->association["FieldRefVal2"] == "") {
            $asscObj = Openbizx::getObject($dataObj->association["AsscObjName"]);
            $dataObj->association["FieldRefVal2"] = $asscObj->getFieldValue($dataObj->association["FieldRef2"]);
        }

        if ($dataObj->association["Relationship"] == "Self-Self") {
            $dataObj->association["ParentRecordIdColumn"] = $dataObj->getField("Id")->column;
        }
        $dataSqlObj->addAssociation($dataObj->association);

        // apply _ruleToSql to JoinCondition if any
        if ($dataSqlObj->hasJoinCondition) {
            $dataSqlObj->setTableJoinStm($this->_ruleToSql($dataObj, $dataSqlObj->getTableJoinStm()));
        }

        $querySQL = $dataSqlObj->getSqlStatement() . " ";

        //echo $querySQL."###\n";
        return $querySQL;
    }

    /**
     * Build update sql
     * UPDATE table SET col1=val1, col2=val2 ...
     * WHERE idcol1='id1' AND idcol2='id2'
     *
     * @param BizDataObj $dataObj
     * @return mixed
     * @todo consider the record data on main table as well as join table, this function can return a sql array.
     * */
    public function buildUpdateSQL($dataObj)
    {
        // generate column value pairs. ignore those whose inputValue=fieldValue
        $sqlFlds = $dataObj->bizRecord->getToSaveFields('UPDATE');
        $colval_pairs = null;
        foreach ($sqlFlds as $field) {
            $col = $field->column;

            // ignore empty vallue for Date or Datetime
            if (($field->value == "" && $field->oldValue == "") && ($field->type == "Date" || $field->type == "Datetime"))
                continue;

            if ($field->valueOnUpdate != "") // ignore ValueOnUpdate field first
                continue;

            if ($field->isLobField())  // take care of blob/clob type later
                continue;

            // ignore the column where old value is same as new value; set the column only if new value is diff than the old value
            if ($field->oldValue == $field->value)
                continue;

            $_val = $field->getSqlValue();
            $colval_pairs[$col] = $_val; //($_val===null || $_val === '') ? "''" : $_val;
        }
        if ($colval_pairs == null)
            return false;

        // take care value on update fields only
        foreach ($sqlFlds as $field) {
            $col = $field->column;
            if ($field->valueOnUpdate != "") {
                $_val = $field->getValueOnUpdate();
                $colval_pairs[$col] = $_val; //($_val===null || $_val === '') ? "''" : $_val;
            }
        }

        $db = $dataObj->getDBConnection('WRITE');
        $sql = "";
        foreach ($colval_pairs as $col => $val) {
            //$queryString = QueryStringParam::formatQueryString("`$col`", "=", $val);
            $queryString = "`$col`=" . $db->quote($val);
            if ($sql != "") {
                $sql .= ", $queryString";
            } else {
                $sql .= $queryString;
            }
        }

        $sql = "UPDATE `" . $dataObj->mainTableName . "` SET " . $sql;

        $whereStr = $dataObj->bizRecord->getKeySearchRule(true, true);  // use old value and column name
        $sql .= " WHERE " . $whereStr;

        // append DataPerm in the WHERE clause
        if ($dataObj->dataPermControl == 'Y') {
            $svcObj = Openbizx::getService(OPENBIZ_DATAPERM_SERVICE);
            $hasOwnerField = $this->_hasOwnerField($dataObj);
            $dataPermSQLRule = $svcObj->buildSqlRule($dataObj, 'update', $hasOwnerField);
            $sqlSearchRule = $this->_convertSqlExpressionWithoutPrefix($dataObj, $dataPermSQLRule);
            if ($whereStr != '') {
                $sql .= ' AND ' . $sqlSearchRule;
            } else {
                $sql .= $sqlSearchRule;
            }
        }
        return $sql;
    }

    public function buildUpdateSQLwithCondition($dataObj, $setValue, $condition = null)
    {

        $setValueStr = $this->_convertSqlExpressionWithoutPrefix($dataObj, $setValue);
        $sql = "UPDATE `" . $dataObj->mainTableName . "` SET " . $setValueStr;
        if ($condition) {
            $whereStr = $this->_convertSqlExpressionWithoutPrefix($dataObj, $condition);
            $sql .= " WHERE " . $whereStr;
        }

        // append DataPerm in the WHERE clause
        if ($dataObj->dataPermControl == 'Y') {
            $svcObj = Openbizx::getService(OPENBIZ_DATAPERM_SERVICE);
            $hasOwnerField = $this->_hasOwnerField($dataObj);
            $dataPermSQLRule = $svcObj->buildSqlRule($dataObj, 'update', $hasOwnerField);
            $sqlSearchRule = $this->_convertSqlExpressionWithoutPrefix($dataObj, $dataPermSQLRule);
            if ($whereStr != '') {
                $sql .= ' AND ' . $sqlSearchRule;
            } else {
                $sql .= $sqlSearchRule;
            }
        }
        return $sql;
    }

    /**
     * Build delete-sql DELETE FROM table WHERE idcol1='id1' AND idcol2='id2'
     *
     * @param BizDataObj $dataObj
     * @return string SQL statement
     */
    public function buildDeleteSQL($dataObj)
    {
        $sql = "DELETE FROM `" . $dataObj->mainTableName . "`";
        $whereStr = $dataObj->bizRecord->getKeySearchRule(false, true);  // use cur value and column name
        $sql .= " WHERE " . $whereStr;
        // append DataPerm in the WHERE clause
        if ($dataObj->dataPermControl == 'Y') {
            $svcObj = Openbizx::getService(OPENBIZ_DATAPERM_SERVICE);
            $hasOwnerField = $this->_hasOwnerField($dataObj);
            $dataPermSQLRule = $svcObj->buildSqlRule($dataObj, 'delete', $hasOwnerField);
            $sqlSearchRule = $this->_convertSqlExpressionWithoutPrefix($dataObj, $dataPermSQLRule);
            if ($whereStr != '') {
                $sql .= ' AND ' . $sqlSearchRule;
            } else {
                $sql .= $sqlSearchRule;
            }
        }
        return $sql;
    }

    public function buildDeleteSQLwithCondition($dataObj, $condition = null)
    {

        $sql = "DELETE FROM `" . $dataObj->mainTableName . "`";
        if ($condition) {
            $whereStr = $this->_convertSqlExpressionWithoutPrefix($dataObj, $condition);
            $sql .= " WHERE " . $whereStr;
        }
        // append DataPerm in the WHERE clause
        if ($dataObj->dataPermControl == 'Y') {
            $svcObj = Openbizx::getService(OPENBIZ_DATAPERM_SERVICE);
            $hasOwnerField = $this->_hasOwnerField($dataObj);
            $dataPermSQLRule = $svcObj->buildSqlRule($dataObj, 'delete', $hasOwnerField);
            $sqlSearchRule = $this->_convertSqlExpressionWithoutPrefix($dataObj, $dataPermSQLRule);
            if ($whereStr != '') {
                $sql .= ' AND ' . $sqlSearchRule;
            } else {
                $sql .= $sqlSearchRule;
            }
        }
        return $sql;
    }

    /**
     * Build insert-sql
     * INSERT INTO table_name (column1, column2,...) VALUES (value1, value2,....)
     *
     * @param BizDataObj $dataObj
     * @param array $joinValues array of join values
     * @return string Insert-SQL statement
     */
    public function buildInsertSQL($dataObj, $joinValues = null)
    {
        // generate column value pairs.
        $sqlFields = $dataObj->bizRecord->getToSaveFields('CREATE');

        $dbInfo = Openbizx::$app->getConfiguration()->getDatabaseInfo($dataObj->databaseAliasName);
        $dbType = $dbInfo["Driver"];

        $sql_col = "";
        $sql_val = "";
        $db = $dataObj->getDBConnection('WRITE');

        /* @var $field BizField */
        foreach ($sqlFields as $field) {
            $col = $field->column;

            // if Field Id has null value and Id is an identity type, remove the Id's column from the array
            if ($field->objectName == "Id" && $dataObj->idGeneration == "Identity") {
                continue;
            }

            if ($field->isLobField()) {  // special value for blob/clob type
                $_val = $field->getInsertLobValue($dbType);
            } else {
                $_val = $field->getSqlValue();
                if ($_val == '' && $field->valueOnCreate != "") {
                    $_val = $field->getValueOnCreate();
                }
            }

            //if (!$_val || $_val == '') continue;
            // modified by jixian for not ignore 0 value
            if ($_val === '') {
                continue;
            }
            $sql_col .= "`" . $col . "`, ";
            $sql_val .= $db->quote($_val) . ", ";
            //$sql_val .= QueryStringParam::formatQueryValue($_val). ", ";
        }

        // if joinValues is given then add join values in to the main table InsertSQL.
        if (is_array($joinValues)) {
            foreach ($joinValues as $joinColumn => $joinValue) {
                if (!$joinValue || $joinValue == '') {
                    continue;
                }
                $sql_col .= "`" . $joinColumn . "`, ";
                $sql_val .= "'" . $joinValue . "', ";
            }
        }

        $sql_col = substr($sql_col, 0, -2);
        $sql_val = substr($sql_val, 0, -2);

        $sql = "INSERT INTO  `" . $dataObj->mainTableName . "` (" . $sql_col . ") VALUES (" . $sql_val . ")";
        return $sql;
    }

    public function ruleToSql($dataObj, $rule)
    {
        return _ruleToSql($dataObj, $rule);
    }

    /**
     * Convert search/sort rule to sql clause, replace [fieldName] with table.column
     * openbiz SQL expression as :
     * "[fieldName] opr 'Value' AND/OR [fieldName] opr 'Value'...". "()" is valid syntax
     *
     * @param BizDataObj $dataObj
     * @param string $rule "[fieldName] ..."
     * @return string sql statement
     * */
    private function _ruleToSql($dataObj, $rule)
    {
        $cacheKey = $dataObj->objectName . "-" . $rule;
        if (isset($this->_doRuleCache[$cacheKey])) {
            return $this->_doRuleCache[$cacheKey];
        }
        //echo " _ruleToSql ".$dataObj->objectName." ". $rule."\n";
        $dataSqlObj = $this->getDataSqlObj();

        $rule = Expression::evaluateExpression($rule, $dataObj);

        // replace all [field] with table.column
        // use regexp to find [] parts and replace with fields
        if (!preg_match_all("/\[([0-9a-zA-Z_]+)\]/", $rule, $m)) {
            $this->_doRuleCache[$cacheKey] = $rule;
            return $rule;
        }
        foreach ($m[1] as $fld) {
            $bizField = $dataObj->getField($fld);
            if (!$bizField)
                continue;
            $fld_pattern = "[" . $bizField->objectName . "]";
            if ($bizField->column && (strpos($bizField->column, ',') != 0)) {  // handle composite key.
                if (!preg_match('/\[' . $bizField->objectName . '\].*=.*\'(.+)\'/', $rule, $matches))
                    continue; //print_r($matches);
                $keyval = $matches[1];
                // replace the matching part [compkey field]='value'
                $compkey_value = $this->_compKeyRuleToSql($bizField->column, $keyval);
                $rule = $str_replace($matches[0], $compkey_value, $rule);
            }
            else {
                if ($bizField->aliasName) {
                    $rule = str_replace($fld_pattern, $bizField->aliasName, $rule);
                } elseif ($bizField->sqlExpression) {
                    $rule = str_replace($fld_pattern, $bizField->sqlExpression, $rule);
                } else {
                    $tableColumn = $dataSqlObj->getTableColumn($bizField->join, $bizField->column);
                    $rule = str_replace($fld_pattern, $tableColumn, $rule);
                }
            }
        }

        $this->_doRuleCache[$cacheKey] = $rule;
        return $rule;
    }

    //TODO: refactor:rename, what's mean of comp?
    /**
     *
     * @param string $compColumn
     * @param string $compValue
     * @return string SQL rule statement
     */
    private function _compKeyRuleToSql($compColumn, $compValue)
    {
        $dataSqlObj = $this->getDataSqlObj();
        $colArr = explode(",", $compColumn);
        $valArr = explode(CK_CONNECTOR, $compValue);
        $sql = "";
        for ($i = 0; $i < count($colArr); $i++) {
            if ($i > 0)
                $sql .= "and";
            $tableColumn = $dataSqlObj->getTableColumn("", $colArr[$i]);
            if ($valArr[$i] == '')
                $sql .= " ($tableColumn = '" . $valArr[$i] . "' OR $tableColumn is null) ";
            else
                $sql .= " $tableColumn = '" . $valArr[$i] . "' ";
        }
        return $sql;
    }

    /**
     * Convert Sql Expression
     * Replace [field name] in the SQL expression with table_alias.column
     *
     * @param BizDataObj $dataObj - the instance of BizDataObj
     * @param string $sqlExpr - SQL expression supported by the database engine. The syntax is FUNC([FieldName1]...[FieldName2]...)
     * @return string real sql expression with column names
     * */
    private function _convertSqlExpression($dataObj, $sqlExpr)
    {
        $dataSqlObj = $this->getDataSqlObj();
        $sqlstr = $sqlExpr;
        $startpos = 0;
        while (true) {
            $fieldname = substr_lr($sqlstr, "[", "]", $startpos);
            if ($fieldname == "")
                break;
            else {
                $bizField = $dataObj->bizRecord->get($fieldname);
                $tableColumn = $dataSqlObj->getTableColumn($bizField->join, $bizField->column);
                $sqlstr = str_replace("[$fieldname]", $tableColumn, $sqlstr);
                $startpos = strpos($sqlstr, '['); // Move startpos to the first [ (if it exists) in order to be detect by next itteration
            }
        }
        return $sqlstr;
    }

    private function _convertSqlExpressionWithoutPrefix($dataObj, $sqlExpr)
    {
        $dataSqlObj = $this->getDataSqlObj();
        $sqlstr = $sqlExpr;
        $startpos = 0;
        while (true) {
            $fieldname = substr_lr($sqlstr, "[", "]", $startpos);
            if ($fieldname == "")
                break;
            else {
                $bizField = $dataObj->bizRecord->get($fieldname);
                $tableColumn = "`" . $bizField->column . "`";
                $sqlstr = str_replace("[$fieldname]", $tableColumn, $sqlstr);
                $startpos = strpos($sqlstr, '['); // Move startpos to the first [ (if it exists) in order to be detect by next itteration
            }
        }
        return $sqlstr;
    }

    private function _hasOwnerField($dataObj)
    {
        $fld = $dataObj->getField('owner_id');
        if ($fld) {
            return true;
        } else {
            return false;
        }
    }

}

/**
 * Convert the user input on a given fieldcontrol in query mode to search rule
 *
 * @param string $fieldName - field name
 * @param string $value - field value
 * @param EasyForm $formObj
 * @return string - searchRule
 */
function queryParamToRule($fieldName, $value, $dataObj)
{
    // todo: should check single quote for nonoperators clauses
    // find locations for all sql key words
    // search for starting ' and closing ' pair, check if sql key word in the pair

    $val = trim($value);
    // unformat the data
    $bizField = $dataObj->getField($fieldName);
    $val = Openbizx::$app->getTypeManager()->formattedStringToValue($bizField->type, $bizField->format, $val);
    // check " AND ", " OR "
    if (($pos = strpos($val, " AND ")) !== false) {
        $inputArr = explode(" AND ", $val);
        $retStr = null;
        foreach ($inputArr as $v)
            $retStr .= ($retStr) ? " AND " . inputValToRule($fieldName, $v, $formObj) : inputValToRule($fieldName, $v, $formObj);
        return $retStr;
    } else if (($pos = strpos($val, " OR ")) !== false) {
        $inputArr = explode(" OR ", $val);
        $retStr = null;
        foreach ($inputArr as $v)
            $retStr .= ($retStr) ? " OR " . inputValToRule($fieldName, $v, $formObj) : inputValToRule($fieldName, $v, $formObj);
        return "(" . $retStr . ")";
    }

    // check >=, >, <=, <, =
    if (($pos = strpos($val, "<>")) !== false || ($pos = strpos($val, "!=")) !== false) {
        $opr = "<>";
        $oprlen = 2;
    } else if (($pos = strpos($val, ">=")) !== false) {
        $opr = ">=";
        $oprlen = 2;
    } else if (($pos = strpos($val, ">")) !== false) {
        $opr = ">";
        $oprlen = 1;
    } else if (($pos = strpos($val, "<=")) !== false) {
        $opr = "<=";
        $oprlen = 2;
    } else if (($pos = strpos($val, "<")) !== false) {
        $opr = "<";
        $oprlen = 1;
    } else if (($pos = strpos($val, "=")) !== false) {
        $opr = "=";
        $oprlen = 1;
    }
    if ($opr) {
        $val = trim(substr($val, $pos + $oprlen));
    }

    if (strpos($val, "*") !== false) {
        $opr = "LIKE";
        $val = str_replace("*", "%", $val);
    }
    //if (strpos($val, "'") !== false) {   // not needed since addslashes() is called before
    //   $val = str_replace("'", "\\'", $val);
    //}
    if (!$opr)
        $opr = "=";

    // set the query param
    //$queryString = QueryStringParam::formatQueryString("[$fieldName]", $opr, $realValue);
    //return $queryString;
    $db = $dataObj->getDBConnection("READ");
    return "[" . $fieldName . "] " . $opr . $db->quote($val);
}

/**
 * substr_lr() - help function (helper).
 * Get the sub string whose left and right boundary character is $left and $right.
 * The search is in $str, starting from position of $startpos.
 * If $findfirst is true, $left must be the charater on the $startpos.
 *
 * @return string
 * */
function substr_lr(&$str, $left, $right, &$startpos, $findfirst = false)
{
    $pos0 = strpos($str, $left, $startpos);
    if ($pos0 === false)
        return false;
    $tmp = trim(substr($str, $startpos, $pos0 - $startpos));
    if ($findfirst && $tmp != "")
        return false;

    $posleft = $pos0 + strlen($left);
    while (true) {
        $pos1 = strpos($str, $right, $posleft);
        if ($pos1 === false) {
            if (trim($right) == "") {
                $pos1 = strlen($str); // if right is whitespace
                break;
            } else
                return false;
        }
        else {   // avoid \$right is found
            if (substr($str, $pos1 - 1, 1) == "\\")
                $posleft = $pos1 + 1;
            else
                break;
        }
    }

    $startpos = $pos1 + strlen($right);
    $retStr = substr($str, $pos0 + strlen($left), $pos1 - $pos0 - strlen($left));
    return $retStr;
}

?>


<?php

namespace Interpro\Entrance\Agents;

use Interpro\Core\Contracts\Mediator\DestructMediator;
use Interpro\Core\Contracts\Taxonomy\Taxonomy;
use Interpro\Core\Ref\ARef;
use Interpro\Core\Taxonomy\Enum\TypeMode;
use Interpro\Entrance\Contracts\CommandAgent\DestructAgent as DestructAgentInterface;
use Interpro\Entrance\Exception\EntranceException;

class DestructAgent implements DestructAgentInterface
{
    private $destructMediator;
    private $taxonomy;

    public function __construct(
        DestructMediator $destructMediator,
        Taxonomy $taxonomy
    )
    {
        $this->destructMediator = $destructMediator;
        $this->taxonomy         = $taxonomy;
    }

    /**
     * @param string $type_name
     * @param int $id
     *
     * @return void
     */
    public function delete($type_name, $id = 0)
    {
        if(!is_string($type_name))
        {
            throw new EntranceException('Название А-типа) должно быть задано строкой!');
        }

        if(!is_int($id))
        {
            throw new EntranceException('Id А-типа должно быть задано целым числом!');
        }

        $type = $this->taxonomy->getType($type_name);

        $typeMode = $type->getMode();

        if($typeMode !== TypeMode::MODE_A)
        {
            throw new EntranceException('Агент удаления может удалять только тип (A) уровня, передан тип:'.$type->getName().'('.$typeMode.')!');
        }

        $family = $type->getFamily();

        $destructor = $this->destructMediator->getADestructor($family);

        $ref = new ARef($type, $id);

        $destructor->delete($ref);
    }

}


<?php
/**
 * Created by PhpStorm.
 * User: tamaskovacs
 * Date: 2017. 01. 27.
 * Time: 21:45
 */

namespace Callisto;

use Psr\Http\Message\StreamInterface;

abstract class Psr7Stream implements StreamInterface
{
	/**
	 * Connection resource.
	 *
	 * @var resource
	 */
	protected $connection;

	/**
	 * @throws \Exception
	 */
	public function __toString()
	{
		throw new \RuntimeException('Cannot read the entire stream.');
	}

	/**
	 * Closes the stream and any underlying resources.
	 *
	 * @return void
	 */
	public function close() : void
	{
		fclose($this->connection);
	}

	/**
	 * Separates any underlying resources from the stream.
	 *
	 * After the stream has been detached, the stream is in an unusable state.
	 *
	 * @return resource|null Underlying PHP stream, if any
	 */
	public function detach()
	{
		$this->close();
		return null;
	}

	/**
	 * We do not know the size of the stream.
	 * @return void
	 * @throws \RuntimeException
	 */
	public function getSize() : void
	{
		throw new \RuntimeException('We no not know the size of the stream.');
	}

	/**
	 * We do not have the position of the cursor.
	 *
	 * @return void
	 * @throws \RuntimeException on error.
	 */
	public function tell() : void
	{
		throw new \RuntimeException('We do not know the position of the cursor.');
	}

	/**
	 * Returns true if the stream is at the end of the stream.
	 *
	 * @return bool
	 */
	public function eof() : bool
	{
		return feof($this->connection);
	}

	/**
	 * The stream is not seekable.
	 *
	 * @return bool
	 */
	public function isSeekable() : bool
	{
		return false;
	}

	/**
	 * The stream is not seekable.
	 *
	 * @throws \RuntimeException on failure.
	 */
	public function seek($offset, $whence = SEEK_SET) : void
	{
		throw new \RuntimeException('The stream is not seekable.');
	}

	/**
	 * The stream cannot be rewind.
	 *
	 * @throws \RuntimeException on failure.
	 */
	public function rewind() : void
	{
		throw new \RuntimeException('The stream is not seekable therefore it cannot be rewind.');
	}

	/**
	 * Returns whether or not the stream is writable.
	 *
	 * @return bool
	 */
	public function isWritable() : bool
	{
		return true;
	}

	/**
	 * Write data to the stream.
	 *
	 * @param string $string The string that is to be written.
	 * @return int Returns the number of bytes written to the stream.
	 * @throws \RuntimeException on failure.
	 */
	public function write($string) : int
	{
		$length = strlen($string);
		fwrite($this->connection, $string, $length);

		return $length;
	}

	/**
	 * Returns whether or not the stream is readable.
	 *
	 * @return bool
	 */
	public function isReadable() : bool
	{
		return true;
	}

	/**
	 * Read data from the stream.
	 *
	 * @param int $length Read up to $length bytes from the object and return
	 *     them. Fewer than $length bytes may be returned if underlying stream
	 *     call returns fewer bytes.
	 * @return string Returns the data read from the stream, or an empty string
	 *     if no bytes are available.
	 * @throws \RuntimeException if an error occurs.
	 */
	public function read($length)
	{
		return fread($this->connection, $length);
	}

	/**
	 * Reads the next line fron the stream.
	 *
	 * @param int $length Read up to $length bytes from the object and return
	 *     them. Fewer than $length bytes may be returned if underlying stream
	 *     call returns fewer bytes.
	 * @return string Returns the data read from the stream, or an empty string
	 *     if no bytes are available.
	 * @throws \RuntimeException if an error occurs.
	 */
	public function readLine($length = 1024) : string
	{
		return (string)fgets($this->connection, $length);
	}

	/**
	 * Returns the remaining contents in a string
	 *
	 * @return string
	 * @throws \RuntimeException if unable to read or an error occurs while
	 *     reading.
	 */
	public function getContents()
	{
		throw new \RuntimeException('We cannot return the remaining contents of the stream.');
	}

	/**
	 * Get stream metadata as an associative array or retrieve a specific key.
	 *
	 * The keys returned are identical to the keys returned from PHP's
	 * stream_get_meta_data() function.
	 *
	 * @link http://php.net/manual/en/function.stream-get-meta-data.php
	 * @param string|null $key Specific metadata to retrieve.
	 * @return array|mixed|null Returns an associative array if no key is
	 *     provided. Returns a specific key value if a key is provided and the
	 *     value is found, or null if the key is not found.
	 */
	public function getMetadata($key = null)
	{
		return stream_get_meta_data($this->connection);
	}
}


<?PHP

/**
 * Openbizx Framework
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @package   openbiz.bin.easy.element
 * @copyright Copyright (c) 2005-2011, Rocky Swen
 * @license   http://www.opensource.org/licenses/bsd-license.php
 * @link      http://www.phpopenbiz.org/
 * @version   $Id: EditCombobox.php 2871 2010-12-16 08:21:22Z rockys $
 */

namespace Openbizx\Easy\Element;

use Openbizx\Core\Expression;

/**
 * EditCombobox class is element for EditCombobox
 *
 * @package openbiz.bin.easy.element
 * @author Rocky Swen
 * @copyright Copyright (c) 2005-2009
 * @access public
 */
class EditCombobox extends OptionElement
{

    public $blankOption;
    protected $widthInput = "128px";
    protected $onchange = "";

    /**
     * Read array meta data, and store to meta object
     *
     * @param array $xmlArr
     * @return void
     */
    protected function readMetaData(&$xmlArr)
    {
        parent::readMetaData($xmlArr);
        $this->blankOption = isset($xmlArr["ATTRIBUTES"]["BLANKOPTION"]) ? $xmlArr["ATTRIBUTES"]["BLANKOPTION"] : null;
    }

    /**
     * Get style of element
     *
     * @return string style of Element
     */
    protected function getStyle()
    {
        $htmlClass = $this->cssClass ? "class='" . $this->cssClass . "' " : "class='editcombobox'";
        /*
          $width = $this->width ? $this->width : 146;
          $this->widthInput = ($width-18).'px';
          $this->width = $width.'px';
          $style = "position: absolute; width: $this->width; z-index: 1; clip: rect(auto, auto, auto, $this->widthInput);";
         */
        if ($this->style)
            $style .= $this->style;
        if (!isset($style) && !$htmlClass)
            return null;
        if (isset($style)) {
            $formObj = $this->getFormObj();
            $style = Expression::evaluateExpression($style, $formObj);
            $style = "style='$style'";
        }
        if ($htmlClass) {
            $style = $htmlClass . " " . $style;
        }
        return $style;
    }

    /**
     * Render element, according to the mode
     *
     * @return string HTML text
     */
    public function render()
    {
        $fromList = array();
        $this->getFromList($fromList);
        $valueArr = explode(',', $this->value);
        $disabledStr = ($this->getEnabled() == "N") ? "disabled=\"true\"" : "";
        $style = $this->getStyle();
        $func = $this->getFunction();
        $selName = $this->objectName . "_sel";
        //$onchange = "onchange=\"$('$inputName').value=this.value;".$this->onchange."\"";
        $onChange = "onchange=\"$('$this->objectName').value=this.value; $('$this->objectName').triggerEvent('change');\" $func";

        $sHTML = "
\n";
        $sHTML .= "<select name=\"" . $selName . "\" id=\"" . $selName . "\" $disabledStr $this->htmlAttr $onChange>\n";

        if ($this->blankOption) { // ADD a blank option
            $entry = explode(",", $this->blankOption);
            $text = $entry[0];
            $value = ($entry[1] != "") ? $entry[1] : null;
            $entryList = array(array("val" => $value, "txt" => $text));
            $fromList = array_merge($entryList, $fromList);
        }

        foreach ($fromList as $opt) {
            $test = array_search($opt['val'], $valueArr);
            if ($test === false) {
                $selectedStr = '';
            } else {
                $selectedStr = "selected";
                $selVal = $opt['val'];
            }
            $sHTML .= "<option value=\"" . $opt['val'] . "\" $selectedStr>" . $opt['txt'] . "</option>\n";
        }

        if (!$selVal)
            $selVal = $this->value ? $this->value : $this->getDefaultValue();

        $sHTML .= "</select>\n";
        $sHTML .= "
<input id=\"$this->objectName\" name=\"$this->objectName\" type=\"text\" value=\"$selVal\" $func/>
\n";
        $sHTML .= "
\n";

        return $sHTML;
    }

}

?>


<?php

namespace Environaut\Config\Reader\Dom;

/**
 * Custom \DOMElement implementation for Environaut to have some
 * convenience methods to get child nodes etc. Please be aware, that
 * by default these methods use the Environaut default namespace URI.
 *
 * @todo make namespace URI configurable for convenience methods
 */
class DomElement extends \DOMElement implements \IteratorAggregate
{
    /**
     * @var DomDocument
     */
    protected $ownerDocument;

    /**
     * Returns the nodeValue of the element.
     *
     * @return string nodeValue of the element
     */
    public function __toString()
    {
        return $this->getValue();
    }

    /**
     * Returns the nodeName of the element.
     *
     * @return string nodeName of the element
     */
    public function getName()
    {
        return $this->nodeName;
    }

    /**
     * Returns the nodeValue of the element.
     *
     * @return string nodeValue of the element
     */
    public function getValue()
    {
        return $this->nodeValue;
    }

    /**
     * Returns a \DOMNodeList of all child elements of the element.
     *
     * @return \DOMNodeList (Traversable) of all child elements
     */
    public function getIterator()
    {
        return $this->getChildNodes();
    }

    /**
     * Returns a \DOMNodeList of all child elements of the element.
     *
     * @return \DOMNodeList of all child elements
     */
    public function getChildNodes()
    {
        $prefix = $this->ownerDocument->getDefaultNamespacePrefix();

        if ($prefix) {
            return $this->ownerDocument->getXpath()->query(sprintf('child::%s:*', $prefix), $this);
        } else {
            return $this->ownerDocument->getXpath()->query('child::*', $this);
        }
    }

    /**
     * Returns the value of the given attribute or returns the given
     * default value if the attribute is missing.
     *
     * @param string $name name of attribute
     * @param mixed $default_value value to return if attribute is missing
     *
     * @return mixed string value of attribute or default_value if attribute is not found or empty
     */
    public function getAttributeValue($name, $default_value = null)
    {
        $value = parent::getAttribute($name);

        if ($value === '') {
            $value = $default_value;
        }

        return $value;
    }

    /**
     * Returns all attributes including their values for the element.
     *
     * @return array of attributes (name => value pairs)
     */
    public function getAttributes()
    {
        $attributes = array();

        foreach ($this->ownerDocument->getXpath()->query('@*', $this) as $attribute) {
            $attributes[$attribute->localName] = $attribute->nodeValue;
        }

        return $attributes;
    }

    /**
     * Returns all child elements of the given name or all children
     * of the element if name is not specified.
     *
     * @param string $name name of child elements to get
     *
     * @return \DOMNodeList of all children
     */
    public function get($name)
    {
        if (!$name) {
            return $this->getChildNodes();
        }

        return $this->getChildren($name);
    }

    /**
     * Determines whether there are children of the element
     * with the given name.
     *
     * @param string $name name of child element to check
     *
     * @return bool true if children of that name exist on the element
     */
    public function has($name)
    {
        return $this->hasChildren($name);
    }

    /**
     * Determines whether there's at least one child node with the given name.
     *
     * @param string $name name of child node
     *
     * @return bool true, if a first child with that name exists
     */
    public function hasChild($name)
    {
        return $this->getChild($name) !== null;
    }

    /**
     * Returns first child of the element with the given name.
     *
     * @param string $name name of element to get
     *
     * @return \DOMNode first child node with the given name
     */
    public function getChild($name)
    {
        $query = 'self::node()[count(child::*[local-name() = "%1$s" and namespace-uri() = "%2$s"]) = 1]/*' .
                '[local-name() = "%1$s" and namespace-uri() = "%2$s"]';

        $node = $this->ownerDocument->getXpath()->query(
            sprintf($query, $name, $this->ownerDocument->getDefaultNamespaceUri()),
            $this
        )->item(0);

        return $node;
    }

    /**
     * Determines whether there are children of the element
     * with the given name.
     *
     * @param string $name name of child element to check
     *
     * @return bool true if children of that name exist on the element
     */
    public function hasChildren($name)
    {
        return $this->countChildren($name) !== 0;
    }

    /**
     * Returns the count of the children with the given name.
     * Special handling for the following names is implemented:
     * - 'paramaters' returns count of all direct 'parameters' OR all 'parameters/parameter' child nodes
     * - 'formatters' returns count of all direct 'formatters' OR all 'formatters/formatter' child nodes
     *
     * @param string $name element name
     *
     * @return int number of child elements of the given name
     */
    public function countChildren($name)
    {
        $query = '';
        $singular_name = null;

        // special nodes of environaut config files where the surrounding plural node
        // may be omitted and the singular nodes be used directly (for less verbose xml)
        if (in_array($name, array('parameters', 'formatters'))) {

            if ($name === 'parameters') {
                $singular_name = 'parameter';
            } elseif ($name === 'formatters') {
                $singular_name = 'formatter';
            }

            $query = 'count(child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"]) + ' .
                    'count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*' .
                    '[local-name() = "%2$s" and namespace-uri() = "%3$s"])';
        } elseif (empty($name)) {
            $query = 'count(child::*[namespace-uri() = "%3$s"])';
        } else {
            $query = 'count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"])';
        }

        $count = (int) $this->ownerDocument->getXpath()->evaluate(
            sprintf($query, $name, $singular_name, $this->ownerDocument->getDefaultNamespaceUri()),
            $this
        );

        return $count;
    }

    /**
     * Returns all child elements of the given name. Special handling for the following names is implemented:
     * - 'paramaters' returns all direct 'parameters' OR all 'parameters/parameter' child nodes
     * - 'formatters' returns all direct 'formatters' OR all 'formatters/formatter' child nodes
     *
     * @param string $name name of child element
     *
     * @return \DOMNodeList of all child elements with the given name in the default namespace
     */
    public function getChildren($name)
    {
        $query = '';
        $singular_name = null;

        // special nodes of environaut config files where the surrounding plural node
        // may be omitted and the singular nodes be used directly (for less verbose xml)
        if (in_array($name, array('parameters', 'formatters'))) {

            if ($name === 'parameters') {
                $singular_name = 'parameter';
            } elseif ($name === 'formatters') {
                $singular_name = 'formatter';
            }

            $query = 'child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"] | ' .
                    'child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*' .
                    '[local-name() = "%2$s" and namespace-uri() = "%3$s"]';
        } else {
            $query = 'child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]';
        }

        $nodes = $this->ownerDocument->getXpath()->query(
            sprintf($query, $name, $singular_name, $this->ownerDocument->getDefaultNamespaceUri()),
            $this
        );

        return $nodes;
    }

    /**
     * Determine whether there's a 'parameters' element as child of the element.
     *
     * @return boolean true if there is a 'parameters' element
     */
    public function hasParameters()
    {
        if ($this->ownerDocument->isEnvironautDocument()) {
            return $this->has('parameters');
        }

        return false;
    }

    /**
     * Returns all (nested) parameters of the element as an associative array.
     *
     * @param array $default array to be used as default
     * @param boolean $literalize whether or not to literalize values like 'true'/'false' by default
     *
     * @return array of associative nested parameters (numerical keys where a 'name' attribute is missing)
     */
    public function getParameters(array $default = array(), $literalize = true)
    {
        $offset = 0;

        if ($this->ownerDocument->isEnvironautDocument()) {
            $elements = $this->get('parameters');
            foreach ($elements as $element) {

                $name = null;
                if (!$element->hasAttribute('name')) {
                    $name = $offset++;
                    $default[$name] = null;
                } else {
                    $name = $element->getAttributeValue('name');
                }

                if ($element->hasParameters()) {
                    $default[$name] = isset($default[$name]) && is_array($default[$name]) ? $default[$name] : array();
                    $default[$name] = $element->getParameters($default[$name], $literalize);
                } else {
                    $default[$name] = $this->getLiteralValue($element);
                }
            }
        }

        return $default;
    }

    /**
     * Depending on the values of the 'literalize' and 'space' attributes of the element
     * the transformed or literal value of the value is returned
     *
     * @param \DOMNode $element element to get a value for
     *
     * @return mixed literalized and/or whitespace preserved value or null if value is empty
     */
    protected function getLiteralValue($element)
    {
        $value = $element->getValue();
        $trimmed_value = trim($value);

        $preserve_whitespace = $element->getAttributeValue('space', 'default') === 'preserve';
        $literalize_value = self::literalize($element->getAttributeValue('literalize')) !== false;

        if ($literalize_value) {
            if ($preserve_whitespace && ($trimmed_value === '' || $value !== $trimmed_value)) {
                $value = $value;
            } else {
                $value = self::literalize($trimmed_value);
            }
        } elseif (!$preserve_whitespace) {
            $value = $trimmed_value;
            if ($value === '') {
                $value = null;
            }
        }

        return $value;
    }

    /**
     * Returns the literalized value, that is:
     * - 'on|yes|true' will be boolean TRUE
     * - 'off|no|false' will be boolean FALSE
     * - '' will be NULL
     *
     * All other non-string values will be returned as is.
     *
     * @param mixed $value value to literalize
     *
     * @return mixed null or boolean value or the original value of it's not a string
     */
    public static function literalize($value)
    {
        if (!is_string($value)) {
            return $value;
        }

        $value = trim($value);
        if ($value == '') {
            return null;
        }

        $lc_value = strtolower($value);
        if ($lc_value === 'on' || $lc_value === 'yes' || $lc_value === 'true') {
            return true;
        } elseif ($lc_value === 'off' || $lc_value === 'no' || $lc_value === 'false') {
            return false;
        }

        return $value;
    }
}


<?php

namespace Modules\Menu\Listeners;

use Illuminate\Support\Facades\Cache;
use Modules\Menu\Events\PostMenuSetup;
use Vain\Events\BackendMenuCreated;

class MenuComposer
{
    /**
     * @param PostMenuSetup $event
     */
    public function postMenuSetup(PostMenuSetup $event)
    {
        // clear all items at top level
        if (config('menu.overwrite')) {
            foreach ($event->handler->getChildren() as $child) {
                $event->handler->removeChild($child);
            }
        }

        // inject own frontend menue
        $menu = $this->cacheIfConfigured(function () use ($event) {
            return $event->builder->getMenuItems();
        });

        foreach ($menu as $menuItem) {
            $event->handler->addChild($menuItem);
        }
    }

    /**
     * @param BackendMenuCreated $event
     */
    public function composeBackendMenu(BackendMenuCreated $event)
    {
        $event->handler->addChild('menu::menu.title.index')
            ->setExtra('patterns', ['/menu\.admin\.entries\.(.+)/'])
            ->setUri(route('menu.admin.items.index'))
            ->setExtra('icon', 'bars');
    }

    /**
     * @param \Illuminate\Events\Dispatcher $event
     */
    public function subscribe($event)
    {
        $event->listen('Modules\Menu\Events\PostMenuSetup', 'Modules\Menu\Listeners\MenuComposer@postMenuSetup');
        $event->listen('Vain\Events\BackendMenuCreated', 'Modules\Menu\Listeners\MenuComposer@composeBackendMenu');
    }

    /**
     * uses the cache if it was configured or calculates
     * the plain output every request otherwise.
     *
     * @param $closure
     *
     * @return array
     */
    private function cacheIfConfigured($closure)
    {
        if (config('menu.cache.enable')) {
            $key = config('menu.cache.key');
            $minutes = config('menu.cache.minutes');

            return Cache::remember($key, $minutes, function () use ($closure) {
                return call_user_func($closure);
            });
        }

        return call_user_func($closure);
    }
}


<?php

namespace Gwsn\HttpRequest;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Exception\ClientException;
use Psr\Log\LoggerInterface;

/**
 * Class BaseConnector
 *
 * @package Gwsn\HttpRequest
 */
class BaseConnector {

    const RESPONSE_ORIGINAL  = 'original';
    const RESPONSE_TYPE_JSON = 'json';
    const RESPONSE_TYPE_XML  = 'xml';
    const RESPONSE_TYPE_TEXT = 'text';
    const RESPONSE_TYPE_HTML = 'html';

    /**
     * @var ResponseInterface $response
     */
    protected $response = null;

    /**
     * The statuscodes that are allowed to pass through the proxy
     *
     * @url https://developer.mozilla.org/nl/docs/Web/HTTP/Status
     * @var array $validStatusCodes
     */
    private $validStatusCodes = [ 200, 201, 202, 204 ];

    /**
     * @var string $baseUri
     */
    private $baseUri = null;

    /**
     * @var int $curlTimeout
     */
    private $curlTimeout = 2.0;

    /**
     * @var object $cacheUtil
     */
    private $cacheUtil = null;

    /**
     * @var LoggerInterface $logger
     */
    private $logger = null;

    /**
     * Set CacheTime (default: 1 hour)
     *
     * @var int $cacheTime
     */
    private $cacheTime = ( 1 * 60 * 60 );

    /**
     * Contains the Guzzle Client
     *
     * @var Client $curlClient
     */
    private $curlClient = null;

    /**
     * Check if request is proxy or not
     *
     * @var bool $proxy
     */
    protected $proxy = null;

    /**
     * BaseConnector constructor.
     *
     * @param $cacheUtil
     * @param $logger
     */
    public function __construct(LoggerInterface $logger = null, $cacheUtil = null) {
        $this->proxy = false;
        $this->cacheUtil = $cacheUtil;
        $this->logger = $logger;
    }

    /**
     * @return array
     */
    protected function getValidStatusCodes()
    : array {
        return $this->validStatusCodes;
    }

    /**
     * @param array $validStatusCodes
     *
     * @return $this
     */
    public function setValidStatusCodes( array $validStatusCodes ) {
        if(empty($validStatusCodes)) {
            throw new \InvalidArgumentException('Cannot set empty valid status codes, please fill in at least one');
        }
        $this->validStatusCodes = $validStatusCodes;

        return $this;
    }

    /**
     * Return the base uri if its set
     *
     * @return string
     */
    protected function getBaseUri() {
        return $this->baseUri;
    }

    /**
     * @param $baseUri
     *
     * @return $this
     */
    public function setBaseUri( $baseUri ) {
        $this->baseUri = $baseUri;

        return $this;
    }

    /**
     * @return int
     */
    protected function getCacheTime()
    : int {
        return $this->cacheTime;
    }

    /**
     * @param int $cacheTime
     */
    public function setCacheTime( int $cacheTime ) {
        $this->cacheTime = $cacheTime;
    }

    /**
     * Return the timout of Curl Connection (default 60 seconds)
     *
     * @return int $curlTimeout
     */
    private function getCurlTimeout(): int
    {
        return $this->curlTimeout;
    }

    /**
     * @param int $curlTimeout
     */
    public function setCurlTimeout(int $curlTimeout): void
    {
        $this->curlTimeout = $curlTimeout;
    }

    /**
     * @return object
     */
    public function getCacheUtil()
    {
        return $this->cacheUtil;
    }

    /**
     * @param object $cacheUtil
     */
    public function setCacheUtil($cacheUtil): void
    {
        $this->cacheUtil = $cacheUtil;
    }

    /**
     * @return LoggerInterface
     */
    public function getLogger(): LoggerInterface
    {
        return $this->logger;
    }

    /**
     * @param LoggerInterface $logger
     */
    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }

    /**
     * @return Client
     */
    public function getCurlClient(): Client
    {
        return $this->curlClient;
    }

    /**
     * @param Client $curlClient
     */
    public function setCurlClient(Client $curlClient): void
    {
        $this->curlClient = $curlClient;
    }

    /**
     * @return bool
     */
    public function isProxy(): bool
    {
        return $this->proxy;
    }

    /**
     * @param bool $proxy
     */
    public function setProxy(bool $proxy): void
    {
        $this->proxy = $proxy;
    }

    /**
     * Prepare the Guzzle Client
     *
     * @param Client|null $client
     */
    public function prepareCall( Client $client = null ) {
        // Set the default client:
        $this->curlClient = null;
        $client           = null;

        $this->log( 'prepare ' . __CLASS__ . ' GuzzleRequest: base_uri(' . $this->getBaseUri() . '), client(' . ( (bool) is_null( $client ) ) . '), timeout(' . $this->getCurlTimeout() . '), ', 'debug');

        // Check if baseUri is set or that $client is set (make pass trough client available else set the client self)
        if ( $this->getBaseUri() !== null && $client === null ) {
            // Initialize the Client:
            $this->curlClient = new Client( [
                // Base URI is used with relative requests
                'base_uri' => $this->getBaseUri(),

                // You can set any number of default request options.
                'timeout'  => 2.0,
            ] );
        } else if ( $client !== null ) {
            $this->curlClient = $client;
        }
    }

    /**
     * @param string $method
     * @param string $url
     * @param array  $data
     * @param array  $headers
     *
     * @return bool|mixed
     */
    public function execute( $method, $url, array $data = [], array $headers = [] ) {
        // Define the response
        $this->response = null;
        $response       = null;
        $bodyType       = 'form_params';
        $headers        = $this->sanitizeHeaders($headers);

        // String replace the base url to prevent double baseUri
        $url = str_replace( $this->getBaseUri(), '', $url );

        $cacheKey = hash( 'sha512', $method . $url . md5( json_encode( $data ) ) . md5( json_encode( $headers ) ) );

        if ($this->hasCache($cacheKey)) {
            $response = $this->getCache($cacheKey);
            $this->setResponse( $response );
            $this->response->setCacheHit( true );
            return true;
        }

        // Check headers for Content Type
        if ( isset($headers['content-type']) && $headers['content-type'] === 'application/json' ) {
            $bodyType = 'json';
        }

        $this->log( 'Start ' . __CLASS__ . ' GuzzleRequest: method(' . $method . '), url(' . $url . '), ' , 'debug');

        try {
            // Do the actual request with Guzzle PSR7
            switch ( strtolower( $method ) ) {
                default:
                case 'get':
                    $response = $this->curlClient->request( strtoupper( $method ), $url, [
                        'headers' => $headers,
                    ] );
                    break;
                case 'put':
                case 'post':
                    $response = $this->curlClient->request( strtoupper( $method ), $url, [
                        $bodyType => $data,
                        'headers' => $headers,
                    ] );
                    break;
            }

            $validResponse = $this->checkValidResponse( $response->getStatusCode() );
        }
        catch ( ClientException $e ) {
            $validResponse = $this->checkValidResponse( $e->getCode() );
            if ( $validResponse === false ) {
                $this->log( $e->getFile().':'.$e->getLine().' Client Exception ' . $e->getMessage().' - '.$e->getCode() , 'error');
                throw new \RuntimeException( 'Client Exception ' . $e->getMessage(), $e->getCode() );
            }
            if ( method_exists( $e, 'getResponse' ) ) {
                $response = $e->getResponse();
            }
        }
        catch ( \Exception $e ) {
            $validResponse = $this->checkValidResponse( $e->getCode() );
            if ( $validResponse === false ) {
                $this->log( $e->getFile().':'.$e->getLine().' Client Exception ' . $e->getMessage().' - '.$e->getCode() , 'error');
                throw new \RuntimeException( 'Exception ' . $e->getMessage(), $e->getCode() );
            }
            if ( method_exists( $e, 'getResponse' ) ) {
                $response = $e->getResponse();
            }
        }

        // Write the response to the cache
        $this->setCache($cacheKey, $response, $this->getCacheTime());

        // Write down the response
        $this->setResponse( $response );

        // When the response is not valid return a
        if ( $validResponse === false ) {
            // the response is not valid this can be a configuration issue or the API is not responding well.
            // Base line is that we need to return a "500: Internal Server Error" with as a error the original message from the API
            $this->log( 'HTTP exception, got a ' . $response->getStatusCode() . ' status, expect only one of these (' . implode( ',', $this->getValidStatusCodes() ) . ')', 'error');
            throw new \RuntimeException( 'HTTP exception, got a ' . $response->getStatusCode() . ' status, expect only one of these (' . implode( ',', $this->getValidStatusCodes() ) . ')', $response->getStatusCode() );
        }

        return true;
    }

    /**
     * Write down the response
     *
     * @param Response $response
     */
    protected function setResponse( Response $response ) {
        $this->response = ( new BaseResponse )->setResponse( $response );
    }

    /**
     * Get the response body from the response and try to parse it to array or object.
     *
     * @param string $type
     *
     * @return null|string|BaseResponseInterface
     */
    public function getResponse( $type = self::RESPONSE_TYPE_JSON ) {
        // Check if response is set
        if ( $this->response === null ) {
            return null;
        }

        try {
            // Get the stream from the response getBody() method returns a stream instead of a string.
            $stream = $this->response->getBody();

            // Get the body from the stream.
            $body = $stream->getContents();

            if ( empty( $body ) ) {
                return null;
            }

            switch ( $type ) {
                default:
                case self::RESPONSE_TYPE_JSON:
                    return $this->getResponseJSON( $body );
                    break;
                case self::RESPONSE_TYPE_XML:
                    return (string) $body;
                    break;
                case self::RESPONSE_TYPE_HTML:
                    return (string) $body;
                    break;
                case self::RESPONSE_TYPE_TEXT:
                    return (string) $body;
                    break;
                case self::RESPONSE_ORIGINAL:
                    return $this->response;
                    break;
            }
        }
        catch ( BadResponseException $exception ) {
            return null;
        }
        catch ( \Exception $exception ) {
            return null;
        }
    }

    /**
     * Decode the JSON String
     *
     * @param string $body JSON encoded string
     *
     * @return string
     */
    private function getResponseJSON( $body ) {
        try {
            return json_decode( (string) $body, true );
        }
        catch ( \Exception $e ) {
            throw new \RuntimeException( 'Invalid JSON ' . $e->getMessage(), 0, $body );
        }
    }

    /**
     * @param array $headers
     *
     * @return array
     */
    private function sanitizeHeaders( array $headers = [] ) {
        // Check if headers is set and is not empty
        if ( empty( $headers )) {
            return [];
        }

        foreach($headers as $header => $value) {
            if ( is_array( $value ) && count( $value ) === 1 ) {
                $headers[$header] = array_pop( $value );
            }
        }

        return $headers;
    }

    /**
     * @param int $statusCode
     *
     * @return bool
     */
    protected function checkValidResponse( $statusCode = null ) {
        $valid_status_codes = $this->getValidStatusCodes();
        foreach ( $valid_status_codes as $valid_status_code ) {
            if ( $statusCode === intval( $valid_status_code ) ) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param string $key
     *
     * @return bool
     */
    protected function hasCache(string $key) {
        $cacheUtil = $this->getCacheUtil();

        if($cacheUtil === null) {
            return false;
        }
        return $this->cacheUtil->has($key);
    }

    /**
     * @param string $key
     *
     * @return mixed
     */
    protected function getCache(string $key) {
        $cacheUtil = $this->getCacheUtil();

        if($cacheUtil === null) {
            return null;
        }

        return $this->cacheUtil->get($key);
    }

    /**
     * @param string $key
     * @param mixed $value
     * @param int|null $cacheTime
     *
     * @return bool|null
     */
    protected function setCache(string $key, $value = null, int $cacheTime = null) {
        $cacheTime = ($cacheTime === null ? $this->getCacheTime() : $cacheTime);
        $cacheUtil = $this->getCacheUtil();

        if($cacheUtil === null) {
            return null;
        }

        return $this->cacheUtil->set($key, $value, $cacheTime);
    }

    /**
     * Logging the message to a log when logger is available else write it to /dev/null
     * @param string $message
     * @param string $type
     *
     * @return bool
     */
    protected function log(string $message = 'Logging - void', string $type = 'info'):bool
    {
        if(empty($this->logger)) {
            return false;
        }

        switch ($type) {
            case 'emergency':
                $this->logger->emergency($message);
                break;
            case 'alert':
                $this->logger->alert($message);
                break;
            case 'critical':
                $this->logger->critical($message);
                break;
            case 'error':
                $this->logger->error($message);
                break;
            case 'warning':
                $this->logger->warning($message);
                break;
            case 'notice':
                $this->logger->notice($message);
                break;
            default:
            case 'info':
                $this->logger->info($message);
                break;
            case 'debug':
                $this->logger->debug($message);
                break;
        }
        return true;
    }

}


<?php
/**
 * Openbizx Framework
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @package   openbiz.bin
 * @copyright Copyright (c) 2005-2011, Rocky Swen
 * @license   http://www.opensource.org/licenses/bsd-license.php
 * @link      http://www.phpopenbiz.org/
 * @version   $Id$
 */

namespace Openbizx\Web;

use Openbizx\Openbizx;

/**
 * Index of $_SESSION array that saves all information regarding statefull objects
 */
define('OB_STATEFUL_DATA_SESSION_INDEX', 'ob_stateful_data');
define('OB_TRANSIENT_DATA_SESSION_INDEX', 'ob_transient_data');

/**
 * SessionContext class is Session management class that has additional methods
 * to save/get session variables of metadata based stateful objects
 * through their loadStatefullVars|saveStatefullVars interfaces
 *
 * @package   openbiz.bin
 * @author    Rocky Swen <rocky@phpopenbiz.org>
 * @copyright Copyright (c) 2005-2009, Rocky Swen
 * @access    public
 */
class SessionContext
{

    protected $_lastAccessTime;
    protected $_timeOut = false;
    protected $_sessObjArr = null;
    protected $_statefulSessObjArr = null;
    protected $_viewHistory = null;
    protected $_prevViewObjNames = array();

    /**
     * Constructor of SessionContext, init session and set session file path
     *
     * @return void
     * */
    function __construct()
    {
        // get session save handler MC or DB
        if (defined("OPENBIZ_SESSION_HANDLER") && OPENBIZ_SESSION_HANDLER != "" && defined('OPENBIZ_USE_CUSTOM_SESSION_HANDLER') && OPENBIZ_USE_CUSTOM_SESSION_HANDLER == true) {
            include_once OPENBIZ_SESSION_HANDLER . ".php";
        } else {
            if (!file_exists(OPENBIZ_SESSION_PATH)) {
                @mkdir(OPENBIZ_SESSION_PATH, 0777, true);
            }
            // default is file session
            if (defined('OPENBIZ_SESSION_PATH') && is_writable(OPENBIZ_SESSION_PATH)) {
                session_save_path(OPENBIZ_SESSION_PATH);
            }
            // we cannot write in the session save path; aborting
            if (!is_writable(session_save_path())) {
                trigger_error("Unable to write in the session save path [" . session_save_path() . "]", E_USER_ERROR);
            }
        }

        ini_set('session.gc_probability', 1);   // force gc
        ini_set('session.gc_divisor', 100);
        if (defined('OPENBIZ_TIMEOUT') && OPENBIZ_TIMEOUT > 0) {
            ini_set("session.gc_maxlifetime", OPENBIZ_TIMEOUT);
        } else {
            ini_set("session.gc_maxlifetime", 21600); // 6 hours
        }

        if (!defined('CLI') || CLI == 0) {
            if (isset($_REQUEST['cubi_sess_id'])) {
                session_id($_REQUEST['cubi_sess_id']);
            }
            session_start();
        }
        // record access time
        $curTime = time();
        if (isset($_SESSION["LastAccessTime"])) {
            $this->_lastAccessTime = $_SESSION["LastAccessTime"];
        } else {
            $this->_lastAccessTime = $curTime;
        }
        $_SESSION["LastAccessTime"] = $curTime;

        // see if timeout
        $this->_timeOut = false;
        if ((OPENBIZ_TIMEOUT > 0) && (($curTime - $this->_lastAccessTime) > OPENBIZ_TIMEOUT)) {
            $this->_timeOut = true;
        }
    }

    /**
     * Set single session variable
     *
     * @param string $varName
     * @param mixed $value
     * @return void
     * */
    public function setVar($varName, $value)
    {
        $_SESSION[$varName] = $value;
    }

    public function mergeVar($varName, $value)
    {
        $var = $_SESSION[$varName];
        if (is_array($var)) {
            foreach ($value as $key => $value) {
                $var[$key] = $value;
            }
            $_SESSION[$varName] = $var;
        } else {
            $_SESSION[$varName] = $value;
        }
    }

    /**
     * Get single session variable
     *
     * @param string $varName name of session variable
     * @return string
     * */
    public function getVar($varName)
    {
        if (!isset($_SESSION[$varName])) {
            return "";
        }
        return $_SESSION[$varName];
    }

    /**
     * Clear/Unset single session variable
     * NOTE: NYU - not yet used
     *
     * @param string $varName
     * @return void
     * */
    public function clearVar($varName)
    {
        unset($_SESSION[$varName]);
    }

    /**
     * Is variable exist in the session
     *
     * @param string $varName variable name that checked
     * @return boolean TRUE if the var exists in the session, otherwise FALSE
     * */
    public function varExists($varName)
    {
        return isset($_SESSION[$varName]);
    }

    /**
     * Get namespace
     *
     * @return string
     */
    public function getNamespace()
    {
        $view = Openbizx::$app->getCurrentViewName();
        if ($view) {
            $namespace = $view;
        } else {
            $namespace = 'DEFAULT_NS';
        }
        return $namespace;
    }

    /**
     * Set single session variable of a stateful object
     *
     * @param string $objName - object name
     * @param string $varName - vaiable name
     * @param mixed $value - reference of the value (in/out)
     * @param boolean $stateful - is stateful?
     * @return void
     * */
    public function saveObjVar($objName, $varName, &$value, $stateful = false)
    {
        if (preg_match('/\./si', $objName)) {
            $objName = $this->getNamespace() . '#' . $objName;
        }
        if (!$stateful) {
            $this->_sessObjArr[$objName][$varName] = $value;
        } else {
            $this->_statefulSessObjArr[$objName][$varName] = $value;
        }
    }

    /**
     * Clean Object
     *
     * @param string $objName object name
     * @param boolean $stateful
     * @return void
     */
    public function cleanObj($objName, $stateful = false)
    {
        if (preg_match('/\./si', $objName)) {
            $objName = $this->getNamespace() . '#' . $objName;
        }
        if (!$stateful) {
            unset($this->_sessObjArr[$objName]);
        } else {
            unset($this->_statefulSessObjArr[$objName]);
        }
    }

    /**
     * Get single session variable of a stateful object
     *
     * @param string $objName - object name
     * @param string $varName - vaiable name
     * @param mixed $value - reference of the value (in/out)
     * @param boolean $stateful - is stateful?
     * @return void
     */
    public function loadObjVar($objName, $varName, &$value, $stateful = false)
    {
        //Openbizx::$app->getLog()->log(LOG_ALERT, __METHOD__, ' | name : ' . $varName . ' | value : ' . $value);
        //Openbizx::$app->getClientProxy()->showClientAlert( __METHOD__ . ' | name : ' . $varName . ' | value : ' . $value);

        if (preg_match('/\./si', $objName)) {
            $objName = $this->getNamespace() . '#' . $objName;
        }
        if (!$stateful) {
            if (!$this->_sessObjArr) {
                return null;
            }
            if (isset($this->_sessObjArr[$objName][$varName])) {
                $value = $this->_sessObjArr[$objName][$varName];
            }
        } else {
            if (!$this->_statefulSessObjArr) {
                return null;
            }
            if (isset($this->_statefulSessObjArr[$objName][$varName])) {
                $value = $this->_statefulSessObjArr[$objName][$varName];
            }
        }
    }

    /**
     * Save session variables of all stateful objects into sessionid_obj file
     *
     * @return void
     * */
    public function saveSessionObjects()
    {
        // loop all objects (bizview, bizform, bizdataobj) collect their session vars
        $allobjs = Openbizx::objectFactory()->getAllObjects();
        foreach ($allobjs as $obj) {
            if (method_exists($obj, "saveStatefullVars")) {
                //after calling $obj->saveStatefullVars SessObjArr and StatefulSessObjArr are filled
                $obj->saveStatefullVars($this);
            }
            // if previous view's object is used in current view, don't discard its session data
            if ( isset($obj->objectName) && isset($this->_prevViewObjNames[$obj->objectName]) ) {
                unset( $this->_prevViewObjNames[$obj->objectName] );
                Openbizx::$app->getLog()->log( LOG_ERR, "SESSION", "unset " . $obj->objectName );
            }
        }

        // discard useless previous view's session objects
        //foreach($this->_prevViewObjNames as $objName=>$tmp)
        //    unset($this->_sessObjArr[$objName]);

        $this->_sessObjArr["ViewHist"] = $this->_viewHistory;

        $this->setVar(OB_TRANSIENT_DATA_SESSION_INDEX, $this->_sessObjArr);
        $this->setVar(OB_STATEFUL_DATA_SESSION_INDEX, $this->_statefulSessObjArr);
    }

    /**
     * Retrieve/Get session variables of all stateful objects from sessionid_obj file
     *
     * @return void
     * */
    public function retrieveSessionObjects()
    {
        $this->_sessObjArr = $this->getVar(OB_TRANSIENT_DATA_SESSION_INDEX);
        $this->_statefulSessObjArr = $this->getVar(OB_STATEFUL_DATA_SESSION_INDEX);

        if (!is_array($this->_sessObjArr)) {
            $this->_sessObjArr = array();
        }
        if (!is_array($this->_statefulSessObjArr)) {
            $this->_statefulSessObjArr = array();
        }
        $this->_viewHistory = isset($this->_sessObjArr['ViewHist']) ? $this->_sessObjArr["ViewHist"] : NULL;
        return TRUE;
    }

    /**
     * Clear session variables of all stateful objects
     *
     * @param boolean $keepObjects
     * @return void
     */
    public function clearSessionObjects($keepObjects = false)
    {
        if ($keepObjects == false) {
            unset($this->_sessObjArr);
            $this->_sessObjArr = array();
        } else { // add previous view's session object names in to a map
            if (isset($this->_sessObjArr)) {
                foreach ($this->_sessObjArr as $objName => $sessobj) {
                    //echo "save sess $objName <br/>";
                    $this->_prevViewObjNames[$objName] = 1;
                }
            }
        }
    }

    /**
     * Save a JSON array in session
     *
     * @param string $jsonValue
     * @param string $jsonName
     * @return void
     * */
    public function saveJSONArray($jsonValue, $jsonName = NULL)
    {
        $jsonArray = json_decode($jsonValue);

        if ((bool) $jsonName) { //If I want save all array in session I send the name of the array in session
            $this->setVar($jsonName, $jsonArray);
        } else {//I save each value in session
            foreach ($jsonArray as $varName => $value) {
                $this->setVar($varName, $value);
            }
        }
    }

    /**
     * Get view history data of given BizForm/EasyForm from saved in session file
     *
     * @param string $formName - name of BizForm/EasyForm
     * @return array - view history data represented by an associated array
     * */
    public function getViewHistory($formName)
    {
        $view = Openbizx::$app->getCurrentViewName();
        $view_form = $formName; //$view."_".$formname;
        return $this->_viewHistory[$view_form];
    }

    /**
     * Set view history data of given bizform into session file
     *
     * @param string $formName - name of bizform
     * @param array $historyInfo - view history data represented by an associated array
     * @return void
     * */
    public function setViewHistory($formName, $historyInfo)
    {
        $view = Openbizx::$app->getCurrentViewName();
        $view_form = $formName; //$view."_".$formname;
        if (!$historyInfo) {
            unset($this->_viewHistory[$view_form]);
        } else {
            $this->_viewHistory[$view_form] = $historyInfo;
        }
    }

    /**
     * Destroy/free all session data of the current session
     *
     * @return void
     * */
    public function destroy()
    {
        unset($this->_viewHistory);
        unset($this->_sessObjArr);
        unset($this->_statefulSessObjArr);

        session_destroy();
    }

    /**
     * Check if user logged in or not
     * NOTE: NYU - not yet used
     *
     * @return boolean
     */
    public function isUserValid()
    {
        if (CHECKUSER == "N") {
            return true;
        }
        if ($this->getVar("UserId") != "") {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Check if current session is timeout
     *
     * @return boolean
     * */
    public function isTimeout()
    {
        return $this->_timeOut;
    }

}


<?php

namespace xz1mefx\adminlte\helpers;

use yii\bootstrap\BaseHtml;
use yii\helpers\ArrayHelper;

/**
 * @inheritdoc
 */
class Html extends BaseHtml
{
    /**
     * @param string $bgClass it's can be:
     *
     *      label-default,
     *      label-primary,
     *      label-success,
     *      label-info,
     *      label-warning,
     *      label-danger,
     *      bg-red,
     *      bg-yellow,
     *      bg-aqua,
     *      bg-blue,
     *      bg-light-blue,
     *      bg-green,
     *      bg-navy,
     *      bg-teal,
     *      bg-olive,
     *      bg-lime,
     *      bg-orange,
     *      bg-fuchsia,
     *      bg-purple,
     *      bg-maroon,
     *      bg-black
     * @param string $label
     * @param array $options
     * @return string
     */
    public static function infoLabel($bgClass, $label, $options = [])
    {
        $tag = ArrayHelper::remove($options, 'tag', 'span');
        static::addCssClass($options, ['label']);
        static::addCssClass($options, $bgClass);
        return static::tag($tag, $label, $options);
    }
}


<?php
namespace Simphotonics\Utils;

use Simphotonics\Utils\ArrayUtils as ArrayUtils;

/**
 * @author D Reschner <d.reschner@simphotonics.com>
 * @copyright 2015 Simphotonics
 * Description: Timer class similar to Matlab's tic() toc().
 */
class Timer
{
    /**
     * Start time.
     * @var float
     */
    private $start = 0.0;

    /**
     * Stop time.
     * @var float
     */
    private $stop = 0.0;

    /**
     * Elapsed time.
     * @var float
     */
    private $elapsed = 0.0;

    /**
     * Lap count.
     * @var integer
     */
    private $count = 0;

    /**
     * Average time between immediate calls to tic() and toc().
     * @var float
     */
    public $calib = 0.0;

    /**
     * Standard deviation of $calib.
     * @var float
     */
    public $stDev = 0.0;

    /**
     * Logical flag use to reset the lap counter.
     * @see  $this->tac().
     */
    const RESET_COUNTER = 1;

    /**
     * Logical flag to keep lap counter.
     */
    const KEEP_COUNTER = 0;

    /**
     * Logical flag to add lap times.
     */
    const ADD_LAP   = 0;

    /**
     * Logical flag to reset lap times.
     */
    const RESET_LAP = 1;

    /**
     * Initialise object.
     * @return  void
     */
    public function __construct()
    {
        $this->calibrate();
        $this->reset();
    }

    /**
     * Output elapsed time.
     * @return string
     */
    public function __toString()
    {
        return " \n Elapsed time: (" . sprintf('%0.2f', $this->elapsed) ." +- ".
        sprintf('%0.2f', $this->stDev). ") microseconds.\n";
    }

    /**
     * Starts timer.
     * @param  int $flag self::RESET_COUNTER|self::KEEP_COUNTER
     * @return void
     */
    public function tic($flag = self::RESET_COUNTER)
    {
        $this->start = microtime(true);
        if ($flag) {
            $this->count = 0;
        }
    }

    /**
     * Stops timer and displays elapsed time.
     * @param  string $message is an optional user message.
     * @return void
     */
    public function toc($message = '')
    {
        $this->stop = microtime(true);
        ++$this->count;
        $this->elapsed = ($this->stop - $this->start ) * 1e6 - $this->calib;
        print $this;
        if ($message) {
            print $message . "\n";
        }
    }

    /**
     * Keeps lap time.
     * @param  int $flag Takes values self::ADD_LAP|self::RESET_LAP
     * @return void
     */
    public function tac($flag = self::ADD_LAP)
    {
        $this->stop = microtime(true);
        if ($flag) {
            $this->elapsed = ($this->stop - $this->start) * 1e6
            - $this->calib;
        } else {
            $this->elapsed += ($this->stop - $this->start) * 1e6
            - $this->calib;
        }
        ++$this->count;
    }

    /**
     * Returns elapsed time in microseconds.
     * @return float
     */
    public function elapsed()
    {
        return $this->elapsed;
    }

    /**
     * Resets timer.
     * @return void
     */
    public function reset()
    {
        $this->count = 0;
        $this->elapsed = 0;
        $this->start = 0;
        $this->stop = 0;
        return $this;
    }

    /**
     * Returns average lap time
     * @return float Time in microseconds.
     */
    public function lap()
    {
        return $this->elapsed / max($this->count, 1);
    }

    /**
     * Calculates $this->calib, the average time between immediate calls
     * to tic() and toc().
     * Initialises the standard deviation of $this->calib.
     * @return void
     */
    private function calibrate()
    {
        $imax = 20;
        $this->tic();
        $this->tac();
        for ($i=0; $i < $imax; $i++) {
            $this->tic();
            $this->tac(self::RESET_LAP);
            $calib[] = $this->elapsed;
        }
        $this->calib = ArrayUtils::mean($calib);
        $this->stDev = ArrayUtils::stDeviation($calib);
    }
}


<?php

namespace Environaut\Checks;

use Environaut\Checks\Check;

/**
 * Check to get absolute paths to executable files that
 * may be used within an application. As even paths to
 * simple tools like "ls", "find" or "grep" may not be
 * accessible in e.g. crontabs due to non-configured
 * default PATH environment variables they can be searched
 * and configured prior running the application (and thus
 * always use the validated absolute executable paths).
 *
 * Supported parameters are:
 * - "command": name of executable/command to check
 * - "setting": name of setting to use for absolute path storage (for export)
 * - "setting_group": name of settings group to use (for export; defaults to "config")
 * - "question": question to ask the user (defaults to "Path to the executable [command]")
 * - "default": default command or executable path to try (defaults to "/usr/bin/[command]")
 * - "validator": validator callable to use (defaults to one, that uses "which" to find the path of the command)
 * - "max_attempts": maximum number of attempts a user is allowed to have for correct input of a path
 */
class ExecutableCheck extends Check
{
    /**
     * Default group of settings that this check stores in the result.
     */
    const DEFAULT_SETTING_GROUP_NAME = 'config';

    /**
     * Default group name used in messages of the report.
     * By default also used as default setting group name if not customized.
     */
    const DEFAULT_CUSTOM_GROUP_NAME = 'Executables';

    /**
     * Returns the default group name this check uses when none is specified.
     *
     * @return string default group name of the check
     */
    public function getDefaultGroupName()
    {
        return self::DEFAULT_CUSTOM_GROUP_NAME;
    }

    /**
     * Returns the default group name this check uses for settings when none is specified.
     *
     * @return string default group name of settings of this check
     */
    public function getDefaultSettingGroupName()
    {
        if ($this->group !== self::DEFAULT_CUSTOM_GROUP_NAME) {
            return $this->group;
        }

        return self::DEFAULT_SETTING_GROUP_NAME;
    }

    /**
     * Ask user for an absolute path to the given executable or try to determine it
     * by itself using the default value (on confirmation).
     *
     * @return boolean true
     *
     * @throws \InvalidArgumentException on setup errors like "choices" can't be interpreted or parameters being wrong
     * @throws \RuntimeException if there is no data to read in the input stream
     * @throws \Exception when the maximum number of attempts has been reached and no valid response has been given
     */
    public function run()
    {
        $output = $this->getOutputStream();
        $dialog = $this->getDialogHelper();

        $command = $this->parameters->get('command', $this->getName());
        $setting = $this->parameters->get('setting', 'cmd.' . $command);
        $setting_group = $this->parameters->get('setting_group');
        $default = $this->parameters->get('default', '/usr/bin/' . $command);
        $choices = $this->parameters->get(
            'choices',
            array(
                '/bin/',
                '/usr/bin/',
                '/usr/sbin/',
                '/usr/local/bin/',
                '/usr/local/sbin/',
            )
        );
        $validator = $this->parameters->get('validator', array($this, 'validExecutable'));
        $max_attempts = $this->parameters->get('max_attempts', false);

        if ($this->cache->has($setting, $setting_group)) {
            $cached_setting = $this->cache->get($setting, $setting_group);
            $this->addInfo(
                "Setting [" . $cached_setting->getGroup() . "][$setting] already configured. Using " .
                'value: ' . var_export($cached_setting->getValue(), true)
            );
            $this->result->addSetting($cached_setting);
            return true;
        }

        $question = '<question>' . $this->parameters->get(
            'question',
            'Path to the executable "' . $command . '"'
        );

        // add default value to question if specified
        if (null !== $default) {
            $question .= "</question> (Default: which $default)";
        } else {
            $question .=  '</question>';
        }
        $question .= ': ';

        // ask for path to executable with validation and autocomplete of common executable directories like /usr/bin
        $absolute_executable_path = $dialog->askAndValidate(
            $output,
            $question,
            $validator,
            $max_attempts,
            $default,
            $choices
        );

        $this->addCachableSetting($setting, $absolute_executable_path, $setting_group);
        $this->addInfo('Got path to executable "' . $command . '": ' . $absolute_executable_path);

        return true;
    }

    /**
     * Checks whether the given input value leads to an executable that
     * matches the configured version_mask parameter.
     *
     * @param string $value path to an executable
     *
     * @return string absolute path to executable
     *
     * @throws \InvalidArgumentException in case of non-existing executable at the given path or version mismatch
     */
    public function validExecutable($value)
    {
        $val = trim($value);

        if (empty($val)) {
            throw new \InvalidArgumentException(
                'Not a valid executable path. Please specify a command (like "ls") or a path (like "/usr/bin/ls").'
            );
        }

        $executable = trim(shell_exec('which ' . $val));
        if (!$executable) {
            throw new \InvalidArgumentException('Could not find executable: ' . $val);
        }

        $command = $this->parameters->get('command', $this->getName());
        $cli_option = $this->parameters->get('version_parameter', '--version');
        $version_mask = $this->parameters->get('version_mask', '/Version/');

        if ($version_mask) {
            $version_info_raw = trim(shell_exec('cat /dev/null | ' . $executable . ' ' . $cli_option . ' 2>&1'));
            if (!preg_match($version_mask, $version_info_raw, $matches, PREG_OFFSET_CAPTURE)) {
                throw new \InvalidArgumentException(
                    'Could not get version information for "' . $command . '" using "' . $executable . '".'
                );
            }
        }

        return $executable;
    }
}


<?php
/**
 * FormHelper class
 *
 * @package
 * @author Rocky Swen
 * @copyright Copyright (c) 2005-2009
 * @access public
 */

namespace Openbizx\View;

use Openbizx\Core\ErrorHandler;

 /*
  * Navigation methods: switchForm, showForm, getRedirectPage, processPostAction
  * Error Handling methods:
  * Validation methods
  */
class FormHelper
{
	protected $formObj;
	protected $invokingElement;

	public function __construct($formObj)
	{
		$this->formObj = $formObj;
	}

// -------------------------- Navigation Methods ---------------------- //
	/**
     * Switch to other form
     *
     * @param string $formName to-be-swtiched form name. if empty, then switch to default form
     * @param string $id id value of the target form
     * @return void
     * @access remote
     */
    public function switchForm($formName=null, $id=null)
    {
		$formObj1 = Openbizx::getObject($formName);
		$formObj1->setRecordId($id);
		$output = $formObj1->render();
		if (!empty($output)) Openbizx::$app->getClientProxy()->redrawForm($this->formObj->objectName, $output);
    }

	public function loadDialog($formName=null, $id=null)
    {
		$formObj1 = Openbizx::getObject($formName);
		$formObj1->setRecordId($id);
		//$formObj1->setParentForm($this->formObj->objectName);
		$output = $formObj1->render();
		if (!empty($output)) Openbizx::$app->getClientProxy()->redrawForm("DIALOG", $output);
    }

    /**
     * Process Post Action
     *
     * @return void
     */
    public function processPostAction()
    {
        // get the $redirectPage from eventHandler
        list($redirectPage,$target) = $this->getRedirectPage();
        if ($redirectPage)
        {
			// if the redirectpage start with "form=", render the form to the target which is defined by FuntionType
			if (strpos($redirectPage,"form=") === 0)
			{
				parse_str($redirectPage, $output);
				$formName = $output['form'];

				$id = null;
				if (isset($output['fld:Id'])) {
					$id = $output['fld:Id'];
				}
				$this->switchForm($formName, $id);
			}
			else
			{
				// otherwise, do page redirection
				Openbizx::$app->getClientProxy()->ReDirectPage($redirectPage);
			}
        }
    }

    /**
     * return redirect page and target array
     *
     * @return array {redirectPage, $target}
     */
    public function getRedirectPage()
    {
        // get the control that issues the call
        // __this is elementName:eventHandlerName
        list($element, $eventHandler) = $this->getInvokingElement();
        $eventHandlerName = $eventHandler->objectName;
        $redirectPage = $element->getRedirectPage($eventHandlerName); // need to get postaction of eventhandler
        $functionType = $element->getFunctionType($eventHandlerName);
        switch ($functionType)
        {
            case "Popup":
                $target = "Popup";
                break;
            default:
                $target = "";
        }
        return array($redirectPage, $target);
    }

	/**
     * Get the element that issues the call.
     *
     * @return array element object and event handler name
     */
    public function getInvokingElement()
    {
    	if ($this->invokingElement)
        	return $this->invokingElement;
    	// __this is elementName:eventHandlerName
        $elementAndEventName = Openbizx::$app->getClientProxy()->getFormInputs("__this");
        if (! $elementAndEventName)
        	return array(null,null);
        list ($elementName, $eventHandlerName) = explode(":", $elementAndEventName);
        $element = $this->formObj->getElement($elementName);
        $eventHandler = $element->eventHandlers->get($eventHandlerName);
        $this->invokingElement = array($element, $eventHandler);
        return $this->invokingElement;
    }

// -------------------------- Error Handling Methods ---------------------- //
    /**
     * Handle the error from {@link BizDataObj::getErrorMessage} method,
     * report the error as an alert window and log.
     *
     * @param int $errCode
     * @return void
     */
    public function processDataObjError($errCode = 0)
    {
        $errorMsg = $this->formObj->getDataObj()->getErrorMessage();
        Openbizx::$app->getLog()->log(LOG_ERR, "DATAOBJ", "DataObj error = ".$errorMsg);
        Openbizx::$app->getClientProxy()->showErrorMessage($errorMsg);
    }

    /**
     * Process error of form object
     *
     * @param array $errors
     * @return string - HTML text of this form's read mode
     */
    public function processFormObjError($errors)
    {
        $this->formObj->errors = $errors;
		//print_r($this->errors); exit;
        //$this->hasError = true;
        return $this->formObj->rerender();
    }

    /**
     * Handle the exception from DataObj method,
     *  report the error as an alert window
     *
     * @param int $errCode
     * @return string
     */
    public function processDataException($e)
    {
        $errorMsg = $e->getMessage();
        Openbizx::$app->getLog()->log(LOG_ERR, "DATAOBJ", "DataObj error = ".$errorMsg);
        //Openbizx::$app->getClientProxy()->showClientAlert($errorMsg);   //showErrorMessage($errorMsg);
        //Openbizx::$app->getClientProxy()->showErrorMessage($errorMsg);
        $e->no_exit=true;
	    ErrorHandler::exceptionHandler($e);
    }

}