From b1df69696fc62e2d7301c329553f593fb8329a2c Mon Sep 17 00:00:00 2001 From: afornerot Date: Sun, 6 Jul 2025 21:36:09 +0200 Subject: [PATCH] svg --- composer.json | 5 +- composer.lock | 545 ++++++++++++++++++++++++++- config/packages/twig.yaml | 2 +- config/services.yaml | 1 + src/Controller/HomeController.php | 11 + src/Controller/ProjectController.php | 10 +- src/Entity/Project.php | 45 +++ src/Form/ProjectType.php | 47 +++ src/Twig/TextileExtension.php | 55 +++ symfony.lock | 9 + templates/home/home.html.twig | 180 ++++++--- templates/issue/view.html.twig | 76 ++++ templates/project/edit.html.twig | 20 + 13 files changed, 955 insertions(+), 51 deletions(-) create mode 100644 src/Twig/TextileExtension.php create mode 100644 templates/issue/view.html.twig diff --git a/composer.json b/composer.json index 2f44667..c107268 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,8 @@ "doctrine/orm": "^3.3", "friendsofsymfony/rest-bundle": "^3.8", "guzzlehttp/guzzle": "^7.9", + "league/commonmark": "^2.7", + "netcarver/textile": "^4.1", "oneup/uploader-bundle": "^5.0", "phpdocumentor/reflection-docblock": "^5.4", "phpstan/phpdoc-parser": "^1.33", @@ -46,7 +48,8 @@ "symfony/validator": "7.1.*", "symfony/web-link": "7.1.*", "symfony/yaml": "7.1.*", - "twig/extra-bundle": "^2.12|^3.0", + "twig/extra-bundle": "^3.21", + "twig/markdown-extra": "^3.21", "twig/twig": "^2.12|^3.0" }, "config": { diff --git a/composer.lock b/composer.lock index 12d155a..a368b16 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4e3288f402ef7fdd6634a7695bbba17e", + "content-hash": "02db7717ce6acd724d39ff2a85d6986b", "packages": [ { "name": "apereo/phpcas", @@ -137,6 +137,81 @@ ], "time": "2025-03-29T13:50:30+00:00" }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + }, + "time": "2024-07-08T12:26:09+00:00" + }, { "name": "doctrine/cache", "version": "2.2.0", @@ -1852,6 +1927,195 @@ ], "time": "2025-03-27T12:30:47+00:00" }, + { + "name": "league/commonmark", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 | ^7.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2025-05-05T12:20:28+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, { "name": "monolog/monolog", "version": "3.9.0", @@ -1955,6 +2219,213 @@ ], "time": "2025-03-24T10:02:05+00:00" }, + { + "name": "netcarver/textile", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/textile/php-textile.git", + "reference": "a16ccd9e7c5ab758cf66fca5ab2b39eaae1b616c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/textile/php-textile/zipball/a16ccd9e7c5ab758cf66fca5ab2b39eaae1b616c", + "reference": "a16ccd9e7c5ab758cf66fca5ab2b39eaae1b616c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.11", + "phpunit/phpunit": "^9.5.20", + "psy/psysh": "^0.12.4", + "squizlabs/php_codesniffer": "3.*", + "symfony/yaml": "^5.4.40" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Netcarver\\Textile\\": "src/Netcarver/Textile/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Textile markup language parser", + "homepage": "https://github.com/textile/php-textile", + "keywords": [ + "document", + "format", + "html", + "language", + "markup", + "parser", + "php-textile", + "plaintext", + "textile" + ], + "support": { + "issues": "https://github.com/textile/php-textile/issues", + "source": "https://github.com/textile/php-textile", + "wiki": "https://github.com/textile/php-textile/wiki" + }, + "time": "2025-01-07T14:11:32+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.2" + }, + "time": "2024-10-06T23:10:23+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.7", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/e67c4061eb40b9c113b218214e42cb5a0dda28f2", + "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.7" + }, + "time": "2025-06-03T04:55:08+00:00" + }, { "name": "oneup/uploader-bundle", "version": "5.0.1", @@ -8350,6 +8821,78 @@ ], "time": "2025-02-19T14:29:33+00:00" }, + { + "name": "twig/markdown-extra", + "version": "v3.21.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/markdown-extra.git", + "reference": "f4616e1dd375209dacf6026f846e6b537d036ce4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/f4616e1dd375209dacf6026f846e6b537d036ce4", + "reference": "f4616e1dd375209dacf6026f846e6b537d036ce4", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "twig/twig": "^3.13|^4.0" + }, + "require-dev": { + "erusev/parsedown": "dev-master as 1.x-dev", + "league/commonmark": "^1.0|^2.0", + "league/html-to-markdown": "^4.8|^5.0", + "michelf/php-markdown": "^1.8|^2.0", + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Twig\\Extra\\Markdown\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for Markdown", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "markdown", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/markdown-extra/tree/v3.21.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2025-01-31T20:45:36+00:00" + }, { "name": "twig/twig", "version": "v3.21.1", diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index aeb223e..8be6e1d 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -3,7 +3,7 @@ twig: form_themes: ['bootstrap_5_layout.html.twig'] globals: appName: "%appName%" - + redmineUrl: "%redmineUrl%" when@test: twig: strict_variables: true diff --git a/config/services.yaml b/config/services.yaml index 9c11e5c..8119b57 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -31,3 +31,4 @@ services: App\Security\DynamicAuthenticator: arguments: $modeAuth: '%env(MODE_AUTH)%' + diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index da5d5ad..159ead7 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -2,6 +2,7 @@ namespace App\Controller; +use App\Repository\IssueRepository; use App\Service\RedmineService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -49,4 +50,14 @@ class HomeController extends AbstractController 'usesidebar' => false, ]); } + + #[Route('/user/issue/{id}', name: 'issue_view')] + public function view(int $id, IssueRepository $issueRepository): Response + { + $issue = $issueRepository->find($id); + + return $this->render('issue/view.html.twig', [ + 'issue' => $issue, + ]); + } } diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index 288f6d5..4bcefe1 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -72,13 +72,18 @@ class ProjectController extends AbstractController return $this->redirectToRoute('app_admin_project'); } - $form = $this->createForm(ProjectType::class, $project, ['mode' => 'update', 'redmineprojects' => $this->redmineService->getProjects($this->getParameter('redmineApikey'))]); + $redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey')); + $project->setRedmine($redmine); + $em->persist($project); + $em->flush(); + + $form = $this->createForm(ProjectType::class, $project, ['mode' => 'update', 'redmineprojects' => $this->redmineService->getProjects($this->getParameter('redmineApikey')), 'redmine' => $redmine]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $redmine = $this->redmineService->getProject($project->getId(), $this->getParameter('redmineApikey')); $project->setRedmine($redmine); $em->flush(); - $this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), true); + $this->redmineService->majProjectIssues($project, $this->getParameter('redmineApikey'), false); return $this->redirectToRoute('app_admin_project'); } @@ -91,6 +96,7 @@ class ProjectController extends AbstractController 'routedelete' => 'app_admin_project_delete', 'mode' => 'update', 'form' => $form, + 'project' => $project, ]); } diff --git a/src/Entity/Project.php b/src/Entity/Project.php index f93ea70..0039c6a 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -27,6 +27,15 @@ class Project #[ORM\Column(nullable: false)] private array $redmine; + #[ORM\Column(nullable: true)] + private ?array $hiddenstatuses = null; + + #[ORM\Column(nullable: true)] + private ?array $hiddensprints = null; + + #[ORM\Column(nullable: true)] + private ?array $hiddenversions = null; + /** * @var Collection */ @@ -112,6 +121,42 @@ class Project return $this; } + public function getHiddenstatuses(): ?array + { + return $this->hiddenstatuses; + } + + public function setHiddenstatuses(array $hiddenstatuses): static + { + $this->hiddenstatuses = $hiddenstatuses; + + return $this; + } + + public function getHiddensprints(): ?array + { + return $this->hiddensprints; + } + + public function setHiddensprints(array $hiddensprints): static + { + $this->hiddensprints = $hiddensprints; + + return $this; + } + + public function getHiddenversions(): ?array + { + return $this->hiddenversions; + } + + public function setHiddenversions(array $hiddenversions): static + { + $this->hiddenversions = $hiddenversions; + + return $this; + } + /** * @return Collection */ diff --git a/src/Form/ProjectType.php b/src/Form/ProjectType.php index 246d38a..c5fdb96 100644 --- a/src/Form/ProjectType.php +++ b/src/Form/ProjectType.php @@ -21,11 +21,13 @@ class ProjectType extends AbstractType foreach ($options['redmineprojects'] as $redmine) { $redmines[$redmine['name']] = $redmine['id']; } + $builder ->add('id', ChoiceType::class, [ 'label' => 'Projet Redmine', 'choices' => $redmines, 'placeholder' => 'SĂ©lectionnez un projet', + 'disabled' => ('update' == $options['mode']), ]) ->add('submit', SubmitType::class, [ @@ -48,6 +50,50 @@ class ProjectType extends AbstractType 'required' => false, 'by_reference' => false, ]); + + if ('update' == $options['mode']) { + $redmines = []; + foreach ($options['redmine']['issue_statuses'] as $redmine) { + $redmines[$redmine['name']] = $redmine['id']; + } + + $builder + ->add('hiddenstatuses', ChoiceType::class, [ + 'label' => 'Statuts CachĂ©s', + 'choices' => $redmines, + 'placeholder' => 'SĂ©lectionnez un statut', + 'multiple' => true, + 'attr' => ['class' => 'select2'], + ]); + + $redmines = []; + foreach ($options['redmine']['sprints'] as $redmine) { + $redmines[$redmine['name']] = $redmine['id']; + } + + $builder + ->add('hiddensprints', ChoiceType::class, [ + 'label' => 'Sprints CachĂ©s', + 'choices' => $redmines, + 'placeholder' => 'SĂ©lectionnez un sprint', + 'multiple' => true, + 'attr' => ['class' => 'select2'], + ]); + + $redmines = []; + foreach ($options['redmine']['versions'] as $redmine) { + $redmines[$redmine['name']] = $redmine['id']; + } + + $builder + ->add('hiddenversions', ChoiceType::class, [ + 'label' => 'Versions CachĂ©s', + 'choices' => $redmines, + 'placeholder' => 'SĂ©lectionnez une version', + 'multiple' => true, + 'attr' => ['class' => 'select2'], + ]); + } } public function configureOptions(OptionsResolver $resolver): void @@ -56,6 +102,7 @@ class ProjectType extends AbstractType 'data_class' => Project::class, 'mode' => 'submit', 'redmineprojects' => [], + 'redmine' => [], ]); } } diff --git a/src/Twig/TextileExtension.php b/src/Twig/TextileExtension.php new file mode 100644 index 0000000..8281699 --- /dev/null +++ b/src/Twig/TextileExtension.php @@ -0,0 +1,55 @@ + ['html']]), + ]; + } + + public function textileToHtml(string $text): string + { + $text = $this->fixTextileTable($text); + $parser = new Parser(); + + return $parser->parse($text); + } + + private function fixTextileTable(string $text): string + { + $lines = explode("\n", $text); + $fixed = []; + + foreach ($lines as $line) { + $line = trim($line); + if (!$line) { + $fixed[] = ''; + continue; + } + + if (preg_match('/^\|.*\|$/', $line)) { + $fixed[] = $line; + continue; + } + + // Ligne mal formĂ©e potentiellement issue d’un tableau + $columns = array_map('trim', explode('|', $line)); + $columns = array_filter($columns); + if (count($columns)) { + $fixed[] = '|'.implode('|', $columns).'|'; + } else { + $fixed[] = $line; + } + } + + return implode("\n", $fixed); + } +} diff --git a/symfony.lock b/symfony.lock index e5086fb..6582239 100644 --- a/symfony.lock +++ b/symfony.lock @@ -1,4 +1,13 @@ { + "doctrine/deprecations": { + "version": "1.1", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "87424683adc81d7dc305eefec1fced883084aab9" + } + }, "doctrine/doctrine-bundle": { "version": "2.13", "recipe": { diff --git a/templates/home/home.html.twig b/templates/home/home.html.twig index 46f66e9..85fd724 100644 --- a/templates/home/home.html.twig +++ b/templates/home/home.html.twig @@ -2,27 +2,44 @@ {% block localstyle %}