Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Extra Hour DAO to use PDO #575

Merged
merged 8 commits into from
Apr 19, 2022
23 changes: 0 additions & 23 deletions model/dao/ExtraHourDAO/ExtraHourDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <var>$extraHourId</var> and creates an {@link ExtraHourVO} with its data.
Expand All @@ -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 <var>$userId</var> 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
Expand Down
217 changes: 63 additions & 154 deletions model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <var>$row</var>.
* @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 <var>$extraHourId</var> and creates an {@link ExtraHourVO} with its data.
Expand All @@ -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 <var>$userId</var> 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.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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;
}

Expand All @@ -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.
Expand All @@ -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);*/
41 changes: 31 additions & 10 deletions model/vo/ExtraHourVO.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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) {
Expand All @@ -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;
}

Expand All @@ -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;
}
}
}
1 change: 0 additions & 1 deletion web/hourCompensationManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
Loading