StopwordRepository.php
- Pfad:
src/Infrastructure/Persistence/StopwordRepository.php - Namespace: Infrastructure\Persistence
- Zeilen: 240 | Größe: 6,210 Bytes
- Geändert: 2025-12-27 00:19:04 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 98
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 90 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 4
- implements Domain\Repository\StopwordRepositoryInterface
- constructor PDO
- use Domain\Repository\StopwordRepositoryInterface
- use PDO
Klassen 1
-
StopwordRepositoryclass Zeile 12
Funktionen 11
-
__construct()public Zeile 19 -
findAll()public Zeile 27 -
find()public Zeile 52 -
getCanonicalForms()public Zeile 64 -
isStopword()public Zeile 88 -
create()public Zeile 99 -
update()public Zeile 124 -
delete()public Zeile 167 -
toggleActive()public Zeile 180 -
getStats()public Zeile 197 -
normalize()private Zeile 224
Verwendet von 1
Versionen 1
-
v1
2025-12-27 00:19 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
Code
<?php
declare(strict_types=1);
namespace Infrastructure\Persistence;
// @responsibility: CRUD-Operationen für Stopwords (Entity-Extraction Filter)
use Domain\Repository\StopwordRepositoryInterface;
use PDO;
final class StopwordRepository implements StopwordRepositoryInterface
{
private PDO $db;
/** @var array<string>|null Cached canonical forms */
private ?array $canonicalCache = null;
public function __construct(PDO $pdo)
{
$this->db = $pdo;
}
/**
* {@inheritDoc}
*/
public function findAll(bool $activeOnly = true, ?string $category = null): array
{
$sql = 'SELECT * FROM stopwords WHERE 1=1';
$params = [];
if ($activeOnly) {
$sql .= ' AND is_active = 1';
}
if ($category !== null) {
$sql .= ' AND category = :category';
$params['category'] = $category;
}
$sql .= ' ORDER BY word ASC';
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
/**
* {@inheritDoc}
*/
public function find(int $id): ?array
{
$stmt = $this->db->prepare('SELECT * FROM stopwords WHERE id = :id');
$stmt->execute(['id' => $id]);
$result = $stmt->fetch();
return $result === false ? null : $result;
}
/**
* {@inheritDoc}
*/
public function getCanonicalForms(bool $activeOnly = true): array
{
if ($this->canonicalCache !== null && $activeOnly) {
return $this->canonicalCache;
}
$sql = 'SELECT canonical_form FROM stopwords';
if ($activeOnly) {
$sql .= ' WHERE is_active = 1';
}
$stmt = $this->db->query($sql);
$forms = $stmt->fetchAll(PDO::FETCH_COLUMN);
if ($activeOnly) {
$this->canonicalCache = $forms;
}
return $forms;
}
/**
* {@inheritDoc}
*/
public function isStopword(string $word): bool
{
$canonical = $this->normalize($word);
$forms = $this->getCanonicalForms();
return in_array($canonical, $forms, true);
}
/**
* {@inheritDoc}
*/
public function create(array $data): int
{
$canonical = $this->normalize($data['word'] ?? '');
$stmt = $this->db->prepare(
'INSERT INTO stopwords (word, canonical_form, category, reason, is_active)
VALUES (:word, :canonical, :category, :reason, :active)'
);
$stmt->execute([
'word' => $data['word'],
'canonical' => $canonical,
'category' => $data['category'] ?? 'generic',
'reason' => $data['reason'] ?? null,
'active' => $data['is_active'] ?? 1,
]);
$this->canonicalCache = null;
return (int) $this->db->lastInsertId();
}
/**
* {@inheritDoc}
*/
public function update(int $id, array $data): bool
{
$sets = [];
$params = ['id' => $id];
if (isset($data['word'])) {
$sets[] = 'word = :word';
$sets[] = 'canonical_form = :canonical';
$params['word'] = $data['word'];
$params['canonical'] = $this->normalize($data['word']);
}
if (isset($data['category'])) {
$sets[] = 'category = :category';
$params['category'] = $data['category'];
}
if (array_key_exists('reason', $data)) {
$sets[] = 'reason = :reason';
$params['reason'] = $data['reason'];
}
if (isset($data['is_active'])) {
$sets[] = 'is_active = :active';
$params['active'] = $data['is_active'];
}
if ($sets === []) {
return false;
}
$sql = 'UPDATE stopwords SET ' . implode(', ', $sets) . ' WHERE id = :id';
$stmt = $this->db->prepare($sql);
$result = $stmt->execute($params);
$this->canonicalCache = null;
return $result && $stmt->rowCount() > 0;
}
/**
* {@inheritDoc}
*/
public function delete(int $id): bool
{
$stmt = $this->db->prepare('DELETE FROM stopwords WHERE id = :id');
$result = $stmt->execute(['id' => $id]);
$this->canonicalCache = null;
return $result && $stmt->rowCount() > 0;
}
/**
* {@inheritDoc}
*/
public function toggleActive(int $id): bool
{
$stmt = $this->db->prepare(
'UPDATE stopwords SET is_active = NOT is_active WHERE id = :id'
);
$result = $stmt->execute(['id' => $id]);
$this->canonicalCache = null;
return $result && $stmt->rowCount() > 0;
}
/**
* {@inheritDoc}
*
* @return array{total: int, active: int, by_category: array<string, array{count: int, active: int}>}
*/
public function getStats(): array
{
$stmt = $this->db->query(
'SELECT category, COUNT(*) as count, SUM(is_active) as active
FROM stopwords GROUP BY category'
);
/** @var array<string, array{count: int, active: int}> $byCategory */
$byCategory = [];
$total = 0;
$active = 0;
foreach ($stmt->fetchAll() as $row) {
$byCategory[$row['category']] = [
'count' => (int) $row['count'],
'active' => (int) $row['active'],
];
$total += (int) $row['count'];
$active += (int) $row['active'];
}
return ['total' => $total, 'active' => $active, 'by_category' => $byCategory];
}
/**
* Normalize word to canonical form.
*/
private function normalize(string $word): string
{
$result = mb_strtolower(trim($word));
// German umlauts
$replacements = [
'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss',
];
$result = str_replace(array_keys($replacements), array_values($replacements), $result);
// Remove special chars, keep only alphanumeric and underscore
$result = preg_replace('/[^a-z0-9_]/', '', $result);
return $result ?? '';
}
}