Compare commits
No commits in common. "feature_paste" and "master" have entirely different histories.
feature_pa
...
master
30
.env
30
.env
|
@ -1,30 +0,0 @@
|
||||||
# In all environments, the following files are loaded if they exist,
|
|
||||||
# the latter taking precedence over the former:
|
|
||||||
#
|
|
||||||
# * .env contains default values for the environment variables needed by the app
|
|
||||||
# * .env.local uncommitted file with local overrides
|
|
||||||
# * .env.$APP_ENV committed environment-specific defaults
|
|
||||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
|
||||||
#
|
|
||||||
# Real environment variables win over .env files.
|
|
||||||
#
|
|
||||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
|
||||||
# https://symfony.com/doc/current/configuration/secrets.html
|
|
||||||
#
|
|
||||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_ENV=dev
|
|
||||||
APP_SECRET=your_secret_please_set_on_local_env
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
|
|
||||||
###> doctrine/doctrine-bundle ###
|
|
||||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
|
||||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
|
||||||
#
|
|
||||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
|
|
||||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=15&charset=utf8"
|
|
||||||
###< doctrine/doctrine-bundle ###
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,10 +0,0 @@
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
/.env.local
|
|
||||||
/.env.local.php
|
|
||||||
/.env.*.local
|
|
||||||
/config/secrets/prod/prod.decrypt.private.php
|
|
||||||
/public/bundles/
|
|
||||||
/var/
|
|
||||||
/vendor/
|
|
||||||
###< symfony/framework-bundle ###
|
|
17
bin/console
17
bin/console
|
@ -1,17 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use App\Kernel;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
|
||||||
|
|
||||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
|
||||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
|
||||||
|
|
||||||
return function (array $context) {
|
|
||||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
|
||||||
|
|
||||||
return new Application($kernel);
|
|
||||||
};
|
|
|
@ -1,75 +0,0 @@
|
||||||
{
|
|
||||||
"type": "project",
|
|
||||||
"license": "proprietary",
|
|
||||||
"minimum-stability": "stable",
|
|
||||||
"prefer-stable": true,
|
|
||||||
"require": {
|
|
||||||
"php": ">=8.1",
|
|
||||||
"ext-ctype": "*",
|
|
||||||
"ext-iconv": "*",
|
|
||||||
"doctrine/doctrine-bundle": "^2.10",
|
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.2",
|
|
||||||
"doctrine/orm": "^2.15",
|
|
||||||
"scrivo/highlight.php": "v9.18.1.10",
|
|
||||||
"symfony/console": "6.3.*",
|
|
||||||
"symfony/dotenv": "6.3.*",
|
|
||||||
"symfony/flex": "^2",
|
|
||||||
"symfony/form": "6.3.*",
|
|
||||||
"symfony/framework-bundle": "6.3.*",
|
|
||||||
"symfony/runtime": "6.3.*",
|
|
||||||
"symfony/twig-bundle": "6.3.*",
|
|
||||||
"symfony/validator": "6.3.*",
|
|
||||||
"symfony/yaml": "6.3.*"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"allow-plugins": {
|
|
||||||
"php-http/discovery": true,
|
|
||||||
"symfony/flex": true,
|
|
||||||
"symfony/runtime": true
|
|
||||||
},
|
|
||||||
"sort-packages": true
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"App\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"App\\Tests\\": "tests/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"replace": {
|
|
||||||
"symfony/polyfill-ctype": "*",
|
|
||||||
"symfony/polyfill-iconv": "*",
|
|
||||||
"symfony/polyfill-php72": "*",
|
|
||||||
"symfony/polyfill-php73": "*",
|
|
||||||
"symfony/polyfill-php74": "*",
|
|
||||||
"symfony/polyfill-php80": "*",
|
|
||||||
"symfony/polyfill-php81": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"auto-scripts": {
|
|
||||||
"cache:clear": "symfony-cmd",
|
|
||||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
|
||||||
},
|
|
||||||
"post-install-cmd": [
|
|
||||||
"@auto-scripts"
|
|
||||||
],
|
|
||||||
"post-update-cmd": [
|
|
||||||
"@auto-scripts"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"symfony/symfony": "*"
|
|
||||||
},
|
|
||||||
"extra": {
|
|
||||||
"symfony": {
|
|
||||||
"allow-contrib": false,
|
|
||||||
"require": "6.3.*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/maker-bundle": "^1.50"
|
|
||||||
}
|
|
||||||
}
|
|
5045
composer.lock
generated
5045
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
|
||||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
|
||||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
|
||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
|
||||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
|
||||||
];
|
|
|
@ -1,19 +0,0 @@
|
||||||
framework:
|
|
||||||
cache:
|
|
||||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
|
||||||
#prefix_seed: your_vendor_name/app_name
|
|
||||||
|
|
||||||
# The "app" cache stores to the filesystem by default.
|
|
||||||
# The data in this cache should persist between deploys.
|
|
||||||
# Other options include:
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
#app: cache.adapter.redis
|
|
||||||
#default_redis_provider: redis://localhost
|
|
||||||
|
|
||||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
|
||||||
#app: cache.adapter.apcu
|
|
||||||
|
|
||||||
# Namespaced pools use the above "app" backend by default
|
|
||||||
#pools:
|
|
||||||
#my.dedicated.cache: null
|
|
|
@ -1,46 +0,0 @@
|
||||||
doctrine:
|
|
||||||
dbal:
|
|
||||||
url: '%env(resolve:DATABASE_URL)%'
|
|
||||||
|
|
||||||
# IMPORTANT: You MUST configure your server version,
|
|
||||||
# either here or in the DATABASE_URL env var (see .env file)
|
|
||||||
#server_version: '15'
|
|
||||||
orm:
|
|
||||||
auto_generate_proxy_classes: true
|
|
||||||
enable_lazy_ghost_objects: true
|
|
||||||
report_fields_where_declared: true
|
|
||||||
validate_xml_mapping: true
|
|
||||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
|
||||||
auto_mapping: true
|
|
||||||
mappings:
|
|
||||||
App:
|
|
||||||
is_bundle: false
|
|
||||||
dir: '%kernel.project_dir%/src/Entity'
|
|
||||||
prefix: 'App\Entity'
|
|
||||||
alias: App
|
|
||||||
|
|
||||||
when@test:
|
|
||||||
doctrine:
|
|
||||||
dbal:
|
|
||||||
# "TEST_TOKEN" is typically set by ParaTest
|
|
||||||
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
|
|
||||||
|
|
||||||
when@prod:
|
|
||||||
doctrine:
|
|
||||||
orm:
|
|
||||||
auto_generate_proxy_classes: false
|
|
||||||
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
|
|
||||||
query_cache_driver:
|
|
||||||
type: pool
|
|
||||||
pool: doctrine.system_cache_pool
|
|
||||||
result_cache_driver:
|
|
||||||
type: pool
|
|
||||||
pool: doctrine.result_cache_pool
|
|
||||||
|
|
||||||
framework:
|
|
||||||
cache:
|
|
||||||
pools:
|
|
||||||
doctrine.result_cache_pool:
|
|
||||||
adapter: cache.app
|
|
||||||
doctrine.system_cache_pool:
|
|
||||||
adapter: cache.system
|
|
|
@ -1,6 +0,0 @@
|
||||||
doctrine_migrations:
|
|
||||||
migrations_paths:
|
|
||||||
# namespace is arbitrary but should be different from App\Migrations
|
|
||||||
# as migrations classes should NOT be autoloaded
|
|
||||||
'DoctrineMigrations': '%kernel.project_dir%/migrations'
|
|
||||||
enable_profiler: false
|
|
|
@ -1,25 +0,0 @@
|
||||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
|
||||||
framework:
|
|
||||||
secret: '%env(APP_SECRET)%'
|
|
||||||
#csrf_protection: true
|
|
||||||
http_method_override: false
|
|
||||||
handle_all_throwables: true
|
|
||||||
|
|
||||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
|
||||||
# Remove or comment this section to explicitly disable session support.
|
|
||||||
session:
|
|
||||||
handler_id: null
|
|
||||||
cookie_secure: auto
|
|
||||||
cookie_samesite: lax
|
|
||||||
storage_factory_id: session.storage.factory.native
|
|
||||||
|
|
||||||
#esi: true
|
|
||||||
#fragments: true
|
|
||||||
php_errors:
|
|
||||||
log: true
|
|
||||||
|
|
||||||
when@test:
|
|
||||||
framework:
|
|
||||||
test: true
|
|
||||||
session:
|
|
||||||
storage_factory_id: session.storage.factory.mock_file
|
|
|
@ -1,12 +0,0 @@
|
||||||
framework:
|
|
||||||
router:
|
|
||||||
utf8: true
|
|
||||||
|
|
||||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
|
||||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
|
||||||
#default_uri: http://localhost
|
|
||||||
|
|
||||||
when@prod:
|
|
||||||
framework:
|
|
||||||
router:
|
|
||||||
strict_requirements: null
|
|
|
@ -1,6 +0,0 @@
|
||||||
twig:
|
|
||||||
default_path: '%kernel.project_dir%/templates'
|
|
||||||
|
|
||||||
when@test:
|
|
||||||
twig:
|
|
||||||
strict_variables: true
|
|
|
@ -1,13 +0,0 @@
|
||||||
framework:
|
|
||||||
validation:
|
|
||||||
email_validation_mode: html5
|
|
||||||
|
|
||||||
# Enables validator auto-mapping support.
|
|
||||||
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
|
|
||||||
#auto_mapping:
|
|
||||||
# App\Entity\: []
|
|
||||||
|
|
||||||
when@test:
|
|
||||||
framework:
|
|
||||||
validation:
|
|
||||||
not_compromised_password: false
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
|
||||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
controllers:
|
|
||||||
resource:
|
|
||||||
path: ../src/Controller/
|
|
||||||
namespace: App\Controller
|
|
||||||
type: attribute
|
|
|
@ -1,4 +0,0 @@
|
||||||
when@dev:
|
|
||||||
_errors:
|
|
||||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
|
||||||
prefix: /_error
|
|
|
@ -1,24 +0,0 @@
|
||||||
# This file is the entry point to configure your own services.
|
|
||||||
# Files in the packages/ subdirectory configure your dependencies.
|
|
||||||
|
|
||||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
|
||||||
parameters:
|
|
||||||
|
|
||||||
services:
|
|
||||||
# default configuration for services in *this* file
|
|
||||||
_defaults:
|
|
||||||
autowire: true # Automatically injects dependencies in your services.
|
|
||||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
|
||||||
App\:
|
|
||||||
resource: '../src/'
|
|
||||||
exclude:
|
|
||||||
- '../src/DependencyInjection/'
|
|
||||||
- '../src/Entity/'
|
|
||||||
- '../src/Kernel.php'
|
|
||||||
|
|
||||||
# add more service definitions when explicit configuration is needed
|
|
||||||
# please note that last definitions always *replace* previous ones
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace DoctrineMigrations;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
|
|
||||||
final class Version20230720115905 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('CREATE SEQUENCE paste_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
|
||||||
$this->addSql('CREATE TABLE paste (id INT NOT NULL, text TEXT NOT NULL, language VARCHAR(25), description TEXT, filename VARCHAR(128), author VARCHAR(128), publish_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, expiration_date TIMESTAMP(0) WITHOUT TIME ZONE, ip VARCHAR(39) NOT NULL, secret VARCHAR(40), PRIMARY KEY(id))');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('CREATE SCHEMA public');
|
|
||||||
$this->addSql('DROP SEQUENCE paste_id_seq CASCADE');
|
|
||||||
$this->addSql('DROP TABLE paste');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
/* Ocean Dark Theme */
|
|
||||||
/* https://github.com/gavsiu */
|
|
||||||
/* Original theme - https://github.com/chriskempson/base16 */
|
|
||||||
|
|
||||||
/* Ocean Comment */
|
|
||||||
.hljs-comment,
|
|
||||||
.hljs-quote {
|
|
||||||
color: #65737e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Red */
|
|
||||||
.hljs-variable,
|
|
||||||
.hljs-template-variable,
|
|
||||||
.hljs-tag,
|
|
||||||
.hljs-name,
|
|
||||||
.hljs-selector-id,
|
|
||||||
.hljs-selector-class,
|
|
||||||
.hljs-regexp,
|
|
||||||
.hljs-deletion {
|
|
||||||
color: #bf616a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Orange */
|
|
||||||
.hljs-number,
|
|
||||||
.hljs-built_in,
|
|
||||||
.hljs-builtin-name,
|
|
||||||
.hljs-literal,
|
|
||||||
.hljs-type,
|
|
||||||
.hljs-params,
|
|
||||||
.hljs-meta,
|
|
||||||
.hljs-link {
|
|
||||||
color: #d08770;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Yellow */
|
|
||||||
.hljs-attribute {
|
|
||||||
color: #ebcb8b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Green */
|
|
||||||
.hljs-string,
|
|
||||||
.hljs-symbol,
|
|
||||||
.hljs-bullet,
|
|
||||||
.hljs-addition {
|
|
||||||
color: #a3be8c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Blue */
|
|
||||||
.hljs-title,
|
|
||||||
.hljs-section {
|
|
||||||
color: #8fa1b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ocean Purple */
|
|
||||||
.hljs-keyword,
|
|
||||||
.hljs-selector-tag {
|
|
||||||
color: #b48ead;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hljs {
|
|
||||||
display: block;
|
|
||||||
overflow-x: auto;
|
|
||||||
background: #2b303b;
|
|
||||||
color: #c0c5ce;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hljs-emphasis {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hljs-strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use App\Kernel;
|
|
||||||
|
|
||||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
|
||||||
|
|
||||||
return function (array $context) {
|
|
||||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
|
||||||
};
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use App\DTO\PasteFormData;
|
|
||||||
use App\Entity\CodeHighlighter;
|
|
||||||
use App\Entity\Paste;
|
|
||||||
use App\Form\Type\PasteForm;
|
|
||||||
use App\Repository\PasteRepository;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
|
|
||||||
class PasteController extends AbstractController
|
|
||||||
{
|
|
||||||
#[Route('/', name: 'homepage')]
|
|
||||||
public function new(Request $request, PasteRepository $pasteRepository): Response
|
|
||||||
{
|
|
||||||
$pasteData = new PasteFormData();
|
|
||||||
$form = $this->createForm(PasteForm::class, $pasteData);
|
|
||||||
|
|
||||||
$form->handleRequest($request);
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
$pasteData = $form->getData();
|
|
||||||
|
|
||||||
$paste = Paste::fromFormDataAndIp($pasteData, $request->getClientIp());
|
|
||||||
$pasteRepository->save($paste, true);
|
|
||||||
|
|
||||||
return $this->redirectToRoute('showpaste', ['id' => $paste->id, 'secret' => $paste->secret]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('paste.html.twig', [
|
|
||||||
'form' => $form,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route('/{id}/{secret}', name: 'showpaste')]
|
|
||||||
public function showPaste(PasteRepository $pasteRepository, string $id, ?string $secret = NULL): Response
|
|
||||||
{
|
|
||||||
$paste = $pasteRepository->findOneBy(['id' => $id, 'secret' => $secret]);
|
|
||||||
$pasteData = new PasteFormData($paste);
|
|
||||||
$form = $this->createForm(PasteForm::class, $pasteData);
|
|
||||||
|
|
||||||
return $this->render('show_paste.html.twig', [
|
|
||||||
'form' => $form,
|
|
||||||
'highlighted_text' => CodeHighlighter::highlight($pasteData->language, $pasteData->text)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\DTO;
|
|
||||||
|
|
||||||
use App\Entity\Paste;
|
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
|
||||||
|
|
||||||
|
|
||||||
class PasteFormData
|
|
||||||
{
|
|
||||||
#[Assert\NotBlank]
|
|
||||||
public string $text;
|
|
||||||
public bool $private;
|
|
||||||
public ?string $language = null;
|
|
||||||
public ?string $description = null;
|
|
||||||
public ?string $filename = null;
|
|
||||||
public ?string $author = null;
|
|
||||||
public ?\DateTimeImmutable $expirationDate;
|
|
||||||
|
|
||||||
public function __construct(?Paste $paste = null)
|
|
||||||
{
|
|
||||||
if ($paste === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->fromPaste($paste);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function fromPaste(Paste $paste)
|
|
||||||
{
|
|
||||||
$this->text = $paste->text;
|
|
||||||
$this->private = $paste->secret !== null;
|
|
||||||
$this->language = $paste->language;
|
|
||||||
$this->description = $paste->description;
|
|
||||||
$this->filename = $paste->filename;
|
|
||||||
$this->author = $paste->author !== null ? $paste->author : 'anonymous';
|
|
||||||
$this->expirationDate = $paste->expirationDate;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
use \Highlight\Highlighter;
|
|
||||||
|
|
||||||
|
|
||||||
class CodeHighlighter
|
|
||||||
{
|
|
||||||
public static function highlight(?string $language, string $code): string
|
|
||||||
{
|
|
||||||
$hl = new Highlighter();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Highlight some code.
|
|
||||||
$highlighted = $hl->highlight($language, $code);
|
|
||||||
$highlighted_text = "<pre><code class=\"hljs {$highlighted->language}\">".$highlighted->value.'</code></pre>';
|
|
||||||
}
|
|
||||||
catch (\DomainException $e) {
|
|
||||||
// This is thrown if the specified language does not exist
|
|
||||||
$highlighted_text = '<pre><code>'.htmlentities($code).'</code></pre>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $highlighted_text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
use App\DTO\PasteFormData;
|
|
||||||
use App\Repository\PasteRepository;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: PasteRepository::class)]
|
|
||||||
class Paste
|
|
||||||
{
|
|
||||||
#[ORM\Id]
|
|
||||||
#[ORM\GeneratedValue]
|
|
||||||
#[ORM\Column]
|
|
||||||
public readonly int $id;
|
|
||||||
|
|
||||||
private function __construct(
|
|
||||||
#[ORM\Column(type: 'text', nullable: false)]
|
|
||||||
public readonly string $text,
|
|
||||||
#[ORM\Column(type: 'string', length: 25, nullable: true)]
|
|
||||||
public readonly ?string $language,
|
|
||||||
#[ORM\Column(type: 'text', nullable: true)]
|
|
||||||
public readonly ?string $description,
|
|
||||||
#[ORM\Column(type: 'string', length: 128, nullable: true)]
|
|
||||||
public readonly ?string $filename,
|
|
||||||
#[ORM\Column(type: 'string', length: 128, nullable: true)]
|
|
||||||
public readonly ?string $author,
|
|
||||||
#[ORM\Column(type: 'datetime_immutable', nullable: false)]
|
|
||||||
public readonly \DateTimeImmutable $publishDate,
|
|
||||||
#[ORM\Column(type: 'datetime_immutable', nullable: true)]
|
|
||||||
public readonly ?\DateTimeImmutable $expirationDate,
|
|
||||||
#[ORM\Column(type: 'string', length: 39, nullable: false)]
|
|
||||||
public readonly string $ip,
|
|
||||||
#[ORM\Column(type: 'string', length: 40, nullable: true)]
|
|
||||||
public readonly ?string $secret,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public static function fromFormDataAndIp(PasteFormData $pasteFormData, $ip): Paste
|
|
||||||
{
|
|
||||||
return new self(
|
|
||||||
$pasteFormData->text,
|
|
||||||
$pasteFormData->language,
|
|
||||||
$pasteFormData->description,
|
|
||||||
$pasteFormData->filename,
|
|
||||||
$pasteFormData->author,
|
|
||||||
new \DateTimeImmutable(),
|
|
||||||
$pasteFormData->expirationDate,
|
|
||||||
$ip,
|
|
||||||
$pasteFormData->private ? \hash('sha1', \random_bytes(25)) : null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\Form\Type;
|
|
||||||
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
|
||||||
|
|
||||||
|
|
||||||
class PasteForm extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
|
||||||
{
|
|
||||||
$builder
|
|
||||||
->add('language', ChoiceType::class, [
|
|
||||||
'choices' => [
|
|
||||||
'Python' => 'python',
|
|
||||||
'PHP' => 'php',
|
|
||||||
'Plain text' => NULL,
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
->add('description', TextType::class, ['required' => false])
|
|
||||||
->add('text', TextareaType::class)
|
|
||||||
->add('author', TextType::class, ['attr' => ['maxlength' => 128], 'required' => false])
|
|
||||||
->add('filename', TextType::class, ['required' => false, 'attr' => ['maxlength' =>128]])
|
|
||||||
->add('expirationDate', DateTimeType::class, [
|
|
||||||
'required' => false,
|
|
||||||
'date_widget' => 'single_text',
|
|
||||||
'input' => 'datetime_immutable',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
->add('private', CheckboxType::class, ['required' => false])
|
|
||||||
->add('save', SubmitType::class)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
|
||||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
|
||||||
|
|
||||||
class Kernel extends BaseKernel
|
|
||||||
{
|
|
||||||
use MicroKernelTrait;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace App\Repository;
|
|
||||||
|
|
||||||
use App\Entity\Paste;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class PasteRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, Paste::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function save(Paste $paste, bool $flush = false): void
|
|
||||||
{
|
|
||||||
$entityManager = $this->getEntityManager();
|
|
||||||
$entityManager->persist($paste);
|
|
||||||
|
|
||||||
if ($flush) {
|
|
||||||
$entityManager->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
119
symfony.lock
119
symfony.lock
|
@ -1,119 +0,0 @@
|
||||||
{
|
|
||||||
"doctrine/doctrine-bundle": {
|
|
||||||
"version": "2.10",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "2.10",
|
|
||||||
"ref": "f0d8c9a4da17815830aac0d63e153a940ae176bb"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/doctrine.yaml",
|
|
||||||
"src/Entity/.gitignore",
|
|
||||||
"src/Repository/.gitignore"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"doctrine/doctrine-migrations-bundle": {
|
|
||||||
"version": "3.2",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "3.1",
|
|
||||||
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/doctrine_migrations.yaml",
|
|
||||||
"migrations/.gitignore"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/console": {
|
|
||||||
"version": "6.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"bin/console"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/flex": {
|
|
||||||
"version": "2.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "1.0",
|
|
||||||
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
".env"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/framework-bundle": {
|
|
||||||
"version": "6.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "6.2",
|
|
||||||
"ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/cache.yaml",
|
|
||||||
"config/packages/framework.yaml",
|
|
||||||
"config/preload.php",
|
|
||||||
"config/routes/framework.yaml",
|
|
||||||
"config/services.yaml",
|
|
||||||
"public/index.php",
|
|
||||||
"src/Controller/.gitignore",
|
|
||||||
"src/Kernel.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/maker-bundle": {
|
|
||||||
"version": "1.50",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "1.0",
|
|
||||||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"symfony/routing": {
|
|
||||||
"version": "6.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "6.2",
|
|
||||||
"ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/routing.yaml",
|
|
||||||
"config/routes.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/twig-bundle": {
|
|
||||||
"version": "6.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "6.3",
|
|
||||||
"ref": "b7772eb20e92f3fb4d4fe756e7505b4ba2ca1a2c"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/twig.yaml",
|
|
||||||
"templates/base.html.twig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/validator": {
|
|
||||||
"version": "6.3",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "5.3",
|
|
||||||
"ref": "c32cfd98f714894c4f128bb99aa2530c1227603c"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/validator.yaml"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>{% block title %}Copypaste{% endblock %}</title>
|
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
|
||||||
{% block stylesheets %}
|
|
||||||
{% endblock %}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{% block content %}{% endblock %}
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,6 +0,0 @@
|
||||||
{% extends "base.html.twig" %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{{ form(form) }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
{% extends "base.html.twig" %}
|
|
||||||
|
|
||||||
{% block stylesheets %}
|
|
||||||
<link rel="stylesheet" href="/css/ocean.css"></link>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link active" id="show-tab" data-bs-toggle="tab" data-bs-target="#show" type="button" role="tab" aria-controls="show" aria-selected="true">Show</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#edit" type="button" role="tab" aria-controls="edit" aria-selected="false">Edit</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="tab-content" id="myTabContent">
|
|
||||||
<div class="tab-pane fade show active" id="show" role="tabpanel" aria-labelledby="show-tab">
|
|
||||||
{{ highlighted_text|raw }}
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="edit" role="tabpanel" aria-labelledby="edit-tab">
|
|
||||||
{% include 'paste.html.twig' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
Loading…
Reference in a new issue