null, * writeErrorReport() will use the next ID which is not used in the table. * * @par * An error report that has been written to the database can be changed using * writeErrorReport(), setting the $nUid member of the erErrorReport parameter * to the UID of the error report to be changed. * * @par * To change the visibility of an error report to @e hidden, call * setErrorReportDoneFlag() with the UID of the error report and set the second * parameter to false. * * @par * To delete an error report from the database, call deleteErrorReport() with * the UID of the error report you want to delete. * * @par * Error reports can be retrieved by their UID (getErrorReportByID()), by * creation date (getErrorReportsByDate()), by owner (getErrorReportsByOwner()), * by machine to which the report refers (getErrorReportsByMachine()) and by * the person who wrote the comment (getErrorReportsByCommentOwner()). All * error reports in the database can be retrieved using getErrorReports(). All * of these functions return a object of type erErrorReport or an array of * erErrorReport objects. * * @par Example * The following example creates a new error report “This doesn’t work”, written * by the user “testuser” on February 5, 2007, which refers to the machine * “Client-26” and is not visible for non-admin users. Then it adds a nice * comment, makes the error report visible and writes it to the database. * @code * setComment("We know that already", "admin"); * // $em->nUid is null, so writeErrorReport() calculates the UID by itself * $nNewID = $obj->writeErrorReport($em); * @endcode */ class erErrorReportManager { /////////////////////////////////// QUERYING ///////////////////////////////// /** * @name Quering * @{ */ /** * Get the number of reported errors * @return int */ public function getNumErrorReports() { $ar = pg_fetch_array(db_query("SELECT COUNT(*) AS count FROM ". "mod_errorreporter;"), 0); return intval($ar["count"]); } /** * Get all error reports in the database. * If this function fails, it returns null. Call getLastError() to * get more information. * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ public function getErrorReports($arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { return $this->readFromSQL("", $arcSort); } /** * Get an error report by its unique ID in database. * If this function fails, it returns null. * @param $nID (int) ID of the error report * @return erErrorReport */ public function getErrorReportByID($nID) { $arReturn = $this->readFromSQL("er_uid = ".qdb(intval($nID))); if(is_array($arReturn) and count($arReturn) > 0) { return $arReturn[0]; // return as scalar } else { return null; } } /** * Get all error reports which have been created on the specified date. * If this function fails, it returns null. Call getLastError() to * get more information. * @param $tsDate (timestamp) Date * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ public function getErrorReportsByDate($tsDate, $arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { return $this->readFromSQL("er_date = ".qdb(date("Y\-m\-d", $tsDate)), $arcSort); } /** * Get all error reports which have been created by the specified user. * If this function fails, it returns null. Call getLastError() to * get more information. * @param $strAct (string) Account name * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ public function getErrorReportsByOwner($strAct, $arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { return $this->readFromSQL("er_act = ".qdb($strAct), $arcSort); } /** * Get all error reports which are related to a specified machine. * If this function fails, it returns null. Call getLastError() to * get more information. * @param $strMachine (string) Machine name * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ public function getErrorReportsByMachine($strMachine, $arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { return $this->readFromSQL("er_machine = ".qdb($strMachine), $arcSort); } /** * Get all error reports which have been commented by the specified user. * If this function fails, it returns null. Call getLastError() to * get more information. * @param $strAct (string) Account name * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ public function getErrorReportsByCommentOwner($strAct, $arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { return $this->readFromSQL("er_commentact = ".qdb($strAct), $arcSort); } /*@}*/ /** * Get datasets from the SQL tables. * This function should not be called directly. Use the getBy* functions * instead. If this function fails, it returns null. Call * getLastError() to get more information. * @internal * @param $strWhere (string) Parameters for the SQL WHERE clause * @param $arcSort (array of constants) Defines the sorting of the returned * array. See the documentation of the $arcSort parameter of * buildOrderByClause() for more information. * @return array of objects of type erErrorReport */ protected function readFromSQL($strWhere = "", $arcSort = array(ER_ERM_SORT_UID => ER_ERM_SORT_ASC)) { $arReturn = array(); // only allow visible reports for non-admins, but all reports for // admins and owners if(erConfig::userIsAdmin()) { $strWhereClause = (trim($strWhere) == "") ? "" : "WHERE $strWhere"; } else { $strWhereClause = "WHERE ".((trim($strWhere) == "") ? "" : "$strWhere AND ").sprintf("((er_act = '%s') or (er_hidden IS NULL OR ". " NOT er_hidden))", $_SESSION["act"]); } $strSortClause = $this->buildOrderByClause($arcSort); // fetch the error reports $hQuery = db_query("SELECT * FROM mod_errorreporter $strWhereClause ". "$strSortClause;"); if(!is_resource($hQuery)) { setLastError(ER_ERROR_SQL); return null; } while($arResult = pg_fetch_array($hQuery)) { $er = new erErrorReport(strtotime($arResult["er_date"]), $arResult["er_act"], $arResult["er_machine"], $arResult["er_text"], $arResult["er_hidden"] == "t"); $er->setUid($arResult["er_uid"]); $er->setComment($arResult["er_comment"], $arResult["er_commentact"]); $arReturn[] = $er; } return $arReturn; } /** * Build a ORDER BY clause from an array. * This helper function takes an array of sorting constants as input and * returns an ORDER BY clause. The values in the clause are in the same order * as the constants in the array. The function in the following example * returns an ORDER BY clause where the datasets are first sorted ascending * by visibility, then descending by the machine name to which they refer and * finally ascending by their UID: * @code * $strOrder = buildOrderClause(array( * ER_ERM_SORT_VISIBILITY => ER_ERM_SORT_ASC, * ER_ERM_SORT_MACHINE => ER_ERM_SORT_DESC, * ER_ERM_SORT_UID => ER_ERM_SORT_ASC)); * echo $strOrder; * @endcode * The output is: ORDER BY er_hidden ASC, er_machine DESC, er_uid ASC * @internal * @param $arcSort (array of constants) The array which declares the order of * the SQL rows. Use @ref errorreportmanager_sorting as keys and * @ref errorreportmanager_sorting_dir as values. * @return string */ protected function buildOrderByClause($arcSort) { // build the sorting clause $arstrSort = array(); foreach($arcSort as $cSort => $cDir) { switch($cSort) { case ER_ERM_SORT_UID: $arstrSort[] = "er_uid ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_DATE: $arstrSort[] = "er_date ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_OWNER: $arstrSort[] = "er_act ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_MACHINE: $arstrSort[] = "er_machine ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_TEXT: $arstrSort[] = "er_text ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_COMMENT: $arstrSort[] = "er_comment ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_COMMENTOWNER: $arstrSort[] = "er_commentact ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; case ER_ERM_SORT_VISIBILITY: $arstrSort[] = "er_hidden ".($cDir == ER_ERM_SORT_DESC ? "DESC" : "ASC"); break; } } return ("ORDER BY ".join(", ", $arstrSort)); } ////////////////////////// ERROR MESSAGE MANAGEMENT ////////////////////////// /** * @name Error report management * @{ */ /** * Insert or update an error report in the database. * When the $nUid member of the $erErrorReport object is null, a new * unique ID is assigned and the error report is written to the database. * Otherwise, the record having the respective UID in the table is updated. * @param $er (erErrorReport) * @return (int) The unique ID of the inserted or updated record. * @throws Exception */ public function writeErrorReport(erErrorReport $er) { if(!erConfig::userHasAccess() and (!$this->userIsOwner($er->nUid) or ($er->getUid() == null and !(erConfig::userIsAdmin())))) { throw new Exception(ER_ERROR_ACCESS_DENIED); } $strWhere = null; $strLog = ""; // Update or insert? $arPut = array(); if($er->getUid() == null) { // er_uid is now serial /*$hQuery = db_query("SELECT MAX(er_uid) AS id FROM mod_errorreporter;"); if(!is_resource($hQuery)) { setLastError(ER_ERROR_SQL); return -1; } $arResult = pg_fetch_array($hQuery); $er->setUid(intval($arResult["id"]) + 1);*/ $strLog = sprintf("Fehlermeldung für Rechner „%s“ eingetragen.", $er->getMachine()); } else { $strWhere = "er_uid = ".qdb(intval($er->getUid())); $oOldReport = $this->getErrorReportByID($er->getUid()); $strLog = sprintf("Fehlermeldung geändert, Rechner war „%s“, Text war ". "„%s“. Neuer Rechner: „%s“, neuer Text: „%s“, Kommentar: %s", $oOldReport->getMachine(), $oOldReport->getText(), $er->getMachine(), $er->getText(), (strlen($er->getComment()) > 0) ? "„" . $er->getComment() . "“" : "(leer)"); } $arPut["er_date"] = date("Y\-m\-d\ G\:i\:s", $er->getDate()); $arPut["er_act"] = $er->getOwner(); $arPut["er_machine"] = $er->getMachine(); $arPut["er_text"] = $er->getText(); $arPut["er_comment"] = $er->getComment(); $arPut["er_commentact"] = $er->getCommentOwner(); $arPut["er_hidden"] = $er->isHidden() ? "true" : "false"; db_store("mod_errorreporter", $arPut, $strWhere); erInsertLog($strLog); // send notification mail, but only if the message is new if(cfg("errorreportermailnotify") and $er->getUid() == null) { $strMailText = sprintf("\nEin Benutzer hat eine ". "Fehlermeldung mit dem Fehlermeldungs-Assistenten abgeschickt. ". "Nachfolgend finden sich Angaben über den Fehler.\n". "\n\n". "\n". "\n". "\n
Fehler gemeldet von:%s
Datum:%s
Betroffener Rechner:%s
%s
\n
\n". "Diese Mail wurde automatisch generiert.\n". "", q(erGetRealUserName($er->getOwner())), q(date("d\.m\.Y\ G\:i\:s", $er->getDate())), q($er->getMachine()), q($er->getText())); $strMailSubject = sprintf("%s hat einen Fehler im System gemeldet", q(erGetRealUserName($er->getOwner()))); $strMailHeader = sprintf("From: %s <%s>\n". "Content-Type: text/html; charset=utf-8", q(erGetRealUserName($er->getOwner())), user_mail_addr($er->getOwner())); mail(cfg("errorreportermailaddress"), $strMailSubject, $strMailText, $strMailHeader); } return $er->getUid(); } /** * Delete an error report from the database. * @param $nErrorReportID (int) Unique ID of the error report to delete or -1 * if an error occured. In this case, call getLastError() to get more * information. */ public function deleteErrorReport($nErrorReportID) { if(!(erConfig::userIsAdmin() or $this->userIsOwner($nErrorReportID))) { setLastError(ER_ERROR_ACCESS_DENIED); return -1; } $oOldReport = $this->getErrorReportByID($nErrorReportID); db_query(sprintf("DELETE FROM mod_errorreporter WHERE er_uid = '%d';", intval($nErrorReportID))); erInsertLog(sprintf("Fehlermeldung gelöscht, Rechner war „%s“, Text war ". "„%s“", $oOldReport->getMachine(), $oOldReport->getText())); } /** * Determine if the current user is the owner of a specified error report. * If this function fails, call getLastError() to get more information. * @param $nID (int) Unique ID of the error report * @return bool */ public function userIsOwner($nID) { if(!$_SESSION["act"]) { return false; // user is not logged in } else { $hQuery = db_query(sprintf("SELECT er_act FROM mod_errorreporter WHERE ". "er_uid = %d;", intval($nID))); if(!is_resource($hQuery)) { setLastError(ER_ERROR_SQL); return false; } $arResult = pg_fetch_array($hQuery); return ($arResult["er_act"] == $_SESSION["act"]); } } } ?>