inital commit
This commit is contained in:
commit
f3205fe53d
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.idea
|
||||||
|
vendor
|
||||||
|
var/
|
||||||
16
composer.json
Normal file
16
composer.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.2",
|
||||||
|
"symfony/http-client": "^7.1",
|
||||||
|
"dflydev/hawk": "^0.0.0",
|
||||||
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
|
"symfony/dotenv": "^7.1",
|
||||||
|
"symfony/cache": "^7.1",
|
||||||
|
"ext-intl": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
1504
composer.lock
generated
Normal file
1504
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
config/nginx.conf
Normal file
19
config/nginx.conf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
root /home/tim/app/public;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
include snippets/fastcgi-php.conf;
|
||||||
|
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
146
public/index.php
Normal file
146
public/index.php
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Arbeitstage FTK - Tim Lappe</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>
|
||||||
|
.type-urlaub {
|
||||||
|
background-color: rgb(166, 199, 203);
|
||||||
|
}
|
||||||
|
.type-ftk {
|
||||||
|
background-color: rgb(0, 124, 0);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 10;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (!isset($_GET['key']) || $_GET['key'] !== "74857389798572903480209489024") {
|
||||||
|
echo "Kein Zugriff";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
use App\App;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
Locale::setDefault('de_DE');
|
||||||
|
setlocale(LC_ALL, "de_DE"); //only necessary if the locale isn't already set
|
||||||
|
|
||||||
|
$formatter = new IntlDateFormatter(
|
||||||
|
'de_DE',
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
IntlDateFormatter::FULL,
|
||||||
|
'Europe/Berlin',
|
||||||
|
IntlDateFormatter::GREGORIAN,
|
||||||
|
'EEEE'
|
||||||
|
);
|
||||||
|
|
||||||
|
$app = new App();
|
||||||
|
$app->init();
|
||||||
|
|
||||||
|
$data = ($app->getAbsenceClient())->getAbsences([
|
||||||
|
'skip' => 0,
|
||||||
|
'limit' => 50,
|
||||||
|
'filter' => [
|
||||||
|
'start' => ['$gte' => (new DateTime('-1 day'))->format('Y-m-d\TH:i:s.u\Z')],
|
||||||
|
'assignedTo:user._id' => [
|
||||||
|
'email' => 'tim.lappe@check24.de'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'sortBy' => [
|
||||||
|
'start' => 1
|
||||||
|
],
|
||||||
|
'relations' => ['assignedToId', 'reasonId', 'approverId']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = $data['data'];
|
||||||
|
|
||||||
|
// Funktion zum Erstellen einer Liste aller Tage in einem bestimmten Zeitraum
|
||||||
|
function getAllDays($startDate, $endDate) {
|
||||||
|
$period = new DatePeriod(
|
||||||
|
new DateTime($startDate),
|
||||||
|
new DateInterval('P1D'),
|
||||||
|
(new DateTime($endDate))->modify('+1 day')
|
||||||
|
);
|
||||||
|
|
||||||
|
$days = [];
|
||||||
|
foreach ($period as $date) {
|
||||||
|
$days[] = $date->format('Y-m-d');
|
||||||
|
}
|
||||||
|
return $days;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beispiel: Zeitraum eines Monats (kann angepasst werden)
|
||||||
|
$startDate = (new DateTime())->format('Y-m-d');
|
||||||
|
$endDate = (new DateTime('+90 days'))->format('Y-m-d');
|
||||||
|
$allDays = getAllDays($startDate, $endDate);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
|
<h1>Arbeitstage FTK - Tim Lappe</h1>
|
||||||
|
<p>Zeitraum: <?= $startDate; ?> - <?= $endDate; ?></p>
|
||||||
|
<table class="table table-borderless" style="table-layout: fixed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 100px">Datum</th>
|
||||||
|
<th>Wochentag</th>
|
||||||
|
<th>Typ</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($allDays as $day): ?>
|
||||||
|
<?php
|
||||||
|
$reason = '';
|
||||||
|
$isFtk = false;
|
||||||
|
$isUrlaub = false;
|
||||||
|
$class = 'bg-light text-dark';
|
||||||
|
|
||||||
|
// Prüfen, ob es für diesen Tag eine Abwesenheit gibt
|
||||||
|
foreach ($data as $absence) {
|
||||||
|
foreach ($absence['days'] as $absenceDay) {
|
||||||
|
if ((new DateTime($absenceDay['date']))->format('Y-m-d') === $day) {
|
||||||
|
$reason = $absence['reason']['name'];
|
||||||
|
$isFtk = str_contains($reason, 'mobile Arbeit');
|
||||||
|
$isUrlaub = str_contains($reason, 'Urlaub') || str_contains($reason, 'Sonderurlaub');
|
||||||
|
$class = $isFtk ? 'type-ftk' : '';
|
||||||
|
$class = $isUrlaub ? 'type-urlaub' : $class;
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (DateTimeImmutable::createFromFormat('Y-m-d', $day)->format('N') == 6): ?>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<?php continue; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (DateTimeImmutable::createFromFormat('Y-m-d', $day)->format('N') == 7): ?>
|
||||||
|
<tr class="bg-white text-secondary">
|
||||||
|
<td colspan="2">KW <?php echo ((int) (new DateTime($day))->format('W')) + 1; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php continue; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
<tr class="<?= $class ?>">
|
||||||
|
<td><?= (new DateTime($day))->format('d.m.Y'); ?></td>
|
||||||
|
<td><?= $formatter->format((new DateTime($day))) ?></td>
|
||||||
|
<td><?php if ($isFtk): ?>FTK<?php endif; ?> <?php if($isUrlaub): ?>Urlaub<?php endif; ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
70
src/AbsenceClient.php
Normal file
70
src/AbsenceClient.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Dflydev\Hawk\Client\ClientBuilder;
|
||||||
|
use Dflydev\Hawk\Credentials\Credentials;
|
||||||
|
use GuzzleHttp\Client as Guzzle;
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
use GuzzleHttp\Psr7\Request;
|
||||||
|
use Psr\Cache\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||||
|
|
||||||
|
class AbsenceClient
|
||||||
|
{
|
||||||
|
private Guzzle $client;
|
||||||
|
|
||||||
|
private FilesystemAdapter $cache;
|
||||||
|
|
||||||
|
public function __construct(private string $key, private string $id)
|
||||||
|
{
|
||||||
|
$this->client = new Guzzle();
|
||||||
|
$this->cache = new FilesystemAdapter(defaultLifetime: 3600, directory: __DIR__ . '/../var/cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRequest(string $method, string $path, array $data): Request
|
||||||
|
{
|
||||||
|
$credentials = new Credentials($this->key, 'sha256', $this->id);
|
||||||
|
$client = ClientBuilder::create()->build();
|
||||||
|
$request = $client->createRequest(
|
||||||
|
$credentials,
|
||||||
|
$path,
|
||||||
|
$method,
|
||||||
|
['content-type' => 'application/json']
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Request($method, $path, [
|
||||||
|
'Authorization' => $request->header()->fieldValue(),
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
], json_encode($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getAbsences(array $filter): array
|
||||||
|
{
|
||||||
|
$request = $this->cache->get("get_absences", function ($item) use ($filter) {
|
||||||
|
echo "Cache miss\n";
|
||||||
|
$item->expiresAfter(3600);
|
||||||
|
|
||||||
|
$request = $this->getRequest('POST', 'https://app.absence.io/api/v2/absences', $filter);
|
||||||
|
try {
|
||||||
|
$res = $this->client->send($request);
|
||||||
|
} catch (GuzzleException $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_decode($res->getBody()->getContents(), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->cache->commit();
|
||||||
|
|
||||||
|
return $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClient(): Guzzle
|
||||||
|
{
|
||||||
|
return $this->client;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/App.php
Normal file
24
src/App.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Symfony\Component\Dotenv\Dotenv;
|
||||||
|
|
||||||
|
class App
|
||||||
|
{
|
||||||
|
private AbsenceClient $absenceClient;
|
||||||
|
|
||||||
|
public function init(): void
|
||||||
|
{
|
||||||
|
$dotenv = new Dotenv();
|
||||||
|
$dotenv->load(__DIR__ . '/../.env');
|
||||||
|
$dotenv->overload(__DIR__ . '/../.env.local');
|
||||||
|
|
||||||
|
$this->absenceClient = new AbsenceClient($_ENV['ABSENCE_KEY'], $_ENV['ABSENCE_ID']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAbsenceClient(): AbsenceClient
|
||||||
|
{
|
||||||
|
return $this->absenceClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user