diff --git a/app/composer.lock b/app/composer.lock index d3c679b..a665e11 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -605,16 +605,16 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.3.5", + "version": "v1.3.6", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c" + "reference": "f865a58ea3a0107c336b7045104c75243fa59d96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c", - "reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f865a58ea3a0107c336b7045104c75243fa59d96", + "reference": "f865a58ea3a0107c336b7045104c75243fa59d96", "shasum": "" }, "require": { @@ -662,7 +662,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2024-09-23T13:33:08+00:00" + "time": "2024-11-11T17:06:04+00:00" }, { "name": "league/config", @@ -1018,16 +1018,16 @@ }, { "name": "monolog/monolog", - "version": "3.7.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8" + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", "shasum": "" }, "require": { @@ -1047,12 +1047,14 @@ "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^10.5.17", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", "predis/predis": "^1.1 || ^2", - "ruflin/elastica": "^7", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -1103,7 +1105,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.7.0" + "source": "https://github.com/Seldaek/monolog/tree/3.8.0" }, "funding": [ { @@ -1115,7 +1117,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:40:51+00:00" + "time": "2024-11-12T13:57:08+00:00" }, { "name": "nette/schema", @@ -3056,16 +3058,16 @@ }, { "name": "symfony/console", - "version": "v7.1.7", + "version": "v7.1.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a" + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3284aafcac338b6e86fd955ee4d794cbe434151a", - "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a", + "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", "shasum": "" }, "require": { @@ -3129,7 +3131,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.7" + "source": "https://github.com/symfony/console/tree/v7.1.8" }, "funding": [ { @@ -3145,7 +3147,7 @@ "type": "tidelift" } ], - "time": "2024-11-05T15:34:55+00:00" + "time": "2024-11-06T14:23:19+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3839,16 +3841,16 @@ }, { "name": "symfony/string", - "version": "v7.1.6", + "version": "v7.1.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626" + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626", - "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626", + "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", "shasum": "" }, "require": { @@ -3906,7 +3908,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.6" + "source": "https://github.com/symfony/string/tree/v7.1.8" }, "funding": [ { @@ -3922,7 +3924,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-13T13:31:21+00:00" }, { "name": "twig/twig", @@ -4497,16 +4499,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.5.1", + "version": "5.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "0c70d2c566e899666f367ab7b80986beb3581e6f" + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/0c70d2c566e899666f367ab7b80986beb3581e6f", - "reference": "0c70d2c566e899666f367ab7b80986beb3581e6f", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c", + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c", "shasum": "" }, "require": { @@ -4515,7 +4517,7 @@ "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1" }, "require-dev": { @@ -4555,9 +4557,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.5.1" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0" }, - "time": "2024-11-06T11:58:54+00:00" + "time": "2024-11-12T11:25:25+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -4740,30 +4742,30 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.33.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", - "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^5.3.0", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", "symfony/process": "^5.2" }, "type": "library", @@ -4781,9 +4783,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0" }, - "time": "2024-10-13T11:25:22+00:00" + "time": "2024-10-13T11:29:49+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/app/src/Domain/Entity/Episode.php b/app/src/Domain/Entity/Episode.php index fb58b58..9021224 100644 --- a/app/src/Domain/Entity/Episode.php +++ b/app/src/Domain/Entity/Episode.php @@ -21,7 +21,7 @@ class Episode private DateTimeImmutable $publishedDate, private string $episodeType, ) { - $this->duration = $this->parseDuration($this->length); + $this->duration = self::parseDurationFromLength($this->length); } public function getTitle(): string @@ -72,13 +72,42 @@ class Episode /** * @TODO Figure out how to parse second to HH:MM:SS */ - public static function parseDuration(int $length): string + public static function parseDurationFromLength(int $length): string { $hours = floor($length / 3600); $minutes = floor($length / 60) % 60; $seconds = $length % 60; - return ""; + $buffer = ""; + + if ($hours) { + if ($hours < 10) { + $hours = "0" . $hours; + } + + $buffer = "{$hours}:"; + } + + if ($minutes) { + if ($minutes < 10) { + $minutes = "0" . $minutes; + } + + $buffer .= "{$minutes}:"; + } else { + $buffer .= "00:"; + } + + if ($seconds) { + if ($seconds < 10) { + $seconds = "0" . $seconds; + } + $buffer .= "{$seconds}"; + } else { + $buffer .= "00"; + } + + return $buffer; } /** diff --git a/app/src/Domain/Repository/User/UserRepository.php b/app/src/Domain/Repository/User/UserRepository.php index b486278..0fae9bb 100644 --- a/app/src/Domain/Repository/User/UserRepository.php +++ b/app/src/Domain/Repository/User/UserRepository.php @@ -2,6 +2,8 @@ namespace Slovocast\Domain\Repository\User; +use DateTime; +use DateTimeImmutable; use Slovocast\Domain\Entity\User; use Slovocast\Exception\EntityNotFoundException; use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface; @@ -65,22 +67,26 @@ class UserRepository implements UserRepositoryInterface return $this->userFromQueryResults($results); } - public function create(User $user): User + public function create(User $user): bool { $query = "INSERT INTO users (email, password, name) VALUES (:email, :password, :name)"; $statement = $this->db->getConnection()->prepare($query); - $statement->execute([ + $results = $statement->execute([ ':email' => $user->getEmail(), ':password' => $this->userAuth->hash($user->getPassword()), ':name' => $user->getName(), ]); - $insertId = $this->db->getConnection()->lastInsertId(); - $user->setId($insertId); - - return $user; + if ($results) { + $insertId = $this->db->getConnection()->lastInsertId(); + $user->setId($insertId); + $user->setCreatedAt(new DateTimeImmutable()); + $user->setUpdatedAt(new DateTime()); + } + + return $results; } public function update(User $user): bool @@ -92,12 +98,18 @@ class UserRepository implements UserRepositoryInterface WHERE id = :id"; $statement = this->db->prepare($query); - return $statement->execute([ + $results = $statement->execute([ $user->getEmail(), $user->getName(), $this->userAuth->hash($user->getPassword()), $user->getId() ]); + + if ($results == true) { + $user->setUpdatedAt(new DateTime()); + } + + return $results; } /** diff --git a/app/src/Domain/Repository/User/UserRepositoryInterface.php b/app/src/Domain/Repository/User/UserRepositoryInterface.php index 83208f2..4d2af5c 100644 --- a/app/src/Domain/Repository/User/UserRepositoryInterface.php +++ b/app/src/Domain/Repository/User/UserRepositoryInterface.php @@ -8,7 +8,7 @@ interface UserRepositoryInterface { public function get(int $id): User; public function getFromEmail(string $email): User; - public function create(User $user): User; + public function create(User $user): bool; public function update(User $user): bool; public function delete(User $user): bool; public function verifyPassword(string $email, string $password): bool; diff --git a/app/tests/Controller/User/RegisterUserActionTest.php b/app/tests/Controller/User/RegisterUserActionTest.php index e011d6b..d4b0df1 100644 --- a/app/tests/Controller/User/RegisterUserActionTest.php +++ b/app/tests/Controller/User/RegisterUserActionTest.php @@ -22,7 +22,7 @@ class RegisterUserActionTest extends TestCase protected function createNewUserRequest(): Request { $user = $this->getUser(); - return $this->createRequest('POST', '/users/register') + return $this->createRequest('POST', '/register') ->withParsedBody([ 'email' => $user->getEmail(), 'name' => $user->getName(), @@ -34,7 +34,7 @@ class RegisterUserActionTest extends TestCase protected function createNewUserRequestWithMismatchedPasswords(): Request { $user = $this->getUser(); - return $this->createRequest('POST', '/users/register') + return $this->createRequest('POST', '/register') ->withParsedBody([ 'email' => $user->getEmail(), 'name' => $user->getName(), diff --git a/app/tests/Domain/Entity/Episode.php b/app/tests/Domain/Entity/Episode.php new file mode 100644 index 0000000..29e9c3e --- /dev/null +++ b/app/tests/Domain/Entity/Episode.php @@ -0,0 +1,21 @@ +assertEquals("01:30:00", $r); + } + +}