Quelltext des aktuellen Standes
<?php
declare(strict_types=1);
/**
* Vorlagen, die eine Klasse selbst einbindet, laufen in deren Geltungsbereich:
* `$this` ist dort der Controller bzw. die Anwendung, nicht die View. Jeder
* `$this->…`-Aufruf einer solchen Vorlage muss es an der einbindenden Klasse
* also wirklich geben – sonst steht an der Stelle kein Text, sondern ein
* Abbruch, und zwar erst beim Aufruf der Seite.
*/
return static function (): void {
$wurzel = dirname(__DIR__);
/**
* Alle Vorlagen, die irgendwo unter src/ per include/require eingebunden
* werden, mit der Klasse, in deren Geltungsbereich das geschieht.
*
* @return array<int,array{vorlage:string,klasse:string,quelle:string}>
*/
$einbindungen = static function () use ($wurzel): array {
$treffer = [];
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($wurzel . '/src'));
foreach ($it as $datei) {
if (!$datei->isFile() || $datei->getExtension() !== 'php') {
continue;
}
$quelle = (string)file_get_contents($datei->getPathname());
// include dirname(__DIR__, N) . '/templates/…php'
if (!preg_match_all(
'#(?:include|require)(?:_once)?\s+dirname\(__DIR__,\s*(\d+)\)\s*\.\s*\'(/templates/[^\']+\.php)\'#',
$quelle,
$m,
PREG_SET_ORDER
)) {
continue;
}
preg_match('/^namespace\s+([^;]+);/m', $quelle, $ns);
preg_match('/^(?:final\s+)?(?:abstract\s+)?class\s+(\w+)/m', $quelle, $kl);
if (!isset($ns[1], $kl[1])) {
continue;
}
foreach ($m as $einzel) {
$vorlage = $wurzel . $einzel[2];
if (!is_file($vorlage)) {
continue;
}
$treffer[] = [
'vorlage' => $einzel[2],
'klasse' => trim($ns[1]) . '\\' . $kl[1],
'quelle' => str_replace($wurzel . '/', '', $datei->getPathname()),
];
}
}
return $treffer;
};
$stellen = $einbindungen();
test('Es gibt Vorlagen, die ohne View eingebunden werden', function () use ($stellen) {
assertTrue(count($stellen) >= 3, 'Die Suche findet die bekannten Einbindungen nicht mehr');
});
test('Jeder Aufruf einer solchen Vorlage existiert an der einbindenden Klasse', function () use ($stellen, $wurzel) {
foreach ($stellen as $stelle) {
$inhalt = (string)file_get_contents($wurzel . $stelle['vorlage']);
preg_match_all('/\$this->([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/', $inhalt, $m);
foreach (array_unique($m[1]) as $methode) {
assertTrue(
method_exists($stelle['klasse'], $methode),
$stelle['vorlage'] . ' ruft $this->' . $methode . '() auf, '
. $stelle['klasse'] . ' (' . $stelle['quelle'] . ') kennt das nicht'
);
}
}
});
test('Übersetzen und Maskieren heißt überall gleich', function () {
// Dieselbe Schreibweise in Vorlagen, gleich ob View, Controller oder
// Anwendung sie einbindet.
foreach ([\OpenNIT\Core\View::class, \OpenNIT\Controllers\BaseController::class, \OpenNIT\Core\Application::class] as $klasse) {
assertTrue(method_exists($klasse, 'te'), $klasse . ' kennt te() nicht');
}
});
};