relaunch
This commit is contained in:
parent
abaa95f71d
commit
6309faa898
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
Binary file not shown.
After Width: | Height: | Size: 416 KiB |
|
@ -5,5 +5,25 @@ require('bootstrap');
|
||||||
|
|
||||||
import '../styles/app.scss';
|
import '../styles/app.scss';
|
||||||
|
|
||||||
|
// CKEditor
|
||||||
|
//require '@'
|
||||||
|
import '../styles/ckeditor.css';
|
||||||
|
|
||||||
|
|
||||||
require('@fortawesome/fontawesome-free/css/all.min.css');
|
require('@fortawesome/fontawesome-free/css/all.min.css');
|
||||||
require('@fortawesome/fontawesome-free/js/all.js');
|
require('@fortawesome/fontawesome-free/js/all.js');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
window.Dropzone = require('@symfony/ux-dropzone/dist/controller');
|
||||||
|
Dropzone.autodiscover = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
initializeDropzone();
|
||||||
|
|
||||||
|
function initializeDropzone()
|
||||||
|
{
|
||||||
|
let formElement = document.querySelector('js-dropzone');
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,106 @@
|
||||||
|
:root {
|
||||||
|
/* Overrides the border radius setting in the theme. */
|
||||||
|
--ck-border-radius: 4px;
|
||||||
|
|
||||||
|
/* Overrides the default font size in the theme. */
|
||||||
|
--ck-font-size-base: 14px;
|
||||||
|
|
||||||
|
/* Helper variables to avoid duplication in the colors. */
|
||||||
|
--ck-custom-background: hsl(270, 1%, 29%);
|
||||||
|
--ck-custom-foreground: hsl(255, 3%, 18%);
|
||||||
|
--ck-custom-border: hsl(300, 1%, 22%);
|
||||||
|
--ck-custom-white: hsl(0, 0%, 100%);
|
||||||
|
|
||||||
|
/* -- Overrides generic colors. ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-base-foreground: var(--ck-custom-background);
|
||||||
|
--ck-color-focus-border: hsl(208, 90%, 62%);
|
||||||
|
--ck-color-text: hsl(0, 0%, 98%);
|
||||||
|
--ck-color-shadow-drop: hsla(0, 0%, 0%, 0.2);
|
||||||
|
--ck-color-shadow-inner: hsla(0, 0%, 0%, 0.1);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-button class colors. ---------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-button-default-background: var(--ck-custom-background);
|
||||||
|
--ck-color-button-default-hover-background: hsl(270, 1%, 22%);
|
||||||
|
--ck-color-button-default-active-background: hsl(270, 2%, 20%);
|
||||||
|
--ck-color-button-default-active-shadow: hsl(270, 2%, 23%);
|
||||||
|
--ck-color-button-default-disabled-background: var(--ck-custom-background);
|
||||||
|
|
||||||
|
--ck-color-button-on-background: var(--ck-custom-foreground);
|
||||||
|
--ck-color-button-on-hover-background: hsl(255, 4%, 16%);
|
||||||
|
--ck-color-button-on-active-background: hsl(255, 4%, 14%);
|
||||||
|
--ck-color-button-on-active-shadow: hsl(240, 3%, 19%);
|
||||||
|
--ck-color-button-on-disabled-background: var(--ck-custom-foreground);
|
||||||
|
|
||||||
|
--ck-color-button-action-background: hsl(168, 76%, 42%);
|
||||||
|
--ck-color-button-action-hover-background: hsl(168, 76%, 38%);
|
||||||
|
--ck-color-button-action-active-background: hsl(168, 76%, 36%);
|
||||||
|
--ck-color-button-action-active-shadow: hsl(168, 75%, 34%);
|
||||||
|
--ck-color-button-action-disabled-background: hsl(168, 76%, 42%);
|
||||||
|
--ck-color-button-action-text: var(--ck-custom-white);
|
||||||
|
|
||||||
|
--ck-color-button-save: hsl(120, 100%, 46%);
|
||||||
|
--ck-color-button-cancel: hsl(15, 100%, 56%);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-dropdown class colors. -------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-dropdown-panel-background: var(--ck-custom-background);
|
||||||
|
--ck-color-dropdown-panel-border: var(--ck-custom-foreground);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-splitbutton class colors. ----------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-split-button-hover-background: var(--ck-color-button-default-hover-background);
|
||||||
|
--ck-color-split-button-hover-border: var(--ck-custom-foreground);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-input class colors. ----------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-input-background: var(--ck-custom-background);
|
||||||
|
--ck-color-input-border: hsl(257, 3%, 43%);
|
||||||
|
--ck-color-input-text: hsl(0, 0%, 98%);
|
||||||
|
--ck-color-input-disabled-background: hsl(255, 4%, 21%);
|
||||||
|
--ck-color-input-disabled-border: hsl(250, 3%, 38%);
|
||||||
|
--ck-color-input-disabled-text: hsl(0, 0%, 78%);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-labeled-field-view class colors. ---------------------------- */
|
||||||
|
|
||||||
|
--ck-color-labeled-field-label-background: var(--ck-custom-background);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-list class colors. ------------------------------------------ */
|
||||||
|
|
||||||
|
--ck-color-list-background: var(--ck-custom-background);
|
||||||
|
--ck-color-list-button-hover-background: var(--ck-color-base-foreground);
|
||||||
|
--ck-color-list-button-on-background: var(--ck-color-base-active);
|
||||||
|
--ck-color-list-button-on-background-focus: var(--ck-color-base-active-focus);
|
||||||
|
--ck-color-list-button-on-text: var(--ck-color-base-background);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-balloon-panel class colors. --------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-panel-background: var(--ck-custom-background);
|
||||||
|
--ck-color-panel-border: var(--ck-custom-border);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-toolbar class colors. --------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-toolbar-background: var(--ck-custom-background);
|
||||||
|
--ck-color-toolbar-border: var(--ck-custom-border);
|
||||||
|
|
||||||
|
/* -- Overrides the default .ck-tooltip class colors. --------------------------------------- */
|
||||||
|
|
||||||
|
--ck-color-tooltip-background: hsl(252, 7%, 14%);
|
||||||
|
--ck-color-tooltip-text: hsl(0, 0%, 93%);
|
||||||
|
|
||||||
|
/* -- Overrides the default colors used by the ckeditor5-image package. --------------------- */
|
||||||
|
|
||||||
|
--ck-color-image-caption-background: hsl(0, 0%, 97%);
|
||||||
|
--ck-color-image-caption-text: hsl(0, 0%, 20%);
|
||||||
|
|
||||||
|
/* -- Overrides the default colors used by the ckeditor5-widget package. -------------------- */
|
||||||
|
|
||||||
|
--ck-color-widget-blurred-border: hsl(0, 0%, 87%);
|
||||||
|
--ck-color-widget-hover-border: hsl(43, 100%, 68%);
|
||||||
|
--ck-color-widget-editable-focus-background: var(--ck-custom-white);
|
||||||
|
|
||||||
|
/* -- Overrides the default colors used by the ckeditor5-link package. ---------------------- */
|
||||||
|
|
||||||
|
--ck-color-link-default: hsl(190, 100%, 75%);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { startStimulusApp } from '@symfony/stimulus-bridge';
|
||||||
|
|
||||||
|
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||||
|
export const app = startStimulusApp(require.context(
|
||||||
|
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||||
|
true,
|
||||||
|
/\.(j|t)sx?$/
|
||||||
|
));
|
||||||
|
|
||||||
|
// register any custom, 3rd party controllers here
|
||||||
|
// app.register('some_controller_name', SomeImportedController);
|
|
@ -0,0 +1,5 @@
|
||||||
|
when@dev:
|
||||||
|
debug:
|
||||||
|
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
|
||||||
|
# See the "server:dump" command to start a new server.
|
||||||
|
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
|
|
@ -0,0 +1,24 @@
|
||||||
|
framework:
|
||||||
|
messenger:
|
||||||
|
failure_transport: failed
|
||||||
|
|
||||||
|
transports:
|
||||||
|
# https://symfony.com/doc/current/messenger.html#transport-configuration
|
||||||
|
async:
|
||||||
|
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
|
||||||
|
options:
|
||||||
|
use_notify: true
|
||||||
|
check_delayed_interval: 60000
|
||||||
|
retry_strategy:
|
||||||
|
max_retries: 3
|
||||||
|
multiplier: 2
|
||||||
|
failed: 'doctrine://default?queue_name=failed'
|
||||||
|
# sync: 'sync://'
|
||||||
|
|
||||||
|
routing:
|
||||||
|
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
|
||||||
|
Symfony\Component\Notifier\Message\ChatMessage: async
|
||||||
|
Symfony\Component\Notifier\Message\SmsMessage: async
|
||||||
|
|
||||||
|
# Route your messages to the transports
|
||||||
|
# 'App\Message\YourMessage': async
|
|
@ -0,0 +1,61 @@
|
||||||
|
monolog:
|
||||||
|
channels:
|
||||||
|
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||||
|
|
||||||
|
when@dev:
|
||||||
|
monolog:
|
||||||
|
handlers:
|
||||||
|
main:
|
||||||
|
type: stream
|
||||||
|
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||||
|
level: debug
|
||||||
|
channels: ["!event"]
|
||||||
|
# uncomment to get logging in your browser
|
||||||
|
# you may have to allow bigger header sizes in your Web server configuration
|
||||||
|
#firephp:
|
||||||
|
# type: firephp
|
||||||
|
# level: info
|
||||||
|
#chromephp:
|
||||||
|
# type: chromephp
|
||||||
|
# level: info
|
||||||
|
console:
|
||||||
|
type: console
|
||||||
|
process_psr_3_messages: false
|
||||||
|
channels: ["!event", "!doctrine", "!console"]
|
||||||
|
|
||||||
|
when@test:
|
||||||
|
monolog:
|
||||||
|
handlers:
|
||||||
|
main:
|
||||||
|
type: fingers_crossed
|
||||||
|
action_level: error
|
||||||
|
handler: nested
|
||||||
|
excluded_http_codes: [404, 405]
|
||||||
|
channels: ["!event"]
|
||||||
|
nested:
|
||||||
|
type: stream
|
||||||
|
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||||
|
level: debug
|
||||||
|
|
||||||
|
when@prod:
|
||||||
|
monolog:
|
||||||
|
handlers:
|
||||||
|
main:
|
||||||
|
type: fingers_crossed
|
||||||
|
action_level: error
|
||||||
|
handler: nested
|
||||||
|
excluded_http_codes: [404, 405]
|
||||||
|
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||||
|
nested:
|
||||||
|
type: stream
|
||||||
|
path: php://stderr
|
||||||
|
level: debug
|
||||||
|
formatter: monolog.formatter.json
|
||||||
|
console:
|
||||||
|
type: console
|
||||||
|
process_psr_3_messages: false
|
||||||
|
channels: ["!event", "!doctrine"]
|
||||||
|
deprecation:
|
||||||
|
type: stream
|
||||||
|
channels: [deprecation]
|
||||||
|
path: php://stderr
|
|
@ -0,0 +1,16 @@
|
||||||
|
framework:
|
||||||
|
notifier:
|
||||||
|
#chatter_transports:
|
||||||
|
# slack: '%env(SLACK_DSN)%'
|
||||||
|
# telegram: '%env(TELEGRAM_DSN)%'
|
||||||
|
#texter_transports:
|
||||||
|
# twilio: '%env(TWILIO_DSN)%'
|
||||||
|
# nexmo: '%env(NEXMO_DSN)%'
|
||||||
|
channel_policy:
|
||||||
|
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo
|
||||||
|
urgent: ['email']
|
||||||
|
high: ['email']
|
||||||
|
medium: ['email']
|
||||||
|
low: ['email']
|
||||||
|
admin_recipients:
|
||||||
|
- { email: admin@example.com }
|
|
@ -0,0 +1,3 @@
|
||||||
|
sensio_framework_extra:
|
||||||
|
router:
|
||||||
|
annotations: false
|
|
@ -0,0 +1,15 @@
|
||||||
|
when@dev:
|
||||||
|
web_profiler:
|
||||||
|
toolbar: true
|
||||||
|
intercept_redirects: false
|
||||||
|
|
||||||
|
framework:
|
||||||
|
profiler: { only_exceptions: false }
|
||||||
|
|
||||||
|
when@test:
|
||||||
|
web_profiler:
|
||||||
|
toolbar: false
|
||||||
|
intercept_redirects: false
|
||||||
|
|
||||||
|
framework:
|
||||||
|
profiler: { collect: false }
|
|
@ -0,0 +1,4 @@
|
||||||
|
when@dev:
|
||||||
|
_errors:
|
||||||
|
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||||
|
prefix: /_error
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"controllers": {
|
||||||
|
"@symfony/ux-dropzone": {
|
||||||
|
"dropzone": {
|
||||||
|
"enabled": true,
|
||||||
|
"fetch": "eager",
|
||||||
|
"autoimport": {
|
||||||
|
"@symfony/ux-dropzone/src/style.css": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entrypoints": []
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
###> doctrine/doctrine-bundle ###
|
||||||
|
database:
|
||||||
|
ports:
|
||||||
|
- "5432"
|
||||||
|
###< doctrine/doctrine-bundle ###
|
||||||
|
|
||||||
|
###> symfony/mailer ###
|
||||||
|
mailer:
|
||||||
|
image: schickling/mailcatcher
|
||||||
|
ports: [1025, 1080]
|
||||||
|
###< symfony/mailer ###
|
|
@ -0,0 +1,21 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
###> doctrine/doctrine-bundle ###
|
||||||
|
database:
|
||||||
|
image: postgres:${POSTGRES_VERSION:-13}-alpine
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-app}
|
||||||
|
# You should definitely change the password in production
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-symfony}
|
||||||
|
volumes:
|
||||||
|
- db-data:/var/lib/postgresql/data:rw
|
||||||
|
# You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
|
||||||
|
# - ./docker/db/data:/var/lib/postgresql/data:rw
|
||||||
|
###< doctrine/doctrine-bundle ###
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
###> doctrine/doctrine-bundle ###
|
||||||
|
db-data:
|
||||||
|
###< doctrine/doctrine-bundle ###
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20220409135404 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE user ADD first_name VARCHAR(255) DEFAULT NULL, ADD last_name VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE `user` DROP first_name, DROP last_name');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20220409150258 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE quotes (id INT AUTO_INCREMENT NOT NULL, quote LONGTEXT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE quotes');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20220410123550 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE projects (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, url VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||||
|
$this->addSql('ALTER TABLE user CHANGE first_name first_name VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE projects');
|
||||||
|
$this->addSql('ALTER TABLE `user` CHANGE first_name first_name VARCHAR(255) DEFAULT \'\'');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20220410131552 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE projects_user (projects_id INT NOT NULL, user_id INT NOT NULL, INDEX IDX_B38D6A811EDE0F55 (projects_id), INDEX IDX_B38D6A81A76ED395 (user_id), PRIMARY KEY(projects_id, user_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||||
|
$this->addSql('ALTER TABLE projects_user ADD CONSTRAINT FK_B38D6A811EDE0F55 FOREIGN KEY (projects_id) REFERENCES projects (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE projects_user ADD CONSTRAINT FK_B38D6A81A76ED395 FOREIGN KEY (user_id) REFERENCES `user` (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE projects ADD teaser_image VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE projects_user');
|
||||||
|
$this->addSql('ALTER TABLE projects DROP teaser_image');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Admin;
|
||||||
|
|
||||||
|
use App\Entity\Projects;
|
||||||
|
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProjectsCrudController extends AbstractCrudController
|
||||||
|
{
|
||||||
|
public static function getEntityFqcn(): string
|
||||||
|
{
|
||||||
|
return Projects::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public function configureFields(string $pageName): iterable
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
IdField::new('id'),
|
||||||
|
TextField::new('title'),
|
||||||
|
TextEditorField::new('description'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Admin;
|
||||||
|
|
||||||
|
use App\Entity\Quotes;
|
||||||
|
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||||
|
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||||
|
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||||
|
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class QuotesCrudController extends AbstractCrudController
|
||||||
|
{
|
||||||
|
public static function getEntityFqcn(): string
|
||||||
|
{
|
||||||
|
return Quotes::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureFields(string $pageName): iterable
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
IdField::new(propertyName: 'id'),
|
||||||
|
TextField::new(propertyName: 'quote'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Repository\ProjectsRepository;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProjectsController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route(path: '/projects/{name}', name: 'app_projects')]
|
||||||
|
public function index(ProjectsRepository $projectsRepository, string $name = ''): Response
|
||||||
|
{
|
||||||
|
if ($name == '') {
|
||||||
|
return $this->render(view: 'projects/index.html.twig', parameters: [
|
||||||
|
'projects' => $projectsRepository->findAll()
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
if ($project = $projectsRepository->findOneByName(value: $name)) {
|
||||||
|
$readMe = file_get_contents(filename: $project->getURL() . '/raw/branch/master/README.md');
|
||||||
|
|
||||||
|
//$parsedReadMe = $markdownParser->transformMarkdown(text: $readMe);
|
||||||
|
|
||||||
|
return $this->render(view: 'projects/show.html.twig', parameters: [
|
||||||
|
'project' => $project,
|
||||||
|
'readme' => $readMe
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
throw $this->createNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,17 +2,74 @@
|
||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Repository\UserRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserController
|
||||||
|
* @package App\Controller
|
||||||
|
*/
|
||||||
class UserController extends AbstractController
|
class UserController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route('/user', name: 'user')]
|
/**
|
||||||
public function index(): Response
|
* @param \App\Repository\UserRepository $userRepository
|
||||||
|
* @param string $userName
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
#[Route(path: '/profile/edit/{username}', name: 'app_profile_edit')]
|
||||||
|
public function editProfile(UserRepository $userRepository, string $username = ''): Response
|
||||||
{
|
{
|
||||||
return $this->render('user/index.html.twig', [
|
/** var User $user */
|
||||||
'controller_name' => 'UserController',
|
if ($username === '') {
|
||||||
|
if ($this->isGranted(attribute: 'ROLE_USER')) {
|
||||||
|
$user = $this->getUser();
|
||||||
|
} else {
|
||||||
|
throw new AccessDeniedException('You need to be logged in.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($this->isGranted(attribute: 'ROLE_ADMIN')) {
|
||||||
|
$user = $userRepository->findOneBy([
|
||||||
|
"username" => $username
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($user)) {
|
||||||
|
return $this->render(view: 'user/edit_profile.html.twig', parameters: [
|
||||||
|
'user' => $user,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Repository\UserRepository $userRepository
|
||||||
|
* @param string $username
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
#[Route(path: '/profile/{username}', name: 'app_profile')]
|
||||||
|
public function showProfile(UserRepository $userRepository, string $username = ''): Response
|
||||||
|
{
|
||||||
|
/** var User $user */
|
||||||
|
if ($username === '') {
|
||||||
|
$user = $this->getUser();
|
||||||
|
} else {
|
||||||
|
$user = $userRepository->findOneBy([
|
||||||
|
"username" => $username
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(view: 'user/show_profile.html.twig', parameters: [
|
||||||
|
'user' => $user,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\ProjectsRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#[ORM\Entity(repositoryClass: ProjectsRepository::class)]
|
||||||
|
class Projects
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private ?int $id;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'string', length: 255)]
|
||||||
|
private ?string $name;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'string', length: 255)]
|
||||||
|
private ?string $description;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'string', length: 255)]
|
||||||
|
private ?string $url;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'datetime_immutable')]
|
||||||
|
private ?\DateTimeImmutable $createdAt;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'string', length: 255, nullable: true)]
|
||||||
|
private ?string $teaserImage;
|
||||||
|
|
||||||
|
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'projects')]
|
||||||
|
private $developer;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->developer = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $Name): self
|
||||||
|
{
|
||||||
|
$this->name = $Name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): ?string
|
||||||
|
{
|
||||||
|
return $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDescription(string $Description): self
|
||||||
|
{
|
||||||
|
$this->description = $Description;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getURL(): ?string
|
||||||
|
{
|
||||||
|
return $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setURL(string $url): self
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedAt(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedAt(\DateTimeImmutable $createdAt): self
|
||||||
|
{
|
||||||
|
$this->createdAt = $createdAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeaserImage(): ?string
|
||||||
|
{
|
||||||
|
return $this->teaserImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTeaserImage(?string $teaserImage): self
|
||||||
|
{
|
||||||
|
$this->teaserImage = $teaserImage;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, User>
|
||||||
|
*/
|
||||||
|
public function getDeveloper(): Collection
|
||||||
|
{
|
||||||
|
return $this->developer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addDeveloper(User $developer): self
|
||||||
|
{
|
||||||
|
if (!$this->developer->contains($developer)) {
|
||||||
|
$this->developer[] = $developer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeDeveloper(User $developer): self
|
||||||
|
{
|
||||||
|
$this->developer->removeElement($developer);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\QuotesRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: QuotesRepository::class)]
|
||||||
|
class Quotes
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'text')]
|
||||||
|
private $quote;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuote(): ?string
|
||||||
|
{
|
||||||
|
return $this->quote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setQuote(string $quote): self
|
||||||
|
{
|
||||||
|
$this->quote = $quote;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\Projects;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\ORM\NonUniqueResultException;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method Projects|null find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
* @method Projects|null findOneBy(array $criteria, array $orderBy = null)
|
||||||
|
* @method Projects[] findAll()
|
||||||
|
* @method Projects[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
*/
|
||||||
|
class ProjectsRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct(registry: $registry, entityClass: Projects::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public function add(Projects $entity, bool $flush = true): void
|
||||||
|
{
|
||||||
|
$this->_em->persist($entity);
|
||||||
|
if ($flush) {
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public function remove(Projects $entity, bool $flush = true): void
|
||||||
|
{
|
||||||
|
$this->_em->remove($entity);
|
||||||
|
if ($flush) {
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return Projects[] Returns an array of Projects objects
|
||||||
|
// */
|
||||||
|
/*
|
||||||
|
public function findByExampleField($value)
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('p')
|
||||||
|
->andWhere('p.exampleField = :val')
|
||||||
|
->setParameter('val', $value)
|
||||||
|
->orderBy('p.id', 'ASC')
|
||||||
|
->setMaxResults(10)
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function findOneByName($value): ?Projects
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->createQueryBuilder(alias: 'q')
|
||||||
|
->andWhere('q.name = :val')
|
||||||
|
->setParameter(key: 'val', value: $value)
|
||||||
|
->getQuery()
|
||||||
|
->getOneOrNullResult();
|
||||||
|
} catch(NonUniqueResultException $e) {
|
||||||
|
dd($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\Quotes;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\ORM\OptimisticLockException;
|
||||||
|
use Doctrine\ORM\ORMException;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method Quotes|null find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
* @method Quotes|null findOneBy(array $criteria, array $orderBy = null)
|
||||||
|
* @method Quotes[] findAll()
|
||||||
|
* @method Quotes[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
*/
|
||||||
|
class QuotesRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct(registry: $registry, entityClass: Quotes::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public function add(Quotes $entity, bool $flush = true): void
|
||||||
|
{
|
||||||
|
$this->_em->persist($entity);
|
||||||
|
if ($flush) {
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public function remove(Quotes $entity, bool $flush = true): void
|
||||||
|
{
|
||||||
|
$this->_em->remove($entity);
|
||||||
|
if ($flush) {
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null|float|int|mixed|string
|
||||||
|
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||||
|
*/
|
||||||
|
public function findOneRandom(): mixed
|
||||||
|
{
|
||||||
|
$idLimits = $this->createQueryBuilder(alias: 'q')
|
||||||
|
->select('MIN(q.id)', 'MAX(q.id)')
|
||||||
|
->getQuery()
|
||||||
|
->getOneOrNullResult();
|
||||||
|
$randomPossibleId = rand(min: $idLimits[1], max: $idLimits[2]);
|
||||||
|
|
||||||
|
return $this->createQueryBuilder(alias: 'q')
|
||||||
|
->where(predicates: 'q.id >= :random_id')
|
||||||
|
->setParameter(key: 'random_id', value: $randomPossibleId)
|
||||||
|
->setMaxResults(maxResults: 1)
|
||||||
|
->getQuery()
|
||||||
|
->getOneOrNullResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return Quotes[] Returns an array of Quotes objects
|
||||||
|
// */
|
||||||
|
/*
|
||||||
|
public function findByExampleField($value)
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('q')
|
||||||
|
->andWhere('q.exampleField = :val')
|
||||||
|
->setParameter('val', $value)
|
||||||
|
->orderBy('q.id', 'ASC')
|
||||||
|
->setMaxResults(10)
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
public function findOneBySomeField($value): ?Quotes
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('q')
|
||||||
|
->andWhere('q.exampleField = :val')
|
||||||
|
->setParameter('val', $value)
|
||||||
|
->getQuery()
|
||||||
|
->getOneOrNullResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Security;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\RouterInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||||
|
use App\Repository\UserRepository;
|
||||||
|
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||||
|
use function mysql_xdevapi\getSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
|
||||||
|
{
|
||||||
|
use TargetPathTrait;
|
||||||
|
/**
|
||||||
|
* @var \App\Repository\UserRepository
|
||||||
|
*/
|
||||||
|
private UserRepository $userRepository;
|
||||||
|
/**
|
||||||
|
* @var \Symfony\Component\Routing\RouterInterface
|
||||||
|
*/
|
||||||
|
private RouterInterface $router;
|
||||||
|
|
||||||
|
public function __construct(UserRepository $userRepository, RouterInterface $router)
|
||||||
|
{
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
$this->router = $router;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function authenticate(Request $request): Passport
|
||||||
|
{
|
||||||
|
$username = $request->request->get(key: 'username');
|
||||||
|
$password = $request->request->get(key: 'password');
|
||||||
|
$csrfToken = $request->request->get(key: '_csrf_token');
|
||||||
|
|
||||||
|
$request->getSession()->set(name: Security::LAST_USERNAME, value: $username);
|
||||||
|
|
||||||
|
return new Passport(
|
||||||
|
userBadge: new UserBadge(userIdentifier: $username, userLoader: function ($userIdentifier) {
|
||||||
|
$user = $this->userRepository->findOneBy(['username' => $userIdentifier]);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$user = $this->userRepository->findOneBy(['email' => $userIdentifier]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}),
|
||||||
|
credentials: new CustomCredentials(customCredentialsChecker: function ($credentials, User $user) {
|
||||||
|
return $credentials === 'test';
|
||||||
|
|
||||||
|
}, credentials : $password),
|
||||||
|
|
||||||
|
// new PasswordCredentials($password),
|
||||||
|
badges: [
|
||||||
|
new CsrfTokenBadge(csrfTokenId: 'authenticate', csrfToken: $csrfToken),
|
||||||
|
new RememberMeBadge()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||||
|
{
|
||||||
|
if ($target = $this->getTargetPath(session: $request->getSession(), firewallName: $firewallName)) {
|
||||||
|
return new RedirectResponse(url: $target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RedirectResponse(
|
||||||
|
url: $this->router->generate(name: 'app_main')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function getLoginUrl(Request $request): string
|
||||||
|
{
|
||||||
|
return $this->router->generate(name: 'app_login');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{# templates/admin/index.html.twig #}
|
||||||
|
|
||||||
|
{% extends '@EasyAdmin/page/content.html.twig' %}
|
|
@ -0,0 +1,70 @@
|
||||||
|
{# templates/projects/index.html.twig #}
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %} Projects {% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="container-fluid box">
|
||||||
|
<div class="row">
|
||||||
|
<h2>This is an overview of my current public (and open source) projects.</h2>
|
||||||
|
|
||||||
|
<!-- projects List -->
|
||||||
|
<div class="col-sm-12">
|
||||||
|
{% for project in projects %}
|
||||||
|
<div class="project-container bg-dark my-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<a href="{{ path('app_projects', { name: project.name }) }}">
|
||||||
|
{% if project.teaserImage %}
|
||||||
|
<img
|
||||||
|
class="blog-img"
|
||||||
|
src=" {# uploaded_asset(blogpost.teaserImage)|imagine_filter('squared_thumbnail_small') #}"
|
||||||
|
alt="Teaser">
|
||||||
|
{% else %}
|
||||||
|
<img
|
||||||
|
class="blog-img"
|
||||||
|
src="{{ asset('build/images/24unix/24_logo_bg_96x96.png') }}"
|
||||||
|
alt="Teaser">
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
<div>
|
||||||
|
{% for developer in project.developer %}
|
||||||
|
<a class="align-left blog-details"
|
||||||
|
href="{{ path('app_profile', { 'username':developer.username }) }}">
|
||||||
|
<img class="article-author-img rounded-circle"
|
||||||
|
src="{{ asset('build/images/tracer_schmolle.png') }}"
|
||||||
|
alt="profile"></a>
|
||||||
|
<a href="{{ path('app_profile', { 'username':developer.username }) }}">{{ developer.username }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8 mt-2">
|
||||||
|
<a href="{{ path('app_projects', { name: project.name }) }}">
|
||||||
|
<div class="article-title d-inline-block pl-3 align-middle">
|
||||||
|
<h2>{{ project.name }}</h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
<div class="blog-teaser mb-2 pb-2 text-xl-start">
|
||||||
|
{{ project.description }}
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
started: {{ project.createdAt | ago }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if is_granted('ROLE_ADMIN') %}
|
||||||
|
<div class="text-xl-start">
|
||||||
|
<a href="{{ path('app_main') }}"><i class="fa fa-plus-circle"></i></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{# templates/blog/blog_show.html.twig #}
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %} Blogpost {% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
{% if is_granted('ROLE_ADMIN') %}
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<a href="{{ path('app_main', { id : project.id }) }}"><i class="fa fa-3x fa-fw fa-edit"></i></a>
|
||||||
|
<a href="{{ path('app_main', { id : project.id }) }}"><i class="fa fa-3x fa-fw fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="show-article-container p-3 mt-4">
|
||||||
|
<div class="show-article-title-container d-inline-block pl-3 align-middle">
|
||||||
|
<h2>{{ project.name }}</h2>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Source: <a href="{{ project.url }}" target="_blank">{{ project.url }}</a> <i
|
||||||
|
class="fa fa-external-link" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="article-text">
|
||||||
|
{{ readme | markdown_to_html }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,53 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Profile of {{ user.username }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="container box rounded bg-dark mt-5 mb-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 border-right">
|
||||||
|
<div class="d-flex flex-column align-items-center text-center p-3 py-5">
|
||||||
|
<img class="rounded-circle mt-5"
|
||||||
|
width="150px"
|
||||||
|
src=" {{ asset('build/images/tracer_schmolle.png') }}" alt="profile image">
|
||||||
|
<span class="font-weight-bold">{{ user.username }}</span>
|
||||||
|
<span class="text-white-50"><i class="fa fa-lg fa-envelope me-1"></i>{{ user.email }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 border-right">
|
||||||
|
<div class="p-3 py-5">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h4 class="text-right">User Profile</h4>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="first-name">First Name</label>
|
||||||
|
<input type="text" id="first-name" class="form-control" placeholder="First Name" value="{{ user.firstName }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="last-name">Last Name</label>
|
||||||
|
<input type="text" id="last-name" class="form-control" value="{{ user.lastName }}" placeholder="Last Name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="username">Username</label>
|
||||||
|
<input type="text" class="form-control" id="username" placeholder="eMail address" value="{{ user.email }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="mt-5 text-center">
|
||||||
|
<button class="btn btn-primary profile-button" type="button">Save Profile</button>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,53 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Profile of {{ user.username }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="container box rounded bg-dark mt-5 mb-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 border-right">
|
||||||
|
<div class="d-flex flex-column align-items-center text-center p-3 py-5">
|
||||||
|
<img class="rounded-circle mt-5"
|
||||||
|
width="150px"
|
||||||
|
src=" {{ asset('build/images/tracer_schmolle.png') }}" alt="profile image">
|
||||||
|
<span class="font-weight-bold">{{ user.username }}</span>
|
||||||
|
<span class="text-white-50"><i class="fa fa-lg fa-envelope me-1"></i>{{ user.email }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 border-right">
|
||||||
|
<div class="p-3 py-5">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h4 class="text-right">User Profile</h4>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="first-name">First Name</label>
|
||||||
|
<input type="text" disabled id="first-name" class="form-control" placeholder="First Name" value="{{ user.firstName }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="last-name">Last Name</label>
|
||||||
|
<input type="text" disabled id="last-name" class="form-control" value="{{ user.lastName }}" placeholder="Last Name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="labels" for="username">Username</label>
|
||||||
|
<input type="text" disabled class="form-control" id="username" placeholder="eMail address" value="{{ user.email }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="mt-5 text-center">
|
||||||
|
<button class="btn btn-primary profile-button" type="button">Save Profile</button>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,2 @@
|
||||||
|
"Invalid credentials.": "Invalid password entered!"
|
||||||
|
"Username could not be found.": "Neither user or eMail address is valid!"
|
Loading…
Reference in New Issue