First Commit
This commit is contained in:
+65
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
class GenerateApiKeysCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'generate:api-keys';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Generates API keys and writes them to the .env file');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// Generate random API keys
|
||||
$publicKey = bin2hex(random_bytes(16)); // Generates a random public key
|
||||
$secretKey = bin2hex(random_bytes(32)); // Generates a random secret key
|
||||
|
||||
// Output to terminal
|
||||
$output->writeln("Public Key: $publicKey");
|
||||
$output->writeln("Secret Key: $secretKey");
|
||||
|
||||
// Path to the .env file
|
||||
$envFilePath = __DIR__ . '/../../../.env';
|
||||
|
||||
// Check if the .env file exists
|
||||
if (!file_exists($envFilePath)) {
|
||||
$output->writeln("<error>.env file not found!</error>");
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
// Read the contents of the .env file
|
||||
$envFile = file_get_contents($envFilePath);
|
||||
|
||||
// Check if the keys already exist in the .env file
|
||||
if (strpos($envFile, 'API_PUBLIC_KEY=') === false) {
|
||||
// Add the public key
|
||||
$envFile .= "\nAPI_PUBLIC_KEY=$publicKey";
|
||||
} else {
|
||||
// Replace the existing public key
|
||||
$envFile = preg_replace('/^API_PUBLIC_KEY=.*$/m', "API_PUBLIC_KEY=$publicKey", $envFile);
|
||||
}
|
||||
|
||||
if (strpos($envFile, 'API_SECRET_KEY=') === false) {
|
||||
// Add the secret key
|
||||
$envFile .= "\nAPI_SECRET_KEY=$secretKey";
|
||||
} else {
|
||||
// Replace the existing secret key
|
||||
$envFile = preg_replace('/^API_SECRET_KEY=.*$/m', "API_SECRET_KEY=$secretKey", $envFile);
|
||||
}
|
||||
|
||||
// Write to the .env file
|
||||
file_put_contents($envFilePath, $envFile);
|
||||
|
||||
$output->writeln("API keys have been written to the .env file");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
class GenerateAppKeyCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'generate:app-key';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Generates an application key and writes it to the .env file');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// Generate random key
|
||||
$appKey = bin2hex(random_bytes(32)); // Generates a 64-character key (32 bytes)
|
||||
|
||||
// Output to terminal
|
||||
$output->writeln("Generated Key: $appKey");
|
||||
|
||||
// Load the .env
|
||||
$dotenv = new Dotenv();
|
||||
$envFilePath = __DIR__ . '/../../../.env'; // Adjust the path as needed
|
||||
if (!file_exists($envFilePath)) {
|
||||
$output->writeln(".env file not found!");
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
// Read the content of the .env file
|
||||
$envFile = file_get_contents($envFilePath);
|
||||
|
||||
// Replace the APP_KEY or add it if it doesn't exist
|
||||
if (strpos($envFile, 'APP_KEY=') !== false) {
|
||||
// If a line with APP_KEY already exists, replace it
|
||||
$envFile = preg_replace('/^APP_KEY=.*$/m', "APP_KEY=$appKey", $envFile);
|
||||
} else {
|
||||
// Otherwise, add it at the end
|
||||
$envFile .= "\nAPP_KEY=$appKey\n";
|
||||
}
|
||||
|
||||
// Write the new content to the .env file
|
||||
file_put_contents($envFilePath, $envFile);
|
||||
|
||||
$output->writeln("The application key has been written to the .env file");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
use Faker\Factory as Faker;
|
||||
|
||||
class MigrateCrudExampleCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'migrate:crudexample';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Migrates the database by creating the crudexample table and adding fake records for testing.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// Load the variables from the .env file
|
||||
$dotenv = new Dotenv();
|
||||
$dotenv->load(__DIR__ . '/../../../.env');
|
||||
|
||||
$capsule = new Capsule;
|
||||
|
||||
$capsule->addConnection([
|
||||
'driver' => $_ENV['DB_CONNECTION'],
|
||||
'host' => $_ENV['DB_HOST'],
|
||||
'database' => $_ENV['DB_DATABASE'],
|
||||
'username' => $_ENV['DB_USERNAME'],
|
||||
'password' => $_ENV['DB_PASSWORD'],
|
||||
'charset' => 'utf8',
|
||||
'collation' => 'utf8_unicode_ci',
|
||||
'prefix' => '',
|
||||
]);
|
||||
|
||||
// Set Capsule as the global Eloquent ORM manager
|
||||
$capsule->setAsGlobal();
|
||||
|
||||
// Boot Eloquent ORM
|
||||
$capsule->bootEloquent();
|
||||
|
||||
// Check if the crudexample table already exists
|
||||
if (Capsule::schema()->hasTable('crudexample')) {
|
||||
$output->writeln('The "crudexample" table already exists. No action needed.');
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
// Create the crudexample table
|
||||
$capsule->schema()->create('crudexample', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->string('company', 50);
|
||||
$table->string('name', 50);
|
||||
$table->string('password', 255);
|
||||
$table->string('email', 100)->unique();
|
||||
$table->string('address', 50);
|
||||
$table->string('phone', 50);
|
||||
$table->text('notes')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
// Generate 30 fake records
|
||||
$faker = Faker::create();
|
||||
for ($i = 0; $i < 30; $i++) {
|
||||
Capsule::table('crudexample')->insert([
|
||||
'company' => $faker->company,
|
||||
'name' => $faker->name,
|
||||
'password' => password_hash('password', PASSWORD_BCRYPT), // Default password for testing
|
||||
'email' => $faker->unique()->safeEmail,
|
||||
'address' => $faker->address,
|
||||
'phone' => $faker->phoneNumber,
|
||||
'notes' => $faker->sentence,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
|
||||
$output->writeln('Migration of the "crudexample" table and insertion of fake records for example completed successfully.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace App\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SayHelloCommand extends Command
|
||||
{
|
||||
// Nome do comando no terminal
|
||||
protected static $defaultName = 'app:say-hello';
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setDescription('Exibe uma mensagem de saudação.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$output->writeln('Hello, SysMVC!');
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
Executable
+174
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Monolog\Logger;
|
||||
use App\Models\CrudExample;
|
||||
use App\Services\Sanitizer;
|
||||
use App\Services\BaseController;
|
||||
|
||||
class CrudExampleController extends BaseController
|
||||
{
|
||||
protected $blade;
|
||||
protected $logger;
|
||||
|
||||
public function __construct(BladeOne $blade, Logger $logger)
|
||||
{
|
||||
$this->blade = $blade;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
protected function validateCsrfToken($token)
|
||||
{
|
||||
return hash_equals($_SESSION['csrf_token'], $token);
|
||||
}
|
||||
|
||||
public function index(Request $request): string
|
||||
{
|
||||
try {
|
||||
$crudexample = CrudExample::all();
|
||||
$this->logger->info('Displaying the CrudExampleController page.');
|
||||
|
||||
if ($crudexample->isEmpty()) {
|
||||
$this->logger->warning('No records found in the database.');
|
||||
// Continue with rendering the view instead of returning a message
|
||||
}
|
||||
|
||||
$crudexample = Sanitizer::sanitizeOutput($crudexample->toArray());
|
||||
|
||||
return $this->blade->run('crudexample.index', ['crudexample' => $crudexample]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when querying the database: ' . $e->getMessage());
|
||||
return 'Error when querying the database: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(Request $request, $id): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Editing record with ID: ' . $id);
|
||||
$crudexample = CrudExample::find($id);
|
||||
if (!$crudexample) {
|
||||
return 'Record not found';
|
||||
}
|
||||
|
||||
$csrfToken = generateCsrfToken();
|
||||
$crudexample = Sanitizer::sanitizeOutput($crudexample->toArray());
|
||||
|
||||
return $this->blade->run('crudexample.edit', ['crudexample' => $crudexample, 'csrfToken' => $csrfToken]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when displaying the edit page: ' . $e->getMessage());
|
||||
return 'Error when displaying the edit page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function create(): string
|
||||
{
|
||||
try {
|
||||
return $this->blade->run('crudexample.create', ['error' => null]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when displaying the create page: ' . $e->getMessage());
|
||||
return 'Error when displaying the create page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
try {
|
||||
$data = $_POST;
|
||||
|
||||
if (!isset($data['csrf_token']) || !$this->validateCsrfToken($data['csrf_token'])) {
|
||||
throw new \Exception('Invalid CSRF token.');
|
||||
}
|
||||
|
||||
$data = Sanitizer::sanitizeInput($data);
|
||||
|
||||
if (!isset($data['password']) || empty($data['password'])) {
|
||||
throw new \Exception('The "password" field is required.');
|
||||
}
|
||||
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
|
||||
|
||||
CrudExample::create($data);
|
||||
|
||||
header('Location: /crudexample');
|
||||
exit;
|
||||
} catch (\Exception $e) {
|
||||
if ($e->getCode() == 23000) { // Error code for duplicate
|
||||
$this->logger->error('Error when creating record: Duplicate email.');
|
||||
return $this->blade->run('crudexample.create', ['error' => 'This email already exists.']);
|
||||
} else {
|
||||
$this->logger->error('Error when creating record: ' . $e->getMessage());
|
||||
echo 'Error when creating record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
{
|
||||
try {
|
||||
$data = $_POST;
|
||||
|
||||
if (!isset($data['csrf_token']) || !$this->validateCsrfToken($data['csrf_token'])) {
|
||||
throw new \Exception('Invalid CSRF token.');
|
||||
}
|
||||
|
||||
$data = Sanitizer::sanitizeInput($data);
|
||||
|
||||
if (isset($data['password']) && !empty($data['password'])) {
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
|
||||
} else {
|
||||
unset($data['password']);
|
||||
}
|
||||
|
||||
$crudexample = CrudExample::find($id);
|
||||
if ($crudexample) {
|
||||
$crudexample->update($data);
|
||||
}
|
||||
|
||||
header('Location: /crudexample');
|
||||
exit;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when updating record: ' . $e->getMessage());
|
||||
echo 'Error when updating record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function show(Request $request, $id): string
|
||||
{
|
||||
try {
|
||||
$crudexample = CrudExample::find($id);
|
||||
if (!$crudexample) {
|
||||
return 'Record not found';
|
||||
}
|
||||
|
||||
$crudexample = Sanitizer::sanitizeOutput($crudexample->toArray());
|
||||
|
||||
return $this->blade->run('crudexample.show', ['crudexample' => $crudexample]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when displaying record details: ' . $e->getMessage());
|
||||
return 'Error when displaying record details: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Deleting record with ID: ' . $id);
|
||||
$crudexample = CrudExample::find($id);
|
||||
if ($crudexample) {
|
||||
$crudexample->delete();
|
||||
}
|
||||
|
||||
header('Location: /crudexample');
|
||||
exit;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error when deleting record: ' . $e->getMessage());
|
||||
echo 'Error when deleting record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Monolog\Logger;
|
||||
use App\Services\BaseController;
|
||||
|
||||
class HomeController extends BaseController
|
||||
{
|
||||
protected $blade;
|
||||
protected $logger;
|
||||
|
||||
public function __construct(BladeOne $blade, Logger $logger)
|
||||
{
|
||||
$this->blade = $blade;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function index(Request $request): string
|
||||
{
|
||||
$data = ['title' => 'Welcome to SysMVC'];
|
||||
return $this->blade->run('home', $data);
|
||||
}
|
||||
|
||||
public function about(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the About page.');
|
||||
return $this->blade->run('home.about');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the About page: ' . $e->getMessage());
|
||||
return 'Error displaying the About page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function details(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Learn More page.');
|
||||
return $this->blade->run('home.details');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Details page: ' . $e->getMessage());
|
||||
return 'Error displaying the Learn More page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function readme(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the ReadMe page.');
|
||||
return $this->blade->run('home.readme');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the ReadMe page: ' . $e->getMessage());
|
||||
return 'Error displaying the ReadMe page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function database(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Database Usage page.');
|
||||
return $this->blade->run('home.database');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Database Usage page: ' . $e->getMessage());
|
||||
return 'Error displaying the Database Usage page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function dependencyInjection(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Dependency Injection page.');
|
||||
return $this->blade->run('home.dependency-injection');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Dependency Injection page: ' . $e->getMessage());
|
||||
return 'Error displaying the Dependency Injection page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function appDevelopment(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the App Development page.');
|
||||
return $this->blade->run('home.app-development');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the App Development page: ' . $e->getMessage());
|
||||
return 'Error displaying the App Development page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// New methods
|
||||
public function templatesBlade(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Blade Templates page.');
|
||||
return $this->blade->run('home.templates-blade');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Blade Templates page: ' . $e->getMessage());
|
||||
return 'Error displaying the Blade Templates page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function security(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Security page.');
|
||||
return $this->blade->run('home.security');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Security page: ' . $e->getMessage());
|
||||
return 'Error displaying the Security page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function consoleCli(): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the Console CLI page.');
|
||||
return $this->blade->run('home.console-cli');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the Console CLI page: ' . $e->getMessage());
|
||||
return 'Error displaying the Console CLI page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
use App\Services\BaseController;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
|
||||
class IndexController extends BaseController
|
||||
{
|
||||
protected $blade;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Configure BladeOne
|
||||
$this->blade = new BladeOne(VIEWS_PATH, CACHE_PATH, BladeOne::MODE_DEBUG);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
// Pass data to the view and render
|
||||
return $this->blade->run('home', ['title' => 'Welcome to SysMVC2025!']);
|
||||
}
|
||||
}
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Monolog\Logger;
|
||||
use App\Services\BaseController;
|
||||
|
||||
class TesteController extends BaseController
|
||||
{
|
||||
protected $blade;
|
||||
protected $logger;
|
||||
|
||||
public function __construct(BladeOne $blade, Logger $logger)
|
||||
{
|
||||
$this->blade = $blade;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function index(Request $request): string
|
||||
{
|
||||
$data = ['title' => 'Bem-vindo ao TesteController'];
|
||||
$this->logger->info('Exibindo a página do TesteController.');
|
||||
return $this->blade->run('test', $data);
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+184
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use eftec\bladeone\BladeOne;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Monolog\Logger;
|
||||
use App\Services\Sanitizer;
|
||||
use App\Services\BaseController;
|
||||
use App\Models\TwigExample;
|
||||
use Twig\Environment;
|
||||
|
||||
class TwigExampleController extends BaseController
|
||||
{
|
||||
protected $twig;
|
||||
protected $logger;
|
||||
protected $blade;
|
||||
|
||||
public function __construct(Environment $twig, Logger $logger, BladeOne $blade)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
$this->logger = $logger;
|
||||
$this->blade = $blade;
|
||||
}
|
||||
|
||||
protected function validateCsrfToken($token)
|
||||
{
|
||||
return hash_equals($_SESSION['csrf_token'], $token);
|
||||
}
|
||||
|
||||
public function index(Request $request): string
|
||||
{
|
||||
try {
|
||||
$twigexample = TwigExample::all();
|
||||
$this->logger->info('Displaying the TwigExampleController page.');
|
||||
|
||||
if ($twigexample->isEmpty()) {
|
||||
$this->logger->warning('No records found in the database.');
|
||||
// Continue with rendering the view instead of returning a message
|
||||
}
|
||||
|
||||
$twigexample = Sanitizer::sanitizeOutput($twigexample->toArray());
|
||||
|
||||
return $this->twig->render('twigexample/index.twig.php', ['twigexample' => $twigexample]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error querying the database: ' . $e->getMessage());
|
||||
return 'Error querying the database: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function create(Request $request): string
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Displaying the creation page of the TwigExampleController.');
|
||||
return $this->twig->render('twigexample/create.twig.php', ['csrf_token' => htmlspecialchars(getCsrfToken(), ENT_QUOTES, 'UTF-8')]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the creation page: ' . $e->getMessage());
|
||||
return 'Error displaying the creation page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(Request $request, $id): string
|
||||
{
|
||||
try {
|
||||
$twigexample = TwigExample::find($id);
|
||||
|
||||
if (!$twigexample) {
|
||||
$this->logger->warning("Record with ID $id not found.");
|
||||
return "Record with ID $id not found.";
|
||||
}
|
||||
|
||||
$twigexample = Sanitizer::sanitizeOutput($twigexample->toArray());
|
||||
|
||||
$this->logger->info("Displaying the edit page for the record with ID: $id.");
|
||||
return $this->twig->render('twigexample/edit.twig.php', ['twigexample' => $twigexample, 'csrf_token' => htmlspecialchars(getCsrfToken(), ENT_QUOTES, 'UTF-8')]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the edit page: ' . $e->getMessage());
|
||||
return 'Error displaying the edit page: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function show(Request $request, $id): string
|
||||
{
|
||||
try {
|
||||
$twigexample = TwigExample::find($id);
|
||||
|
||||
if (!$twigexample) {
|
||||
$this->logger->warning("Record with ID $id not found.");
|
||||
return "Record with ID $id not found.";
|
||||
}
|
||||
|
||||
$twigexample = Sanitizer::sanitizeOutput($twigexample->toArray());
|
||||
|
||||
$this->logger->info("Displaying the record with ID: $id.");
|
||||
return $this->twig->render('twigexample/show.twig.php', ['twigexample' => $twigexample]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error displaying the record: ' . $e->getMessage());
|
||||
return 'Error displaying the record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$twigexample = TwigExample::find($id);
|
||||
|
||||
if (!$twigexample) {
|
||||
$this->logger->warning("Record with ID $id not found.");
|
||||
return "Record with ID $id not found.";
|
||||
}
|
||||
|
||||
$twigexample->delete();
|
||||
|
||||
$this->logger->info("Record with ID: $id deleted successfully.");
|
||||
header('Location: /twigexample');
|
||||
exit;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error deleting the record: ' . $e->getMessage());
|
||||
return 'Error deleting the record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
try {
|
||||
$data = $_POST;
|
||||
|
||||
if (!isset($data['csrf_token']) || !$this->validateCsrfToken($data['csrf_token'])) {
|
||||
throw new \Exception('Invalid CSRF token.');
|
||||
}
|
||||
|
||||
$data = Sanitizer::sanitizeInput($data);
|
||||
|
||||
if (!isset($data['password']) || empty($data['password'])) {
|
||||
throw new \Exception('The "password" field is required.');
|
||||
}
|
||||
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
|
||||
|
||||
TwigExample::create($data);
|
||||
|
||||
header('Location: /twigexample');
|
||||
exit;
|
||||
} catch (\Exception $e) {
|
||||
if ($e->getCode() == 23000) { // Error code for duplicate
|
||||
$this->logger->error('Error creating record: Duplicate email.');
|
||||
return $this->blade->run('twigexample.create', ['error' => 'This email already exists.']);
|
||||
} else {
|
||||
$this->logger->error('Error creating record: ' . $e->getMessage());
|
||||
echo 'Error creating record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$data = $_POST;
|
||||
|
||||
if (!isset($data['csrf_token']) || !$this->validateCsrfToken($data['csrf_token'])) {
|
||||
throw new \Exception('Invalid CSRF token.');
|
||||
}
|
||||
|
||||
$data = Sanitizer::sanitizeInput($data);
|
||||
|
||||
$twigexample = TwigExample::find($id);
|
||||
|
||||
if (!$twigexample) {
|
||||
$this->logger->warning("Record with ID $id not found.");
|
||||
return "Record with ID $id not found.";
|
||||
}
|
||||
|
||||
$twigexample->fill($data);
|
||||
$twigexample->save();
|
||||
|
||||
$this->logger->info("Record with ID: $id updated successfully.");
|
||||
header('Location: /twigexample');
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error updating the record: ' . $e->getMessage());
|
||||
return 'Error updating the record: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CrudExample extends Model
|
||||
{
|
||||
protected $table = 'crudexample'; // Table name in the database
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'password',
|
||||
'company',
|
||||
'address',
|
||||
'phone',
|
||||
'email',
|
||||
'notes'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
// Disable timestamps if there are no created_at and updated_at columns
|
||||
public $timestamps = false;
|
||||
}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TwigExample extends Model
|
||||
{
|
||||
protected $table = 'crudexample'; // Table name in the database
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'password',
|
||||
'company',
|
||||
'address',
|
||||
'phone',
|
||||
'email',
|
||||
'notes'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
// Disable timestamps if there are no created_at and updated_at columns
|
||||
public $timestamps = false;
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class BaseController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// Adding security headers
|
||||
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' https://trusted.cdn.com; img-src 'self' data:;");
|
||||
header("X-Frame-Options: DENY");
|
||||
header("X-Content-Type-Options: nosniff");
|
||||
header("Referrer-Policy: no-referrer");
|
||||
header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class Sanitizer
|
||||
{
|
||||
public static function sanitizeInput(array $data): array
|
||||
{
|
||||
$sanitizedData = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$sanitizedData[$key] = static::sanitizeValue($value);
|
||||
}
|
||||
return $sanitizedData;
|
||||
}
|
||||
|
||||
public static function sanitizeOutput($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
return array_map([static::class, 'sanitizeOutput'], $data);
|
||||
}
|
||||
|
||||
return $data !== null ? htmlspecialchars($data, ENT_QUOTES, 'UTF-8') : '';
|
||||
}
|
||||
|
||||
private static function sanitizeValue($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return static::sanitizeInput($value);
|
||||
} elseif (is_null($value)) {
|
||||
return ''; // Ensures null does not pass through
|
||||
} elseif (filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
return filter_var($value, FILTER_SANITIZE_EMAIL);
|
||||
} elseif (filter_var($value, FILTER_VALIDATE_URL)) {
|
||||
return filter_var($value, FILTER_SANITIZE_URL);
|
||||
} else {
|
||||
return filter_var($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user