mirror of
https://github.com/antonkomarev/github-profile-views-counter.git
synced 2026-07-29 08:42:38 -04:00
@@ -16,20 +16,24 @@ namespace Komarev\GitHubProfileViewsCounter;
|
||||
use Contracts\Komarev\GitHubProfileViewsCounter\CounterRepositoryInterface;
|
||||
use PDO;
|
||||
|
||||
final class CounterDatabaseRepository implements CounterRepositoryInterface
|
||||
final class CounterDatabaseRepository implements
|
||||
CounterRepositoryInterface
|
||||
{
|
||||
private PDO $connection;
|
||||
|
||||
public function __construct(PDO $connection)
|
||||
private string $tableName;
|
||||
|
||||
public function __construct(PDO $connection, string $tableName = null)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->tableName = $tableName !== null ? $tableName : 'github_profile_views';
|
||||
}
|
||||
|
||||
public function getViewsCountByUsername(string $username): int
|
||||
public function getViewsCountByUsername(Username $username): int
|
||||
{
|
||||
$statement = $this->connection->prepare(
|
||||
'SELECT COUNT(*)
|
||||
FROM github_profile_views
|
||||
FROM ' . $this->tableName . '
|
||||
WHERE username = :username;'
|
||||
);
|
||||
$statement->bindParam('username', $username);
|
||||
@@ -38,10 +42,10 @@ final class CounterDatabaseRepository implements CounterRepositoryInterface
|
||||
return (int) $statement->fetchColumn(0);
|
||||
}
|
||||
|
||||
public function addViewByUsername(string $username): void
|
||||
public function addViewByUsername(Username $username): void
|
||||
{
|
||||
$statement = $this->connection->prepare(
|
||||
'INSERT INTO github_profile_views
|
||||
'INSERT INTO ' . $this->tableName . '
|
||||
(username, created_at)
|
||||
VALUES (:username, NOW());'
|
||||
);
|
||||
|
||||
@@ -18,7 +18,8 @@ use Contracts\Komarev\GitHubProfileViewsCounter\InvalidPathException;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
|
||||
final class CounterFileRepository implements CounterRepositoryInterface
|
||||
final class CounterFileRepository implements
|
||||
CounterRepositoryInterface
|
||||
{
|
||||
private string $storagePath;
|
||||
|
||||
@@ -35,38 +36,43 @@ final class CounterFileRepository implements CounterRepositoryInterface
|
||||
$this->storagePath = $storagePath;
|
||||
}
|
||||
|
||||
public function getViewsCountByUsername(string $username): int
|
||||
public function getViewsCountByUsername(Username $username): int
|
||||
{
|
||||
$counterFilePath = $this->getCounterFilePath($username);
|
||||
|
||||
return file_exists($counterFilePath) ? (int) file_get_contents($counterFilePath) : 0;
|
||||
}
|
||||
|
||||
public function addViewByUsername(string $username): void
|
||||
public function addViewByUsername(Username $username): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->getViewsFilePath($username),
|
||||
(new DateTimeImmutable('now', new DateTimeZone('UTC')))->format(DATE_RFC3339_EXTENDED) . PHP_EOL,
|
||||
$this->getCurrentFormattedDateTime() . PHP_EOL,
|
||||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->incrementViewsCount($username);
|
||||
}
|
||||
|
||||
private function incrementViewsCount(string $username): void
|
||||
private function incrementViewsCount(Username $username): void
|
||||
{
|
||||
$counterFilePath = $this->getCounterFilePath($username);
|
||||
|
||||
file_put_contents($counterFilePath, $this->getViewsCountByUsername($username) + 1);
|
||||
}
|
||||
|
||||
private function getViewsFilePath(string $username): string
|
||||
private function getViewsFilePath(Username $username): string
|
||||
{
|
||||
return $this->storagePath . '/' . $username . '-views';
|
||||
}
|
||||
|
||||
private function getCounterFilePath(string $username): string
|
||||
private function getCounterFilePath(Username $username): string
|
||||
{
|
||||
return $this->storagePath . '/' . $username . '-views-count';
|
||||
}
|
||||
|
||||
private function getCurrentFormattedDateTime(): string
|
||||
{
|
||||
return (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format(DATE_RFC3339_EXTENDED);
|
||||
}
|
||||
}
|
||||
|
||||
44
src/Username.php
Normal file
44
src/Username.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of PHP GitHub Profile.
|
||||
*
|
||||
* (c) Anton Komarev <anton@komarev.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Komarev\GitHubProfileViewsCounter;
|
||||
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class Username
|
||||
{
|
||||
private const MIN_LENGTH = 1;
|
||||
|
||||
private const MAX_LENGTH = 39;
|
||||
|
||||
/**
|
||||
* RegEx adapted from https://github.com/shinnn/github-username-regex/blob/master/index.js
|
||||
*/
|
||||
private const REGEX = '#^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$#i';
|
||||
|
||||
private string $username;
|
||||
|
||||
public function __construct(string $username)
|
||||
{
|
||||
Assert::minLength($username, self::MIN_LENGTH);
|
||||
Assert::maxLength($username, self::MAX_LENGTH);
|
||||
Assert::regex($username, self::REGEX, 'Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.');
|
||||
|
||||
$this->username = strtolower($username);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user