<?php /** * class to log all project actions, ie. build, deploy etc. * * @author hahn */ class Actionlog { private $_aLoglevels = array("info", "warning", "error", "success"); // array of valid loglevels private $_sIP = false; private $_sUser = false; private $_sProject = false; private $_sCreate = ' CREATE TABLE "logs" ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , `time` DATETIME, `loglevel` TEXT, `ip` TEXT, `user` TEXT, `project` TEXT, `action` TEXT, `message` TEXT )'; /** * constructor - sets internal environment variables and checks existence * of the database * @global array $aConfig settings * @param string $sProject project ID */ public function __construct($sProject = false) { global $aConfig; $this->_dbfile = $aConfig['appRootDir'] . '/database/logs.db'; if (!file_exists($this->_dbfile)) { $this->_createDb(); } $this->_sProject = $sProject; if (isset($_SERVER) && is_array($_SERVER) && array_key_exists("PHP_AUTH_USER", $_SERVER) && $_SERVER["PHP_AUTH_USER"] ) { $this->_sIP = $_SERVER["REMOTE_ADDR"]; $this->_sUser = $_SERVER["PHP_AUTH_USER"] . " (web)"; } else { $this->_sIP = 'local'; $this->_sUser = get_current_user() . " (system)"; } } /** * create sqlite database - called in constructor if the file does not exist */ private function _createDb() { return $this->_makeQuery($this->_sCreate); } /** * execute a sql statement * @param string $sSql sql statement * @return database object */ private function _makeQuery($sSql) { // $this->_log(__FUNCTION__."($sSql)"); // echo "<pre>$sSql</pre>"; $db = new PDO("sqlite:" . $this->_dbfile); $result = $db->query($sSql); $db = NULL; return $result; } /** * add a log message * @param string $sMessage message * @param string $sAction project action; i.e. build, deploy, ... * @param string $sLoglevel loglevel */ public function add($sMessage, $sAction = "", $sLoglevel = "info") { if (array_search($sLoglevel, $this->_aLoglevels) === false) { die(__class__ . ": loglevel $sLoglevel is invalid"); } $sql = "INSERT INTO `logs` (`time`, `loglevel`, `ip`, `user`, `project` ,`action`, `message`) VALUES( '" . date("Y-m-d H:i:s") . "', '" . $sLoglevel . "', '" . $this->_sIP . "', '" . $this->_sUser . "', '" . $this->_sProject . "', '" . $sAction . "', '" . $sMessage . "' ); "; // echo $sql . "<br>"; $this->_makeQuery($sql); } /** * get log data * @param array $aFilter with the following keys: * 'project' - filter by project; will be mixed with where (see next key) * 'where' - where clausel - part behind "WHERE " * 'order' - order clausel - part behind "ORDER BY "; default is "id DESC" (order by newest entries) * 'limit' - limit clausel - part behind "LIMIT " * @return array */ public function getLogs($aFilter = array()) { // var_dump(R::findAll( 'log' )); $aReturn = array(); $sSql = 'SELECT * from logs '; $sWhere = false; if (array_key_exists("where", $aFilter) && $aFilter["where"]) { $sWhere.=' WHERE (' . $aFilter["where"] . ') '; } if (array_key_exists("project", $aFilter) && $aFilter["project"]) { $sProjectWhere = '`project`="' . $aFilter["project"] . '"'; $sWhere.= $sWhere ? ' AND ' . $sProjectWhere : 'WHERE ' . $sProjectWhere; } $sSql.=$sWhere; if (array_key_exists("order", $aFilter) && $aFilter["order"]) { $sSql.=' ORDER BY ' . $aFilter["order"]; } else { $sSql.=' ORDER BY id DESC '; } if (array_key_exists("limit", $aFilter) && $aFilter["limit"]) { $sSql.=' LIMIT ' . $aFilter["limit"]; } foreach ($this->_makeQuery($sSql) as $row) { for ($i = 0; $i <= 7; $i++) { unset($row[$i]); } $aReturn[] = $row; } return $aReturn; } /** * render html code for a table with logs. The filter will be sent to * getLogs method. * @param array $aFilter with the following keys: * 'project' - filter by project; will be mixed with where (see next key) * 'where' - where clausel - part behind "WHERE " * 'order' - order clausel - part behind "ORDER BY "; default is "id DESC" (order by newest entries) * 'limit' - limit clausel - part behind "LIMIT " * @return string */ public function renderLogs($aFilter = array()) { $sReturn = ""; static $bWasShown; if ($bWasShown) return " "; $bWasShown = true; $aData = $this->getLogs($aFilter); if (!count($aData)) { $sReturn = t("class-actionlog-nolog"); } else { $sReturn.='<thead><tr>'; foreach (array_keys($aData[0]) as $sRow) { $sReturn.='<th>' . $sRow . '</th>'; } $sReturn.='</tr></thead>'; $sReturn.='<tbody>'; foreach ($aData as $aRow) { $sReturn.='<tr class="tractionlogs loglevel-' . $aRow["loglevel"] . ' ' . $aRow["project"] . '">'; foreach ($aRow as $sValue) { $sReturn.='<td>' . $sValue . '</td>'; } $sReturn.='</tr>'; } $sReturn.='</tbody>'; $sReturn = ' <i class="icon-filter"></i> ' . t("overview-textsearch") . ': <input type="text" id="efilterlogs" name="efilterlogs" style="width: 150px;" onchange="filterLogTable();" onKeypress="filterLogTable(); " onKeyup="filterLogTable(); " title="' . t("overview-textsearch-hint") . '" > <i class="icon-list-alt"></i> <a href="/deployment/all/setup/actionlog/">all</a><br> <table class="table">' . $sReturn . '</table>'; } $sReturn = '<strong>' . '<button onclick="setLogVisibility(\'block\');" id="btnShowLogs" class="btnLogs"><b class="icon-chevron-right"></b> </button>' . '<button onclick="setLogVisibility(\'none\');" id="btnHideLogs" class="btnLogs"><b class="icon-chevron-down"></b> </button>' . ' ' . t("class-actionlog-title") . '</strong>' . '<div id="divActionlogs">' . '<p>' . t("class-actionlog-filter") . ': ' . print_r($aFilter, true) . ')</p>' . $sReturn . '</div> <script> function getLogVisibility(){ var sReturn=localStorage.getItem("bActionlogsVisible"); sReturn=(sReturn=="block")?"block":"none"; return sReturn; } function setLogVisibility(sVisibility){ localStorage.setItem("bActionlogsVisible", sVisibility); $("#divActionlogs").css("display", sVisibility); $(".btnLogs").css("display", "none"); if (sVisibility=="block"){ $("#btnHideLogs").css("display", "inline"); } else { $("#btnShowLogs").css("display", "inline"); } } /** * filter table and tiles by filtertext */ function filterLogTable(){ var sSearch=$("#efilterlogs").val(); var Regex = new RegExp(sSearch, "i"); $(".tractionlogs").each(function() { sVisible="none"; if ( Regex.exec(this.innerHTML)) { sVisible=""; } $(this).css("display", sVisible); }); return false; } setLogVisibility(getLogVisibility()); </script>'; return $sReturn; } }