diff --git a/model/dao/ExtraHourDAO/ExtraHourDAO.php b/model/dao/ExtraHourDAO/ExtraHourDAO.php index 30ef886a8..9b136a289 100644 --- a/model/dao/ExtraHourDAO/ExtraHourDAO.php +++ b/model/dao/ExtraHourDAO/ExtraHourDAO.php @@ -40,17 +40,6 @@ */ abstract class ExtraHourDAO extends BaseDAO{ - /** Extra Hour DAO constructor. - * - * This is the base constructor of Extra Hour DAOs, and it just calls its parent's constructor. - * - * @throws {@link ConnectionErrorException} - * @see BaseDAO::__construct() - */ - protected function __construct() { - parent::__construct(); - } - /** Extra Hour retriever by id. * * This function retrieves the row from Extra Hour table with the id $extraHourId and creates an {@link ExtraHourVO} with its data. @@ -61,18 +50,6 @@ protected function __construct() { */ public abstract function getById($extraHourId); - /** Extra Hours retriever by User id. - * - * This function retrieves the rows from Extra Hour table that are associated with the User with - * the id $userId and creates an {@link ExtraHourVO} with data from each row. - * - * @param int $userId the id of the User whose Extra Hours we want to retrieve. - * @return array an array with value objects {@link ExtraHourVO} with their properties set to the values from the rows - * and ordered ascendantly by their database internal identifier. - * @throws {@link OperationErrorException} - */ - public abstract function getByUserId($userId); - /** Extra Hour last entry retriever by User id and date. * * This function retrieves the latest row from Extra Hour table that is associated with the User with diff --git a/model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php b/model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php index 469359685..45f85467f 100644 --- a/model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php +++ b/model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php @@ -53,27 +53,6 @@ function __construct() { parent::__construct(); } - /** Extra Hour value object constructor for PostgreSQL. - * - * This function creates a new {@link ExtraHourVO} with data retrieved from database. - * - * @param array $row an array with the Extra Hour values from a row. - * @return ExtraHourVO an {@link ExtraHourVO} with its properties set to the values from $row. - * @see ExtraHourVO - */ - protected function setValues($row) - { - $extraHourVO = new ExtraHourVO(); - - $extraHourVO->setId($row['id']); - $extraHourVO->setDate(date_create($row['_date'])); - $extraHourVO->setHours($row['hours']); - $extraHourVO->setUserId($row['usrid']); - $extraHourVO->setComment($row['comment']); - - return $extraHourVO; - } - /** Extra Hour retriever by id for PostgreSQL. * * This function retrieves the row from Extra Hour table with the id $extraHourId and creates an {@link ExtraHourVO} with its data. @@ -83,32 +62,11 @@ protected function setValues($row) * @throws {@link SQLQueryErrorException} */ public function getById($extraHourId) { - if (!is_numeric($extraHourId)) - throw new SQLIncorrectTypeException($extraHourId); - $sql = "SELECT * FROM extra_hour WHERE id=".$extraHourId; - $result = $this->execute($sql); - - if (empty($result)) - return NULL; - return $result[0]; - } - - /** Extra Hours retriever by User id for PostgreSQL. - * - * This function retrieves the rows from Extra Hour table that are associated with the User with - * the id $userId and creates an {@link ExtraHourVO} with data from each row. - * - * @param int $userId the id of the User whose Extra Hours we want to retrieve. - * @return array an array with value objects {@link ExtraHourVO} with their properties set to the values from the rows - * and ordered ascendantly by their database internal identifier. - * @throws {@link SQLQueryErrorException} - */ - public function getByUserId($userId) { - if (!is_numeric($userId)) - throw new SQLIncorrectTypeException($userId); - $sql = "SELECT * FROM extra_hour WHERE usrid=" . $userId . " ORDER BY id ASC"; - $result = $this->execute($sql); - return $result; + $result = $this->runSelectQuery( + "SELECT * FROM extra_hour WHERE id=:extraHourId", + [':extraHourId' => $extraHourId], + 'ExtraHourVO'); + return $result[0] ?? NULL; } /** Extra Hour last entry retriever by User id and date for PostgreSQL. @@ -124,12 +82,13 @@ public function getByUserId($userId) { public function getLastByUserId($userId, DateTime $nowadays) { if (!is_numeric($userId)) throw new SQLIncorrectTypeException($userId); - $sql = "SELECT * FROM extra_hour WHERE usrid=" . $userId . " AND _date <=" . DBPostgres::formatDate($nowadays) . " ORDER BY _date DESC LIMIT 1"; - $result = $this->execute($sql); - - if (empty($result)) - return NULL; - return $result[0]; + $result = $this->runSelectQuery( + "SELECT * FROM extra_hour " . + "WHERE usrid=:userId AND _date <= :nowadays " . + "ORDER BY _date DESC LIMIT 1", + [':userId' => $userId, ':nowadays' => DBPostgres::formatDate($nowadays)], + 'ExtraHourVO'); + return $result[0] ?? NULL; } /** Extra Hours retriever for PostgreSQL. @@ -142,7 +101,7 @@ public function getLastByUserId($userId, DateTime $nowadays) { */ public function getAll() { $sql = "SELECT * FROM extra_hour ORDER BY id ASC"; - return $this->execute($sql); + return $this->runSelectQuery($sql, [], 'ExtraHourVO'); } /** Extra Hour updater for PostgreSQL. @@ -154,32 +113,28 @@ public function getAll() { * @throws {@link SQLQueryErrorException}, {@link SQLUniqueViolationException} */ public function update(ExtraHourVO $extraHourVO) { - $affectedRows = 0; - - if($extraHourVO->getId() != "") { - $currExtraHourVO = $this->getById($extraHourVO->getId()); - } - - // If the query returned a row then update - if(sizeof($currExtraHourVO) > 0) { - - $sql = "UPDATE extra_hour SET " . - "_date=" .DBPostgres::formatDate($extraHourVO->getDate()) . - ", hours=" . DBPostgres::checkNull($extraHourVO->getHours()) . - ", usrid=" . DBPostgres::checkNull($extraHourVO->getUserId()) . - ", comment=" . DBPostgres::checkStringNull($extraHourVO->getComment()) . - " WHERE id=".$extraHourVO->getId(); - - $res = pg_query($this->connect, $sql); - - if ($res == NULL) - if (strpos(pg_last_error(), "unique_extra_hour_user_date")) - throw new SQLUniqueViolationException(pg_last_error()); - else throw new SQLQueryErrorException(pg_last_error()); + $affectedRows = 0; - $affectedRows = pg_affected_rows($res); + $sql = "UPDATE extra_hour " . + "SET _date=:date, hours=:hours, usrid=:usrid, comment=:comment " . + "WHERE id=:id"; + try { + $statement = $this->pdo->prepare($sql); + $statement->bindValue(":date", DBPostgres::formatDate($extraHourVO->getDate()), PDO::PARAM_STR); + $statement->bindValue(":usrid", $extraHourVO->getUserId(), PDO::PARAM_INT); + $statement->bindValue(":comment", $extraHourVO->getComment(), PDO::PARAM_STR); + $statement->bindValue(":id", $extraHourVO->getId(), PDO::PARAM_INT); + // Notice there is no specific parameter for floating point values. A proposal + // existed but did not land: https://wiki.php.net/rfc/pdo_float_type + // The current recommended practice is to use PDO::PARAM_STR. + $statement->bindValue(":hours", $extraHourVO->getHours(), PDO::PARAM_STR); + $statement->execute(); + + $affectedRows = $statement->rowCount(); + } catch (PDOException $e) { + error_log('Query failed: ' . $e->getMessage()); + throw new SQLQueryErrorException($e->getMessage()); } - return $affectedRows; } @@ -195,25 +150,27 @@ public function update(ExtraHourVO $extraHourVO) { public function create(ExtraHourVO $extraHourVO) { $affectedRows = 0; - $sql = "INSERT INTO extra_hour (_date, hours, usrid, comment) VALUES(" . - DBPostgres::formatDate($extraHourVO->getDate()) . ", " . - DBPostgres::checkNull($extraHourVO->getHours()) . "," . - DBPostgres::checkNull($extraHourVO->getUserId()) . "," . - DBPostgres::checkStringNull($extraHourVO->getComment()) . ")"; - - $res = pg_query($this->connect, $sql); - - if ($res == NULL) - if (strpos(pg_last_error(), "unique_extra_hour_user_date")) - throw new SQLUniqueViolationException(pg_last_error()); - else throw new SQLQueryErrorException(pg_last_error()); - - $extraHourVO->setId(DBPostgres::getId($this->connect, "extra_hour_id_seq")); - - $affectedRows = pg_affected_rows($res); - + $sql = "INSERT INTO extra_hour (_date, hours, usrid, comment) " . + "VALUES (:date, :hours, :usrid, :comment)"; + try { + $statement = $this->pdo->prepare($sql); + $statement->bindValue(":date", DBPostgres::formatDate($extraHourVO->getDate()), PDO::PARAM_STR); + $statement->bindValue(":usrid", $extraHourVO->getUserId(), PDO::PARAM_INT); + $statement->bindValue(":comment", $extraHourVO->getComment(), PDO::PARAM_STR); + // Notice there is no specific parameter for floating point values. A proposal + // existed but did not land: https://wiki.php.net/rfc/pdo_float_type + // The current recommended practice is to use PDO::PARAM_STR. + $statement->bindValue(":hours", $extraHourVO->getHours(), PDO::PARAM_STR); + $statement->execute(); + + $extraHourVO->setId($this->pdo->lastInsertId('extra_hour_id_seq')); + + $affectedRows = $statement->rowCount(); + } catch (PDOException $e) { + error_log('Query failed: ' . $e->getMessage()); + throw new SQLQueryErrorException($e->getMessage()); + } return $affectedRows; - } /** Extra Hour deleter for PostgreSQL. @@ -227,65 +184,17 @@ public function create(ExtraHourVO $extraHourVO) { public function delete(ExtraHourVO $extraHourVO) { $affectedRows = 0; - // Check for a user ID. - if($extraHourVO->getId() >= 0) { - $currExtraHourVO = $this->getById($extraHourVO->getId()); - } - - // Otherwise delete a user. - if(sizeof($currExtraHourVO) > 0) { - $sql = "DELETE FROM extra_hour WHERE id=".$extraHourVO->getId(); - - $res = pg_query($this->connect, $sql); - if ($res == NULL) throw new SQLQueryErrorException(pg_last_error()); - $affectedRows = pg_affected_rows($res); - } + $sql = "DELETE FROM extra_hour WHERE id=:id"; + try { + $statement = $this->pdo->prepare($sql); + $statement->bindValue(":id", $extraHourVO->getId(), PDO::PARAM_INT); + $statement->execute(); + $affectedRows = $statement->rowCount(); + } catch (PDOException $e) { + error_log('Query failed: ' . $e->getMessage()); + throw new SQLQueryErrorException($e->getMessage()); + } return $affectedRows; } } - - - - -/*//Uncomment these lines in order to do a simple test of the Dao - - - -$dao = new PostgreSQLExtraHourDAO(); - -// We create a new extra hour - -$extraHour = new ExtraHourVO(); - -$extraHour->setDate(date_create('2005-12-21')); -$extraHour->setHours(3); -$extraHour->setUserId(1); - -$dao->create($extraHour); - -print ("New extra hour Id is ". $extraHour->getId() ."\n"); - -// We search for the new Id - -$extraHour = $dao->getById($extraHour->getId()); - -print ("New extra hour Id found is ". $extraHour->getId() ."\n"); - -print ("New extra hour Date found is ". DBPostgres::formatDate($extraHour->getDate()) ."\n"); - -// We update the extra hour with a differente number of hours - -$extraHour->setHours(5); - -$dao->update($extraHour); - -// We search for the new value of hours - -$extraHour = $dao->getById($extraHour->getId()); - -print ("New extra hour hours value found is ". $extraHour->getHours() ."\n"); - -// We delete the new extra hour - -$dao->delete($extraHour);*/ diff --git a/model/vo/ExtraHourVO.php b/model/vo/ExtraHourVO.php index 129ce01f3..1d0eecaba 100644 --- a/model/vo/ExtraHourVO.php +++ b/model/vo/ExtraHourVO.php @@ -33,22 +33,25 @@ * * This class just stores Extra Hour data. * + * NOTICE: properties must match column names in the DB, for PDO::FETCH_CLASS + * to work properly. + * * @property int $id database internal identifier. - * @property int $userId database internal identifier of the associated User. + * @property int $usrid database internal identifier of the associated User. * @property DateTime $date date of the Extra Hour. * @property double $hours number of extra hours. */ class ExtraHourVO { protected $id = NULL; - protected $userId = NULL; + protected $usrid = NULL; protected $date = NULL; protected $hours = NULL; protected $comment = NULL; public function setId($id) { if (is_null($id)) - $this->id = $id; - else + $this->id = $id; + else $this->id = (int) $id; } @@ -58,13 +61,13 @@ public function getId() { public function setUserId($userId) { if (is_null($userId)) - $this->userId = $userId; - else - $this->userId = (int) $userId; + $this->usrid = $userId; + else + $this->usrid = (int) $userId; } public function getUserId() { - return $this->userId; + return $this->usrid; } public function setDate(DateTime $date = NULL) { @@ -77,8 +80,8 @@ public function getDate() { public function setHours($hours) { if (is_null($hours)) - $this->hours = $hours; - else + $this->hours = $hours; + else $this->hours = (double) $hours; } @@ -93,4 +96,22 @@ public function setComment($comment) { public function getComment() { return $this->comment; } + + /* PHP will magically call this function to set the value of a property that + * does not exist yet. We can take advantage of this to properly set the + * $date property from the string stored in the DB during PDO::FETCH_CLASS. + * When PDO::FETCH_CLASS calls `__set('_date', $dateString)`, we will + * convert the string into a DateTime object. + * + * See: + * https://www.php.net/manual/en/language.oop5.overloading.php#object.set + * https://stackoverflow.com/a/69641430 + */ + public function __set($property, $value) { + if ($property === '_date') { + $this->date = date_create($value); + } else { + $this->$property = $value; + } + } } diff --git a/web/hourCompensationManagement.php b/web/hourCompensationManagement.php index 856a937fd..4e3a8a17b 100644 --- a/web/hourCompensationManagement.php +++ b/web/hourCompensationManagement.php @@ -30,7 +30,6 @@ define('PHPREPORT_ROOT', __DIR__ . '/../'); /* We check authentication and authorization */ -$sid = $_GET["sid"]; require_once(PHPREPORT_ROOT . '/web/auth.php'); /* Include the generic header and sidebar */ diff --git a/web/services/createExtraHourVOsService.php b/web/services/createExtraHourVOsService.php index 7c382d4f4..5e342f016 100644 --- a/web/services/createExtraHourVOsService.php +++ b/web/services/createExtraHourVOsService.php @@ -142,7 +142,6 @@ } while ($parser->read()); - if (count($createExtraHours) >= 1) foreach((array)$createExtraHours as $hour) { @@ -154,9 +153,7 @@ } - - - if (!$string) + if (!isset($string)) { $string = "Operation Success!"; diff --git a/web/services/deleteExtraHourVOsService.php b/web/services/deleteExtraHourVOsService.php index 66090f2db..8960b7a6e 100644 --- a/web/services/deleteExtraHourVOsService.php +++ b/web/services/deleteExtraHourVOsService.php @@ -106,7 +106,6 @@ } while ($parser->read()); - if (count($extraHoursList) >= 1) foreach((array)$extraHoursList as $hour) { @@ -118,13 +117,9 @@ } - - - if (!$string) + if (!isset($string)) { - $string = "Operation Success!"; - } } while (false); diff --git a/web/services/getAllExtraHourVOsService.php b/web/services/getAllExtraHourVOsService.php index 8d043204e..d977f9e86 100644 --- a/web/services/getAllExtraHourVOsService.php +++ b/web/services/getAllExtraHourVOsService.php @@ -31,7 +31,7 @@ include_once(PHPREPORT_ROOT . '/web/services/WebServicesFunctions.php'); include_once(PHPREPORT_ROOT . '/model/facade/UsersFacade.php'); - $sid = $_GET['sid']; + $sid = $_GET['sid'] ?? NULL; do { /* We check authentication and authorization */ diff --git a/web/services/updateExtraHourVOsService.php b/web/services/updateExtraHourVOsService.php index eb8489c81..a8d2d029b 100644 --- a/web/services/updateExtraHourVOsService.php +++ b/web/services/updateExtraHourVOsService.php @@ -152,7 +152,6 @@ } while ($parser->read()); - if (count($extraHoursList) >= 1) foreach((array)$extraHoursList as $hour) { @@ -164,9 +163,7 @@ } - - - if (!$string) + if (!isset($string)) { $string = "Operation Success!";