Compare commits

..

1 commit

Author SHA1 Message Date
Renovate Bot 1e211e419f chore(deps): add renovate.json 2024-01-27 22:59:03 +00:00
20 changed files with 33443 additions and 5430 deletions

View file

@ -8,44 +8,44 @@ when:
branch: [master, master-*, develop, develop-*, feature/*] branch: [master, master-*, develop, develop-*, feature/*]
steps: steps:
"Wait the database": db-wait:
image: gitnet.fr/deblan/timeout:latest image: gitnet.fr/deblan/timeout:latest
commands: commands:
- /bin/timeout -t 30 -v -c 'while true; do nc -z -v db 3306 2>&1 | grep succeeded && exit 0; sleep 0.5; done' - /bin/timeout -t 30 -v -c 'while true; do nc -z -v db 3306 2>&1 | grep succeeded && exit 0; sleep 0.5; done'
"Create database": db-create:
image: mariadb:10.3 image: mariadb:10.3
secrets: [mysqldump] secrets: [mysqldump]
commands: commands:
- mysql -hdb -uroot -proot -e "CREATE DATABASE app" - mysql -hdb -uroot -proot -e "CREATE DATABASE app"
- eval "$MYSQLDUMP" | mysql -hdb -uroot -proot app - eval "$MYSQLDUMP" | mysql -hdb -uroot -proot app
"Configure app": app-config:
image: deblan/php:8.1 image: deblan/php:8.1
commands: commands:
- echo APP_ENV=prod >> .env.local - echo APP_ENV=prod >> .env.local
- echo APP_SECRET=$(openssl rand -hex 32) >> .env.local - echo APP_SECRET=$(openssl rand -hex 32) >> .env.local
- echo DATABASE_URL=mysql://root:root@db/app >> .env.local - echo DATABASE_URL=mysql://root:root@db/app >> .env.local
"Installs PHP dependencies": php-composer:
image: deblan/php:8.1 image: deblan/php:8.1
commands: commands:
- apt-get update && apt-get -y install git - apt-get update && apt-get -y install git
- composer install --no-scripts - composer install --no-scripts
"Migrates database": db-migrate:
image: deblan/php:8.1 image: deblan/php:8.1
environment: environment:
- PHP=php - PHP=php
commands: commands:
- ./bin/doctrine-migrate - ./bin/doctrine-migrate
"Generates JS routes": app-jsroutes:
image: deblan/php:8.1 image: deblan/php:8.1
commands: commands:
- php bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json - php bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json
"Build assets": node-build:
image: node:16-alpine image: node:16-alpine
environment: environment:
- CPU_COUNT=3 - CPU_COUNT=3
@ -60,13 +60,13 @@ steps:
- test -f public/js/fos_js_routes.json || echo "{}" > public/js/fos_js_routes.json - test -f public/js/fos_js_routes.json || echo "{}" > public/js/fos_js_routes.json
- npm run build - npm run build
"Check dependencies": security-check:
image: gitnet.fr/deblan/osv-detector:v0.9 image: gitnet.fr/deblan/osv-detector:v0.9
commands: commands:
- osv-detector composer.lock yarn.lock - osv-detector composer.lock yarn.lock
failure: ignore failure: ignore
"Build the cache": cache-build:
image: deblan/mage image: deblan/mage
volumes: *volumes volumes: *volumes
commands: commands:

View file

@ -8,7 +8,7 @@ when:
skip_clone: true skip_clone: true
steps: steps:
"Deploy": app-deploy:
image: deblan/mage image: deblan/mage
secrets: [ssh_priv_key, ssh_user, ssh_host, app_directory] secrets: [ssh_priv_key, ssh_user, ssh_host, app_directory]
volumes: *volumes volumes: *volumes

View file

@ -1,63 +1,57 @@
@import '../../vendor/murph/murph-core/src/core/Resources/assets/css/admin.scss'; @import "../../vendor/murph/murph-core/src/core/Resources/assets/css/admin.scss";
@import '@kangc/v-md-editor/lib/style/base-editor.css'; @import "~simplemde/dist/simplemde.min.css";
@import '@kangc/v-md-editor/lib/theme/style/vuepress.css';
.CodeMirror-fullscreen, .editor-toolbar.fullscreen {
z-index: 2000;
}
.ejs-link { .ejs-link {
margin: 10px auto; margin: 10px auto;
max-width: 80%; max-width: 80%;
border: 2px solid #333; border: 2px solid #333;
border-radius: 5px; border-radius: 5px;
&--anchor { &--anchor {
display: block; display: block;
padding: 30px; padding: 30px;
}
&-content {
display: inline-block;
vertical-align: top;
&--title {
font-weight: bold;
} }
&--description { &-content {
font-size: 15px; display: inline-block;
vertical-align: top;
&--title {
font-weight: bold;
}
&--description {
font-size: 15px;
}
&--link {
padding-top: 10px;
font-size: 14px;
line-height: 20px;
}
} }
&--link { $image-size: 85px;
padding-top: 10px;
font-size: 14px; &--anchor--with-image &-content {
line-height: 20px; width: calc(100% - $image-size - 5px);
padding-right: 25px;
} }
}
$image-size: 85px; &--image {
display: inline-block;
&--anchor--with-image &-content { width: $image-size;
width: calc(100% - $image-size - 5px); height: $image-size;
padding-right: 25px; background-position: center center;
} background-repeat: no-repeat;
background-size: cover;
&--image { }
display: inline-block;
width: $image-size;
height: $image-size;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
} }
.choices__list--dropdown { .choices__list--dropdown {
z-index: 3; z-index: 3;
} }
.v-md-editor {
border: 1px solid $input-border-color;
box-shadow: none;
}
.v-md-editor--fullscreen {
z-index: 3000;
}

View file

@ -411,7 +411,7 @@ pre[class*="language-"] {
.h1 { .h1 {
font-weight: normal; font-weight: normal;
font-size: 40px; font-size: 40px;
font-family: MainFont; font-family: Verdana;
text-shadow: none; text-shadow: none;
color: hsla(0, 0%, 100%, 0.7); color: hsla(0, 0%, 100%, 0.7);
} }

View file

@ -1,6 +1,6 @@
import '../../vendor/murph/murph-core/src/core/Resources/assets/js/admin.js' import '../../vendor/murph/murph-core/src/core/Resources/assets/js/admin.js'
require('./admin_modules/md-editor')() require('./admin_modules/simplemde')()
const $ = require('jquery') const $ = require('jquery')
const Sortable = require('sortablejs').Sortable const Sortable = require('sortablejs').Sortable

View file

@ -1,34 +0,0 @@
const Vue = require('vue').default
const VueMarkdownEditor = require('@kangc/v-md-editor')
const githubTheme = require('@kangc/v-md-editor/lib/theme/github.js')
const fr = require('@kangc/v-md-editor/lib/lang/fr-FR').default
const hljs = require('highlight.js')
VueMarkdownEditor.use(githubTheme, {Hljs: hljs})
VueMarkdownEditor.lang.use('fr-FR', fr)
Vue.use(VueMarkdownEditor)
module.exports = () => {
const components = document.querySelectorAll('.markdown-editor')
components.forEach((component) => {
return new Vue({
el: component,
template: `
<div>
<textarea :name="name" v-model="value" class="d-none"></textarea>
<v-md-editor v-model="value" mode="edit"></v-md-editor>
</div>
`,
data() {
return {
name: component.getAttribute('data-name'),
value: JSON.parse(component.getAttribute('data-value')),
}
},
components: {
VueMarkdownEditor
}
})
})
}

View file

@ -1,6 +1,6 @@
twig: twig:
default_path: '%kernel.project_dir%/templates' default_path: '%kernel.project_dir%/templates'
form_themes: ['form/bootstrap_4_form_theme.html.twig'] form_themes: ['@Core/form/bootstrap_4_form_theme.html.twig']
auto_reload: true auto_reload: true
paths: paths:
'%kernel.project_dir%/templates/core/': Core '%kernel.project_dir%/templates/core/': Core

29948
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -8,15 +8,13 @@
"build": "./node_modules/.bin/encore production" "build": "./node_modules/.bin/encore production"
}, },
"dependencies": { "dependencies": {
"@kangc/v-md-editor": "^1.7.12",
"daisyui": "^2.31.0", "daisyui": "^2.31.0",
"editorjs-hyperlink": "^1.0.6",
"editorjs-inline-tool": "^0.4.0",
"encore": "^0.0.30-beta", "encore": "^0.0.30-beta",
"lozad": "^1.16.0", "lozad": "^1.16.0",
"murph-project": "^1.9.4", "murph-project": "^1",
"particles.js": "^2.0.0", "particles.js": "^2.0.0",
"prismjs": "^1.23.0", "prismjs": "^1.23.0",
"simplemde": "^1.11.2",
"tingle.js": "^0.16.0", "tingle.js": "^0.16.0",
"vanillajs-datepicker": "^1.1.4", "vanillajs-datepicker": "^1.1.4",
"vue": "^2.6.14" "vue": "^2.6.14"

3
renovate.json Normal file
View file

@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View file

@ -2,30 +2,31 @@
namespace App\Controller\Blog; namespace App\Controller\Blog;
use App\Analytic\DateRangeAnalytic;
use App\Core\Controller\Admin\Crud\CrudController; use App\Core\Controller\Admin\Crud\CrudController;
use App\Core\Crud\CrudConfiguration; use App\Core\Crud\CrudConfiguration;
use App\Core\Crud\Field\DatetimeField; use App\Core\Crud\Field\DatetimeField;
use App\Core\Crud\Field\TextField; use App\Core\Crud\Field\TextField;
use App\Core\Entity\EntityInterface;
use App\Core\Form\FileUploadHandler; use App\Core\Form\FileUploadHandler;
use App\Core\Manager\EntityManager; use App\Core\Manager\EntityManager;
use App\Core\Repository\Site\NodeRepository;
use App\Entity\Blog\Post;
use App\Entity\Blog\Post as Entity; use App\Entity\Blog\Post as Entity;
use App\Factory\Blog\PostFactory as EntityFactory; use App\Factory\Blog\PostFactory as EntityFactory;
use App\Form\Blog\Filter\PostFilterType; use App\Form\Blog\Filter\PostFilterType;
use App\Form\Blog\PostType; use App\Form\Blog\PostType;
use App\Form\Blog\PostType as EntityType;
use App\Repository\Blog\PostRepositoryQuery as RepositoryQuery; use App\Repository\Blog\PostRepositoryQuery as RepositoryQuery;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Form\Form;
use App\Core\Entity\EntityInterface;
use App\Entity\Blog\Post;
use App\Analytic\DateRangeAnalytic;
use App\Core\Repository\Site\NodeRepository;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
#[Route(path: '/admin/blog/post')] #[Route(path: '/admin/blog/post')]
class PostAdminController extends CrudController class PostAdminController extends CrudController
@ -67,7 +68,7 @@ class PostAdminController extends CrudController
'attr' => ['class' => 'miw-400'], 'attr' => ['class' => 'miw-400'],
]) ])
->setField('index', 'ID', TextField::class, [ ->setField('index', 'ID', TextField::class, [
'property_builder' => function (EntityInterface $entity) { 'property_builder' => function(EntityInterface $entity) {
return sprintf('#%d', $entity->getId()); return sprintf('#%d', $entity->getId());
}, },
'sort' => ['id', '.id'], 'sort' => ['id', '.id'],
@ -84,7 +85,7 @@ class PostAdminController extends CrudController
'format' => 'd/m/Y H:i', 'format' => 'd/m/Y H:i',
'sort' => ['publishedAt', '.publishedAt'], 'sort' => ['publishedAt', '.publishedAt'],
'attr' => ['class' => 'miw-200'], 'attr' => ['class' => 'miw-200'],
'inline_form' => function (FormBuilderInterface $builder) { 'inline_form' => function(FormBuilderInterface $builder) {
$builder->add( $builder->add(
'publishedAt', 'publishedAt',
DateTimeType::class, DateTimeType::class,
@ -106,7 +107,7 @@ class PostAdminController extends CrudController
'view' => 'blog/post_admin/field/status.html.twig', 'view' => 'blog/post_admin/field/status.html.twig',
'sort' => ['status', '.status'], 'sort' => ['status', '.status'],
'attr' => ['class' => 'miw-100'], 'attr' => ['class' => 'miw-100'],
'inline_form' => function (FormBuilderInterface $builder) { 'inline_form' => function(FormBuilderInterface $builder) {
$builder->add( $builder->add(
'status', 'status',
ChoiceType::class, ChoiceType::class,
@ -124,15 +125,15 @@ class PostAdminController extends CrudController
], ],
] ]
); );
}, }
]) ])
->setBatchAction('index', 'delete', 'Delete', function (EntityInterface $entity, EntityManager $manager) { ->setBatchAction('index', 'delete', 'Delete', function(EntityInterface $entity, EntityManager $manager) {
$manager->delete($entity); $manager->delete($entity);
}) })
->setBatchAction('index', 'draft', 'Statut : publier', function (EntityInterface $entity, EntityManager $manager) { ->setBatchAction('index', 'draft', 'Statut : publier', function(EntityInterface $entity, EntityManager $manager) {
$manager->update($entity->setStatus(Post::PUBLISHED)); $manager->update($entity->setStatus(Post::PUBLISHED));
}) })
->setBatchAction('index', 'publish', 'Statut : brouillon', function (EntityInterface $entity, EntityManager $manager) { ->setBatchAction('index', 'publish', 'Statut : brouillon', function(EntityInterface $entity, EntityManager $manager) {
$manager->update($entity->setStatus(Post::DRAFT)); $manager->update($entity->setStatus(Post::DRAFT));
}) })
; ;
@ -151,7 +152,7 @@ class PostAdminController extends CrudController
$factory->create($this->getUser()), $factory->create($this->getUser()),
$entityManager, $entityManager,
$request, $request,
function (Entity $entity, Form $form, Request $request) use ($fileUpload) { function(Entity $entity, Form $form, Request $request) use ($fileUpload) {
$directory = 'uploads/post/'.date('Y'); $directory = 'uploads/post/'.date('Y');
$fileUpload->handleForm( $fileUpload->handleForm(
@ -172,7 +173,7 @@ class PostAdminController extends CrudController
$entity, $entity,
$entityManager, $entityManager,
$request, $request,
function (Entity $entity, Form $form, Request $request) use ($fileUpload) { function(Entity $entity, Form $form, Request $request) use ($fileUpload) {
$directory = 'uploads/post/'.date('Y'); $directory = 'uploads/post/'.date('Y');
$fileUpload->handleForm( $fileUpload->handleForm(
@ -186,7 +187,7 @@ class PostAdminController extends CrudController
); );
} }
#[Route(path: '/inline_edit/{entity}/{context}/{label}', name: 'admin_blog_post_inline_edit', methods: ['GET', 'POST'])] #[Route(path: "/inline_edit/{entity}/{context}/{label}", name: 'admin_blog_post_inline_edit', methods: ['GET', 'POST'])]
public function inlineEdit(string $context, string $label, Entity $entity, EntityManager $entityManager, Request $request): Response public function inlineEdit(string $context, string $label, Entity $entity, EntityManager $entityManager, Request $request): Response
{ {
return $this->doInlineEdit($context, $label, $entity, $entityManager, $request); return $this->doInlineEdit($context, $label, $entity, $entityManager, $request);
@ -267,7 +268,8 @@ class PostAdminController extends CrudController
DateRangeAnalytic $analytic, DateRangeAnalytic $analytic,
NodeRepository $nodeRepository, NodeRepository $nodeRepository,
string $range = '7days' string $range = '7days'
): Response { ): Response
{
if (!in_array($range, ['7days', '30days', '90days', '1year'])) { if (!in_array($range, ['7days', '30days', '90days', '1year'])) {
throw $this->createNotFoundException(); throw $this->createNotFoundException();
} }

View file

@ -20,7 +20,6 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use App\Factory\Blog\PostFollowFactory; use App\Factory\Blog\PostFollowFactory;
use App\Manager\PostFollowManager; use App\Manager\PostFollowManager;
use App\Core\Twig\Extension\EditorJsExtension; use App\Core\Twig\Extension\EditorJsExtension;
use App\Core\Twig\Extension\BuilderExtension;
class PostController extends PageController class PostController extends PageController
{ {
@ -166,11 +165,7 @@ class PostController extends PageController
return $query; return $query;
} }
public function rss( public function rss(PostParser $parser, EditorJsExtension $editorJsExtension): Response
PostParser $parser,
EditorJsExtension $editorJsExtension,
BuilderExtension $builderExtension
): Response
{ {
$entities = $this->createQuery()->paginate(1, 20); $entities = $this->createQuery()->paginate(1, 20);
$items = []; $items = [];
@ -178,8 +173,6 @@ class PostController extends PageController
foreach ($entities as $entity) { foreach ($entities as $entity) {
if ($entity->getContentFormat() === 'editorjs') { if ($entity->getContentFormat() === 'editorjs') {
$description = $editorJsExtension->buildHtml($entity->getContent()); $description = $editorJsExtension->buildHtml($entity->getContent());
} elseif ($entity->getContentFormat() === 'builder') {
$description = $builderExtension->buildHtml($entity->getContent());
} else { } else {
$description = $parser->transformMarkdown($entity->getContent()); $description = $parser->transformMarkdown($entity->getContent());
} }

View file

@ -7,7 +7,6 @@ use App\Core\Entity\Site\Page\FileBlock;
use App\Form\Type\SimpleMdTextareaBlockType; use App\Form\Type\SimpleMdTextareaBlockType;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use App\Form\MarkdownBlockType;
#[ORM\Entity] #[ORM\Entity]
class SimplePage extends TitledPage class SimplePage extends TitledPage
@ -18,7 +17,7 @@ class SimplePage extends TitledPage
$builder->add( $builder->add(
'content', 'content',
MarkdownBlockType::class, SimpleMdTextareaBlockType::class,
[ [
'label' => 'Contenu', 'label' => 'Contenu',
'options' => [ 'options' => [

View file

@ -25,8 +25,6 @@ use App\Form\Type\SimpleMdTextareaType;
use App\Core\Form\Type\EditorJsTextareaType; use App\Core\Form\Type\EditorJsTextareaType;
use App\Core\Form\FileManager\FilePickerType; use App\Core\Form\FileManager\FilePickerType;
use App\Core\Form\Type\CollectionType as MurphCollectionType; use App\Core\Form\Type\CollectionType as MurphCollectionType;
use App\Form\MarkdownType;
use App\Core\Form\Type\BuilderType;
class PostType extends AbstractType class PostType extends AbstractType
{ {
@ -53,7 +51,6 @@ class PostType extends AbstractType
'required' => true, 'required' => true,
'choices' => [ 'choices' => [
'Markdown' => 'markdown', 'Markdown' => 'markdown',
'Builder' => 'builder',
'HTML' => 'html', 'HTML' => 'html',
'Editor JS' => 'editorjs', 'Editor JS' => 'editorjs',
], ],
@ -64,9 +61,8 @@ class PostType extends AbstractType
); );
$types = [ $types = [
'markdown' => MarkdownType::class, 'markdown' => SimpleMdTextareaType::class,
'builder' => BuilderType::class, 'html' => SimpleMdTextareaType::class,
'html' => MarkdownType::class,
'editorjs' => EditorJsTextareaType::class, 'editorjs' => EditorJsTextareaType::class,
]; ];

View file

@ -1,21 +0,0 @@
<?php
namespace App\Form;
use App\Core\Form\Site\Page\TextareaBlockType;
use Symfony\Component\Form\FormBuilderInterface;
class MarkdownBlockType extends TextareaBlockType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'value',
MarkdownType::class,
array_merge([
'required' => false,
'label' => false,
], $options['options']),
);
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class MarkdownType extends TextareaType
{
public function getBlockPrefix()
{
return 'markdown';
}
}

View file

@ -2,9 +2,7 @@
namespace App; namespace App;
use App\Core\DependencyInjection\Compiler\BuilderBlockPass;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
@ -37,9 +35,4 @@ class Kernel extends BaseKernel
(require $path)($routes->withPath($path), $this); (require $path)($routes->withPath($path), $this);
} }
} }
protected function build(ContainerBuilder $container): void
{
$container->addCompilerPass(new BuilderBlockPass());
}
} }

View file

@ -1,8 +0,0 @@
{% extends '@Core/form/bootstrap_4_form_theme.html.twig' %}
{% block markdown_widget %}
<div {% for attr, value in row_attr %}{{ attr }}="{{ value }}" {% endfor %}>
<div class="markdown-editor" data-value="{{ value|json_encode }}" data-name="{{ full_name }}" data-id="{{ id }}">
</div>
</div>
{% endblock %}

View file

@ -55,8 +55,6 @@
{{- post.content|murph_url|file_attributes|post -}} {{- post.content|murph_url|file_attributes|post -}}
{% elseif post.contentFormat == 'markdown' %} {% elseif post.contentFormat == 'markdown' %}
{{- post.content|murph_url|file_attributes|markdown('post')|lazy_load -}} {{- post.content|murph_url|file_attributes|markdown('post')|lazy_load -}}
{% elseif post.contentFormat == 'builder' %}
{{- post.content|block_to_html|lazy_load -}}
{% elseif post.contentFormat == 'editorjs' %} {% elseif post.contentFormat == 'editorjs' %}
{{- post.content|murph_url|file_attributes|editorjs_to_html|raw -}} {{- post.content|murph_url|file_attributes|editorjs_to_html|raw -}}
{% endif %} {% endif %}

8653
yarn.lock

File diff suppressed because it is too large Load diff