Files
Woles-Framework/app/Core/View.php
mwpn 0b42271bfe feat: Complete Woles Framework v1.0 with enterprise-grade UI
- Add comprehensive error handling system with custom error pages
- Implement professional enterprise-style design with Tailwind CSS
- Create modular HMVC architecture with clean separation of concerns
- Add security features: CSRF protection, XSS filtering, Argon2ID hashing
- Include CLI tools for development workflow
- Add error reporting dashboard with system monitoring
- Implement responsive design with consistent slate color scheme
- Replace all emoji icons with professional SVG icons
- Add comprehensive test suite with PHPUnit
- Include database migrations and seeders
- Add proper exception handling with fallback pages
- Implement template engine with custom syntax support
- Add helper functions and facades for clean code
- Include proper logging and debugging capabilities
2025-10-11 07:08:23 +07:00

161 lines
4.6 KiB
PHP

<?php
namespace App\Core;
/**
* NovaCore View Renderer
* Simple PHP template engine
*/
class View
{
private string $viewPath;
private array $sharedData = [];
public function __construct()
{
$this->viewPath = __DIR__ . '/../Modules';
}
/**
* Render a view
*/
public function render(string $view, array $data = []): string
{
$data = array_merge($this->sharedData, $data);
// Get view file path
$viewFile = $this->getViewFile($view);
if (!file_exists($viewFile)) {
throw new \Exception("View '{$view}' not found");
}
// Read view file content
$content = file_get_contents($viewFile);
// Process template syntax first
$content = $this->processTemplate($content);
// Debug: Log processed content
if (getenv('APP_DEBUG') === 'true') {
error_log("Processed template content: " . substr($content, 0, 500));
}
// Extract data to variables
extract($data);
// Start output buffering
ob_start();
// Evaluate processed content
try {
eval('?>' . $content);
} catch (ParseError $e) {
// Log the problematic content for debugging
error_log("Template parse error: " . $e->getMessage());
error_log("Problematic content around line " . $e->getLine() . ": " . substr($content, max(0, $e->getLine() - 10) * 50, 1000));
throw $e;
}
// Get content and clean buffer
return ob_get_clean();
}
/**
* Get view file path
*/
private function getViewFile(string $view): string
{
// Convert dot notation to path
$view = str_replace('.', '/', $view);
// Add .php extension if not present
if (!str_ends_with($view, '.php')) {
$view .= '.php';
}
return $this->viewPath . '/' . $view;
}
/**
* Process template syntax
*/
private function processTemplate(string $content): string
{
// Process {{ }} syntax (auto-escape)
$content = preg_replace_callback('/\{\{\s*(.+?)\s*\}\}/', function ($matches) {
$expression = trim($matches[1]);
return '<?php echo htmlspecialchars(' . $expression . ', ENT_QUOTES, \'UTF-8\'); ?>';
}, $content);
// Process {!! !!} syntax (raw output)
$content = preg_replace_callback('/\{!!\s*(.+?)\s*!!\}/', function ($matches) {
$expression = trim($matches[1]);
return '<?php echo ' . $expression . '; ?>';
}, $content);
// Process @if statements
$content = preg_replace('/@if\s*\(\s*([^)]+)\s*\)/', '<?php if ($1): ?>', $content);
$content = preg_replace('/@elseif\s*\(\s*([^)]+)\s*\)/', '<?php elseif ($1): ?>', $content);
$content = preg_replace('/@else/', '<?php else: ?>', $content);
$content = preg_replace('/@endif/', '<?php endif; ?>', $content);
// Debug: Log processed @if statements
if (getenv('APP_DEBUG') === 'true') {
error_log("After @if processing: " . substr($content, 0, 1000));
}
// Process @foreach loops
$content = preg_replace('/@foreach\s*\((.+?)\)/', '<?php foreach ($1): ?>', $content);
$content = preg_replace('/@endforeach/', '<?php endforeach; ?>', $content);
// Process @for loops
$content = preg_replace('/@for\s*\((.+?)\)/', '<?php for ($1): ?>', $content);
$content = preg_replace('/@endfor/', '<?php endfor; ?>', $content);
// Process @while loops
$content = preg_replace('/@while\s*\((.+?)\)/', '<?php while ($1): ?>', $content);
$content = preg_replace('/@endwhile/', '<?php endwhile; ?>', $content);
// Process @csrf directive
$content = preg_replace('/@csrf/', '<?php echo csrf_token(); ?>', $content);
// Process @method directive
$content = preg_replace('/@method\s*\((.+?)\)/', '<?php echo method_field($1); ?>', $content);
return $content;
}
/**
* Share data with all views
*/
public function share(string $key, $value): void
{
$this->sharedData[$key] = $value;
}
/**
* Check if view exists
*/
public function exists(string $view): bool
{
$viewFile = $this->getViewFile($view);
return file_exists($viewFile);
}
/**
* Get view path
*/
public function getViewPath(): string
{
return $this->viewPath;
}
/**
* Set view path
*/
public function setViewPath(string $path): void
{
$this->viewPath = $path;
}
}