diff --git a/.env b/.env index a0667ad..5b6040b 100644 --- a/.env +++ b/.env @@ -35,10 +35,3 @@ MAILER_SENDER=example@localhost ASSET_BASE_URL=null UMAMI_URL=null -MESSENGER_TRANSPORT_DSN=doctrine://default - -INFLUXDB_URL= -INFLUXDB_TOKEN= -INFLUXDB_BUCKET= -INFLUXDB_ORG= -INFLUXDB_DEBUG=1 diff --git a/.mage.yml.dist b/.mage.yml.dist index 1b75320..3992365 100644 --- a/.mage.yml.dist +++ b/.mage.yml.dist @@ -18,7 +18,6 @@ magephp: - "/var/cache/*" - "/var/log/*" - "/public/media" - - "/.secrets" hosts: - ssh_host on-deploy: @@ -26,4 +25,3 @@ magephp: - exec: { cmd: 'make doctrine-migration', desc: 'migration' } - exec: { cmd: 'php8.1 ./bin/console cache:warmup', desc: 'warmup' } - exec: { cmd: 'php8.1 ./bin/console cache:warmup', desc: 'warmup2' } - - exec: { cmd: './bin/messenger -a restart', desc: 'messenger' } diff --git a/.novops.yml b/.novops.yml deleted file mode 100644 index a0a9c25..0000000 --- a/.novops.yml +++ /dev/null @@ -1,39 +0,0 @@ -environments: - build: - variables: - - name: MYSQLDUMP - value: - hvault_kv2: - mount: kv - path: deblan/deblan.io-murph - key: mysqldump - - deploy: - variables: - - name: SSH_USER - value: - hvault_kv2: - mount: kv - path: deblan/deblan.io-murph - key: ssh_user - - - name: SSH_HOST - value: - hvault_kv2: - mount: kv - path: deblan/deblan.io-murph - key: ssh_host - - - name: SSH_PRIV_KEY - value: - hvault_kv2: - mount: kv - path: deblan/deblan.io-murph - key: ssh_priv_key - - - name: APP_DIRECTORY - value: - hvault_kv2: - mount: kv - path: deblan/deblan.io-murph - key: app_directory diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..d59572a --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,118 @@ +pipeline: + db-wait: + image: gitnet.fr/deblan/timeout:latest + 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' + when: + event: [push, pull_request] + + db-create: + image: mariadb:10.3 + secrets: [mysqldump] + commands: + - mysql -hdb -uroot -proot -e "CREATE DATABASE app" + - eval "$MYSQLDUMP" | mysql -hdb -uroot -proot app + when: + branch: [master, master-*, develop, develop-*] + event: [push, pull_request] + + app-config: + image: deblan/php:8.1 + commands: + - echo APP_ENV=prod >> .env.local + - echo APP_SECRET=$(openssl rand -hex 32) >> .env.local + - echo DATABASE_URL=mysql://root:root@db/app >> .env.local + when: + branch: [master, master-*, develop, develop-*] + event: [push, pull_request] + + php-composer: + image: deblan/php:8.1 + commands: + - apt-get update && apt-get -y install git + - composer install --no-scripts + when: + event: [push, pull_request] + + db-migrate: + image: deblan/php:8.1 + environment: + - PHP=php + commands: + - ./bin/doctrine-migrate + when: + branch: [master, master-*, develop, develop-*, feature/*] + event: [push, pull_request] + + app-jsroutes: + image: deblan/php:8.1 + commands: + - php bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json + when: + branch: [master, master-*, develop, develop-*, feature/*] + event: [push, pull_request] + + node-build: + image: node:16-alpine + environment: + - CPU_COUNT=3 + commands: + - apk add --no-cache git + - npm install -g svg2ttf ttf2eot ttf2woff2 + - svg2ttf assets/fonts/deblan/src/deblan-icon.svg assets/fonts/deblan/deblan-icon.ttf + - cat assets/fonts/deblan/deblan-icon.ttf | ttf2woff2 > assets/fonts/deblan/deblan-icon.woff2 + - ttf2eot assets/fonts/deblan/deblan-icon.ttf assets/fonts/deblan/deblan-icon.eot + - yarn + - test -f public/js/fos_js_routes.json || echo "{}" > public/js/fos_js_routes.json + - npm run build + when: + event: [push, pull_request] + + security-check: + image: gitnet.fr/deblan/osv-detector:v0.9 + commands: + - osv-detector composer.lock yarn.lock + failure: ignore + when: + event: [push, pull_request] + + create-artifact: + image: alpine:latest + volumes: + - /var/www/html/artifacts:/var/www/html/artifacts + commands: + - ARTIFACT_PATH="/var/www/html/artifacts/deblan/deblan.io-murph/$CI_COMMIT_BRANCH" + - test -d && rm -fr "$ARTIFACT_PATH" + - mkdir -p "$ARTIFACT_PATH" + - cp -R * .* "$ARTIFACT_PATH" + when: + event: [push, pull_request] + + app-deploy: + image: deblan/php:8.1 + secrets: [ssh_user, ssh_host, ssh_priv_key, app_directory] + volumes: + - /var/www/html/artifacts:/var/www/html/artifacts + commands: + - cd "/var/www/html/artifacts/deblan/deblan.io-murph/$CI_COMMIT_BRANCH" + - ls -lah + - exit 1 + - apt-get update && apt-get -y install rsync openssh-client + - mkdir "$HOME/.ssh" + - echo "$SSH_PRIV_KEY" > "$HOME/.ssh/id_ed25519" + - chmod 700 "$HOME/.ssh" + - chmod 600 "$HOME/.ssh/id_ed25519" + - composer global require andres-montanez/magallanes + - cp .mage.yml.dist .mage.yml + - sed -i "s/ssh_user/$SSH_USER/g" .mage.yml + - sed -i "s/ssh_host/$SSH_HOST/g" .mage.yml + - sed -i "s#app_directory#$APP_DIRECTORY#g" .mage.yml + - /root/.config/composer/vendor/bin/mage deploy "$CI_BUILD_DEPLOY_TARGET" + when: + event: [deployment] + +services: + db: + image: mariadb:10.3 + environment: + - MARIADB_ROOT_PASSWORD=root diff --git a/.woodpecker/build.yml b/.woodpecker/build.yml deleted file mode 100644 index 4f785fe..0000000 --- a/.woodpecker/build.yml +++ /dev/null @@ -1,84 +0,0 @@ -variables: - volumes: &volumes - - node_cache:/root/.npm - - /data/${CI_REPO}:/builds - -when: - event: [push, pull_request, tag, manual] - branch: [master, master-*, develop, develop-*, feature/*] - -steps: - "Wait the database": - image: gitnet.fr/deblan/timeout:latest - 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' - - "Create database": - image: mariadb:10.3 - environment: - MYSQLDUMP: - from_secret: mysqldump - commands: - - mysql -hdb -uroot -proot -e "CREATE DATABASE app" - - eval "$MYSQLDUMP" | mysql -hdb -uroot -proot app - - "Configure app": - image: deblan/php:8.1 - commands: - - echo APP_ENV=prod >> .env.local - - echo APP_SECRET=$(openssl rand -hex 32) >> .env.local - - echo DATABASE_URL=mysql://root:root@db/app >> .env.local - - "Installs PHP dependencies": - image: deblan/php:8.1 - commands: - - apt-get update && apt-get -y install git - - composer install --no-scripts - - "Migrates database": - image: deblan/php:8.3 - environment: - PHP: php - commands: - - ./bin/doctrine-migrate - - "Generates JS routes": - image: deblan/php:8.3 - commands: - - php bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json - - "Build assets": - image: node:20-alpine - environment: - CPU_COUNT: 3 - commands: - - apk add --no-cache git - - npm install -g svg2ttf ttf2eot ttf2woff2 - - svg2ttf assets/fonts/deblan/src/deblan-icon.svg assets/fonts/deblan/deblan-icon.ttf - - cat assets/fonts/deblan/deblan-icon.ttf | ttf2woff2 > assets/fonts/deblan/deblan-icon.woff2 - - ttf2eot assets/fonts/deblan/deblan-icon.ttf assets/fonts/deblan/deblan-icon.eot - - yarn - - test -f public/js/fos_js_routes.json || echo "{}" > public/js/fos_js_routes.json - - npm run build - - "Check dependencies": - image: gitnet.fr/deblan/osv-detector:v0.9 - commands: - - osv-detector composer.lock yarn.lock - failure: ignore - - "Build the cache": - image: deblan/mage - volumes: *volumes - commands: - - cd /builds - - rsync -az "$CI_WORKSPACE/" "$CI_COMMIT_SHA" - -services: - db: - image: mariadb:10.3 - environment: - MARIADB_ROOT_PASSWORD: root - -volumes: - node_cache: diff --git a/.woodpecker/deploy.yml b/.woodpecker/deploy.yml deleted file mode 100644 index e78ac67..0000000 --- a/.woodpecker/deploy.yml +++ /dev/null @@ -1,33 +0,0 @@ -variables: - volumes: &volumes - - /data/${CI_REPO}:/builds - -when: - event: [deployment] - -skip_clone: true - -steps: - "Deploy": - image: deblan/mage - environment: - SSH_PRIV_KEY: - from_secret: ssh_priv_key - SSH_USER: - from_secret: ssh_user - SSH_HOST: - from_secret: ssh_host - APP_DIRECTORY: - from_secret: app_directory - volumes: *volumes - commands: - - cd "/builds/$CI_COMMIT_SHA" - - mkdir "$HOME/.ssh" - - echo "$SSH_PRIV_KEY" > "$HOME/.ssh/id_ed25519" - - chmod 700 "$HOME/.ssh" - - chmod 600 "$HOME/.ssh/id_ed25519" - - cp .mage.yml.dist .mage.yml - - sed -i "s/ssh_user/$SSH_USER/g" .mage.yml - - sed -i "s/ssh_host/$SSH_HOST/g" .mage.yml - - sed -i "s#app_directory#$APP_DIRECTORY#g" .mage.yml - - mage deploy "$CI_PIPELINE_DEPLOY_TARGET" diff --git a/Makefile b/Makefile index 9d32bcc..e352647 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ COMPOSER ?= composer -PHP_BIN ?= php8.1 -YARN_BIN ?= yarn +PHP ?= php8.1 +SSH ?= ssh +YARN ?= yarn NPM_BIN ?= npm all: build @@ -19,10 +20,10 @@ js-routing: doctrine-migration clean: rm -fr var/cache/dev/* rm -fr var/cache/prod/* - $(PHP_BIN) bin/console + $(PHP) bin/console doctrine-migration: - PHP=$(PHP_BIN) ./bin/doctrine-migrate + PHP=$(PHP) ./bin/doctrine-migrate .ONESHELL: lint: diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 3025de7..00c0430 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -1,63 +1,57 @@ @import "../../vendor/murph/murph-core/src/core/Resources/assets/css/admin.scss"; -@import "@kangc/v-md-editor/lib/style/base-editor.css"; -@import "@kangc/v-md-editor/lib/theme/style/vuepress.css"; +@import "~simplemde/dist/simplemde.min.css"; + +.CodeMirror-fullscreen, .editor-toolbar.fullscreen { + z-index: 2000; +} .ejs-link { - margin: 10px auto; - max-width: 80%; - border: 2px solid #333; - border-radius: 5px; + margin: 10px auto; + max-width: 80%; + border: 2px solid #333; + border-radius: 5px; - &--anchor { - display: block; - padding: 30px; - } - - &-content { - display: inline-block; - vertical-align: top; - - &--title { - font-weight: bold; + &--anchor { + display: block; + padding: 30px; } - &--description { - font-size: 15px; + &-content { + 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 { - padding-top: 10px; - font-size: 14px; - line-height: 20px; + $image-size: 85px; + + &--anchor--with-image &-content { + width: calc(100% - $image-size - 5px); + padding-right: 25px; } - } - $image-size: 85px; - - &--anchor--with-image &-content { - width: calc(100% - $image-size - 5px); - padding-right: 25px; - } - - &--image { - display: inline-block; - width: $image-size; - height: $image-size; - 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 { z-index: 3; } - -.v-md-editor { - border: 1px solid $input-border-color; - box-shadow: none; -} - -.v-md-editor--fullscreen { - z-index: 3000; -} diff --git a/assets/css/app.scss b/assets/css/app.scss index 40b8938..81a8b03 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -1,26 +1,29 @@ @tailwind base; - @tailwind components; - @tailwind utilities; @import "app/config"; -@import "app/prism"; +@import 'app/prism'; @import "app/typo"; @import "~tingle.js/src/tingle.css"; @font-face { font-family: "MainFont"; - src: url("../fonts/ubuntu/ubuntu-light.woff2?20211108") format("woff2"), url("../fonts/ubuntu/ubuntu-light.woff?20211108") format("woff"); - - // url('../fonts/atkinson/WOFF2/Atkinson-Hyperlegible-Regular-102a.woff2?20220911') format('woff2'), - // url('../fonts/atkinson/WOFF/Atkinson-Hyperlegible-Regular-102.woff?20211108w20220911') format('woff'); + src: + url('../fonts/ubuntu/ubuntu-light.woff2?20211108') format('woff2'), + url('../fonts/ubuntu/ubuntu-light.woff?20211108') format('woff'); + // url('../fonts/atkinson/WOFF2/Atkinson-Hyperlegible-Regular-102a.woff2?20220911') format('woff2'), + // url('../fonts/atkinson/WOFF/Atkinson-Hyperlegible-Regular-102.woff?20211108w20220911') format('woff'); } @font-face { font-family: "deblan-icon"; - src: url("../fonts/deblan/deblan-icon.eot?20211108"); - src: url("../fonts/deblan/deblan-icon.woff2?20211108") format("woff2"), url("../fonts/deblan/deblan-icon.woff?20211108") format("woff"), url("../fonts/deblan/deblan-icon.ttf?20211108") format("truetype"); + src: url('../fonts/deblan/deblan-icon.eot?20211108'); + src: + url('../fonts/deblan/deblan-icon.woff2?20211108') format('woff2'), + url('../fonts/deblan/deblan-icon.woff?20211108') format('woff'), + url('../fonts/deblan/deblan-icon.ttf?20211108') format('truetype'); + font-style: normal; font-weight: normal; text-rendering: optimizeLegibility; @@ -58,7 +61,7 @@ $dicons: coffee server search project share contact list response twitter diaspo } .text-right { - text-align: right; + text-align: right; } .list--inline { @@ -154,9 +157,8 @@ pre[class*="language-"] { height: 50px; overflow: hidden; display: inline-block; - margin-bottom: -19px; + margin-bottom: -19px;i - i &:active, &:focus { background: none; } @@ -171,7 +173,6 @@ pre[class*="language-"] { background: url(../images/Refresh_icon.svg); } } - // // &-captcha { // label { @@ -303,11 +304,9 @@ pre[class*="language-"] { 0% { background-position: 0 0%; } - 50% { background-position: 0 75%; } - 100% { background-position: 0 0%; } @@ -348,20 +347,18 @@ pre[class*="language-"] { width: 100%; height: 10px; background: rgb(0, 0, 0); - background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(255, 255, 255, 0) 100%); + background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(255,255,255,0) 100%); } @keyframes HeaderGradient { 0% { - background-position: 0 50%; + background-position: 0 50% } - 50% { - background-position: 100% 50%; + background-position: 100% 50% } - 100% { - background-position: 0 50%; + background-position: 0 50% } } @@ -414,9 +411,6 @@ pre[class*="language-"] { .h1 { font-weight: normal; font-size: 40px; - font-family: MainFont; - text-shadow: none; - color: hsla(0, 0%, 100%, 0.7); } .h3 { @@ -478,7 +472,7 @@ pre[class*="language-"] { } p a:not(.btn), ul:not(.btn-group) a:not(.btn) { - background: url("../images/link.svg") bottom left repeat-x; + background: url('../images/link.svg') bottom left repeat-x; padding-bottom: 5px; } @@ -509,35 +503,6 @@ pre[class*="language-"] { @include make-pre-code; } - &.mermaid { - box-shadow: none; - background: #343c53; - border: 0; - - text, tspan { - fill: #fff !important; - } - - .actor, .noteText { - text, tspan { - fill: #333 !important; - } - } - - .labelText { - fill: #333 !important; - } - - line, path { - stroke: #fff !important; - } - - svg { - display: block; - margin: auto; - } - } - &.with-title { margin-top: 0; border-top-right-radius: 0; @@ -548,41 +513,11 @@ pre[class*="language-"] { padding-bottom: 10px; padding-top: 10px; border: 1px solid $color-code-border; - // overflow: hidden; // // &:hover { // overflow: auto; // } - - } - } -} - -.post-author-wrapper { - .post-author-avatar { - vertical-align: top; - width: 100px; - padding: 10px; - display: inline-block; - } - - .post-author { - display: inline-block; - width: calc(100% - 100px); - padding: 10px 10px 10px 30px; - } - - @media screen and (max-width: 774px) { - .post-author-avatar { - display: block; - margin: auto; - } - - .post-author { - display: block; - width: 100%; - padding-right: 20px; } } } @@ -642,14 +577,12 @@ pre[class*="language-"] { @for $i from 1 through 6 { .review.offset-#{$i} { margin-left: 5% * $i - 1%; - width: 100% - $i * 5%; + width: 100% - ($i * 5%); } } .review { width: 100%; - max-width: calc($content-max-width - 60px - 2rem); - overflow: auto; .review-avatar, .review-avatar img { width: 60px; @@ -665,7 +598,7 @@ pre[class*="language-"] { border: 1px solid $color-hr-border; .review-content p { - margin-top: 0; + margin-top: 0; } > ul { @@ -730,7 +663,7 @@ pre[class*="language-"] { .code-window { height: 50px; - background: $color-code-title-background url("../images/window.svg") no-repeat center right; + background: $color-code-title-background url('../images/window.svg') no-repeat center right; padding-left: 15px; font-family: Monospace; color: #ccc; @@ -764,8 +697,7 @@ pre[class*="language-"] { width: 100%; height: 450px; background-position: center center; - background: #f2f2f2 url("../images/quick-post-load.png") no-repeat center center; - + background: #f2f2f2 url('../images/quick-post-load.png') no-repeat center center; // border: 2px solid $color-very-light-grey; border-bottom: 0; cursor: pointer; @@ -904,7 +836,19 @@ pre[class*="language-"] { border: 1px solid $color-white; } -$links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, github: #8cc345, code: #51d066, mastodon: #2984d2, pixelfed: #e72151, matrix: #1a588a, gpg: #42a73b, murph: #19b4db); +$links: ( + twitter: #20b8ff, + rss: #fd9f13, + linkedin: #006699, + diaspora: #90b92e, + github: #8cc345, + code: #51d066, + mastodon: #2984d2, + pixelfed: #e72151, + matrix: #1a588a, + gpg: #42a73b, + murph: #19b4db +); @each $site, $bg in $links { .link-#{$site} { @@ -1007,29 +951,25 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g } @keyframes bounceIn { - 0% { + 0%{ opacity: 0; } - - 50% { + 50%{ opacity: 0.9; } - - 80% { + 80%{ opacity: 1; } - - 100% { + 100%{ opacity: 1; } } @keyframes knmc { - 0% { - left: -256px; + 0%{ + left: -256px;; } - - 100% { + 100%{ left: 150vw; } } @@ -1134,8 +1074,6 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g .ejs-link { margin: 10px auto; - width: 80%; - margin-bottom: 20px; &--anchor { display: block; @@ -1260,8 +1198,6 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g } .ejs-link { - width: auto; - &-content { display: block; width: 100% !important; @@ -1335,13 +1271,13 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g } .invalid-feedback { - color: red; - padding-left: 10px; - padding-right: 10px; + color: red; + padding-left: 10px; + padding-right: 10px; - .form-error-icon { - display: none; - } + .form-error-icon { + display: none; + } } @media (prefers-color-scheme: dark) { @@ -1379,7 +1315,7 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g } .header-shadow { - background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(255, 255, 255, 0) 100%); + background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(255,255,255,0) 100%); } } @@ -1392,18 +1328,3 @@ $links: (twitter: #20b8ff, rss: #fd9f13, linkedin: #006699, diaspora: #90b92e, g } } } - -.deprecated { - color: #fff; - background: #3abff8; - padding: 1rem; - border-radius: var(--rounded-box, 1rem); - text-align: center; - - svg { - display: inline-block; - height: 25px; - vertical-align: top; - margin-right: 8px; - } -} diff --git a/assets/css/app/alert.scss b/assets/css/app/alert.scss index d63e072..e4cb112 100644 --- a/assets/css/app/alert.scss +++ b/assets/css/app/alert.scss @@ -1,34 +1,34 @@ .alert { - padding: 20px; - border: 1px solid #333; + padding: 20px; + border: 1px solid #333; - &-success { - border-color: #9db024; - background: #c6ff69; - color: #415f29; - } + &-success { + border-color: #9db024; + background: #c6ff69; + color: #415f29; + } - &-notice { - border-color: $color-blue; - background: #66e6ff; - color: #254e5f; - } + &-notice { + border-color: $color-blue; + background: #66e6ff; + color: #254e5f; + } - &-warning { - border-color: #b07f29; - background: #ffd465; - color: #5f4520; - } + &-warning { + border-color: #b07f29; + background: #ffd465; + color: #5f4520; + } - &-error { - border-color: #b02e2a; - background: #ff6363; - color: #5f2521; - } + &-error { + border-color: #b02e2a; + background: #ff6363; + color: #5f2521; + } - &-notice-light { - border-color: $color-blue; - background: #d9fffc; - color: #254e5f; - } + &-notice-light { + border-color: $color-blue; + background: #d9fffc; + color: #254e5f; + } } diff --git a/assets/css/app/config.scss b/assets/css/app/config.scss index a633f7c..9ed0c22 100644 --- a/assets/css/app/config.scss +++ b/assets/css/app/config.scss @@ -62,7 +62,6 @@ $color-code-text: #f8f8f2; $color-code-mark-background: $color-light-blue; $color-code-title-background: #1d2231; $color-code-title-text: #e0e0e0; - /* --- */ :root { diff --git a/assets/css/app/prism.scss b/assets/css/app/prism.scss index 07f5199..1def76e 100644 --- a/assets/css/app/prism.scss +++ b/assets/css/app/prism.scss @@ -8,59 +8,61 @@ https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clik code[class*="language-"], pre[class*="language-"] { - color: #f8f8f2; - background: none; - text-shadow: 0 1px rgba(0, 0, 0, 0.3); - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - font-size: 1em; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; + color: #f8f8f2; + background: none; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; } /* Code blocks */ pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; - border-radius: 0.3em; + padding: 1em; + margin: .5em 0; + overflow: auto; + border-radius: 0.3em; } :not(pre) > code[class*="language-"], pre[class*="language-"] { - background: #272822; + background: #272822; } /* Inline code */ :not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; + padding: .1em; + border-radius: .3em; + white-space: normal; } .token.comment, .token.prolog, .token.doctype, .token.cdata { - color: #8292a2; + color: #8292a2; } .token.punctuation { - color: #f8f8f2; + color: #f8f8f2; } .token.namespace { - opacity: .7; + opacity: .7; } .token.property, @@ -68,12 +70,12 @@ pre[class*="language-"] { .token.constant, .token.symbol, .token.deleted { - color: #f92672; + color: #f92672; } .token.boolean, .token.number { - color: #ae81ff; + color: #ae81ff; } .token.selector, @@ -82,7 +84,7 @@ pre[class*="language-"] { .token.char, .token.builtin, .token.inserted { - color: #a6e22e; + color: #a6e22e; } .token.operator, @@ -91,34 +93,34 @@ pre[class*="language-"] { .language-css .token.string, .style .token.string, .token.variable { - color: #f8f8f2; + color: #f8f8f2; } .token.atrule, .token.attr-value, .token.function, .token.class-name { - color: #e6db74; + color: #e6db74; } .token.keyword { - color: #66d9ef; + color: #66d9ef; } .token.regex, .token.important { - color: #fd971f; + color: #fd971f; } .token.important, .token.bold { - font-weight: bold; + font-weight: bold; } - .token.italic { - font-style: italic; + font-style: italic; } .token.entity { - cursor: help; + cursor: help; } + diff --git a/assets/css/app/typo.scss b/assets/css/app/typo.scss index 7873701..f30e27b 100644 --- a/assets/css/app/typo.scss +++ b/assets/css/app/typo.scss @@ -16,35 +16,34 @@ // } // .h1, h1 { - font-size: 3.2rem; - line-height: 1.32; + font-size: 3.2rem; + line-height: 1.32 } .h2, h2 { - font-size: 2.6rem; - line-height: 1.35; + font-size: 2.6rem; + line-height: 1.35 } .h3, h3 { - font-size: 2.0rem; - line-height: 1.45; + font-size: 2.0rem; + line-height: 1.45 } .h4, h4 { - font-size: 1.4rem; - line-height: 1.6; + font-size: 1.4rem; + line-height: 1.6 } .h5, h5 { - font-size: 1.1rem; - line-height: 1.75; + font-size: 1.1rem; + line-height: 1.75 } .h6, h6 { - font-size: 1.0rem; - line-height: 1.9; + font-size: 1.0rem; + line-height: 1.9 } - // // p { // margin-top: 17px; @@ -57,6 +56,7 @@ // } // } + .h1, .h2, .h3, @@ -69,7 +69,8 @@ h3, h4, h5, h6 { - font-weight: 600; - margin-bottom: 1rem; - margin-top: 0; + font-weight: 600; + margin-bottom: 1rem; + margin-top: 0 } + diff --git a/assets/css/viewer.scss b/assets/css/viewer.scss index 87c8b23..39b600b 100644 --- a/assets/css/viewer.scss +++ b/assets/css/viewer.scss @@ -1,10 +1,10 @@ body { - margin: 0; - padding: 0; - overflow: hidden; + margin: 0; + padding: 0; + overflow: hidden; } #mesh-viewer { - width: 100vw; - height: 100vh; + width: 100vw; + height: 100vh; } diff --git a/assets/js/admin.js b/assets/js/admin.js index 0b31647..9e22dfb 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -1,6 +1,6 @@ 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 Sortable = require('sortablejs').Sortable diff --git a/assets/js/admin_modules/md-editor.js b/assets/js/admin_modules/md-editor.js deleted file mode 100644 index 7e20b97..0000000 --- a/assets/js/admin_modules/md-editor.js +++ /dev/null @@ -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: ` -
Chargement en cours…
' - } - - const content = document.querySelector('#user_comment_content').value - const httpRequest = new XMLHttpRequest() - - httpRequest.onreadystatechange = function (data) { - if (httpRequest.readyState === 4 && httpRequest.status === 200) { - const json = JSON.parse(httpRequest.response) - previewRender.innerHTML = json.render - document.location.href = '#preview' + for (let i = 0, len = answerButtons.length; i < len; i++) { + answerButtons[i].addEventListener('click', function(e) { + parentCommentIdField.value = e.target.getAttribute('data-answer') + toogleAnswerAlert() + }, false) } - } - httpRequest.open('POST', Routing.generate('api_blog_comment_preview')) - httpRequest.setRequestHeader( - 'Content-Type', - 'application/x-www-form-urlencoded' - ) - httpRequest.send('content=' + encodeURIComponent(content)) - }, false) - } + cancelAnswerButton.addEventListener('click', function(e) { + e.preventDefault() - imagesEvents () { - const document = this.window.document - let isFullscreen = false - const images = document.querySelectorAll('.body img') - - const handleClick = function (image) { - if (isFullscreen) { - if (document.exitFullscreen) { - document.exitFullscreen() - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen() - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen() - } - } else { - if (image.requestFullscreen) { - image.requestFullscreen() - } else if (image.webkitRequestFullscreen) { - image.webkitRequestFullscreen() - } else if (image.mozRequestFullScreen) { - image.mozRequestFullScreen() - } - } - - isFullscreen = !isFullscreen - } - - for (let i = 0, len = images.length; i < len; i++) { - const image = images[i] - - if (image.parentNode.tagName === 'A') { - continue - } - - (function (i) { - i.addEventListener('click', function () { - handleClick(i) + parentCommentIdField.value = null + toogleAnswerAlert() }, false) - })(image) - } - } - init () { - this.commentsEvents() - this.imagesEvents() - } + const previewButton = document.querySelector('.preview-button') + const previewRender = document.querySelector('#preview') + + previewButton.addEventListener('click', function() { + if (previewRender.innerHTML === '') { + previewRender.innerHTML = 'Chargement en cours…
' + } + + const content = document.querySelector('#user_comment_content').value + const httpRequest = new XMLHttpRequest() + + httpRequest.onreadystatechange = function(data) { + if (httpRequest.readyState === 4 && httpRequest.status === 200) { + const json = JSON.parse(httpRequest.response) + previewRender.innerHTML = json.render + document.location.href = '#preview' + } + } + + httpRequest.open('POST', Routing.generate('api_blog_comment_preview')) + httpRequest.setRequestHeader( + 'Content-Type', + 'application/x-www-form-urlencoded' + ) + httpRequest.send('content=' + encodeURIComponent(content)) + }, false) + } + + imagesEvents() { + const document = this.window.document + let isFullscreen = false + const images = document.querySelectorAll('.body img') + + const handleClick = function(image) { + if (isFullscreen) { + if (document.exitFullscreen) { + document.exitFullscreen() + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen() + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen() + } + } else { + if (image.requestFullscreen) { + image.requestFullscreen() + } else if (image.webkitRequestFullscreen) { + image.webkitRequestFullscreen() + } else if (image.mozRequestFullScreen) { + image.mozRequestFullScreen() + } + } + + isFullscreen = !isFullscreen + } + + for (let i = 0, len = images.length; i < len; i++) { + const image = images[i] + + if (image.parentNode.tagName === 'A') { + continue + } + + (function(i) { + i.addEventListener('click', function() { + handleClick(i) + }, false) + })(image) + } + } + + init() { + this.commentsEvents() + this.imagesEvents() + } } module.exports = Post diff --git a/assets/js/app/px-image.js b/assets/js/app/px-image.js index da59baf..fa77d1b 100644 --- a/assets/js/app/px-image.js +++ b/assets/js/app/px-image.js @@ -1,34 +1,34 @@ class PxImage { - constructor (w) { - this.window = w - } - - init () { - const doc = this.window.document - - const images = doc.querySelectorAll('.quick-image img, .card figure img') - - for (let i = 0, len = images.length; i < len; i++) { - ((image) => { - const source = image.getAttribute('data-src') - const sourceError = image.getAttribute('data-src-error') - const color = image.getAttribute('data-color') - const loader = new Image() - - loader.onload = () => { - image.style.background = `${color || null} url(${source})` - image.style.backgroundSize = 'cover' - image.style.backgroundPosition = 'center' - } - - loader.onerror = () => { - image.style.background = `${color || null} url('${sourceError}') center center` - } - - loader.src = source - })(images[i]) + constructor(w) { + this.window = w + } + + init() { + const doc = this.window.document + + const images = doc.querySelectorAll('.quick-image img, .card figure img') + + for (let i = 0, len = images.length; i < len; i++) { + ((image) => { + const source = image.getAttribute('data-src') + const sourceError = image.getAttribute('data-src-error') + const color = image.getAttribute('data-color') + const loader = new Image() + + loader.onload = () => { + image.style.background = `${color ? color : null} url(${source})` + image.style.backgroundSize = 'cover' + image.style.backgroundPosition = 'center' + } + + loader.onerror = () => { + image.style.background = `${color ? color : null} url('${sourceError}') center center` + } + + loader.src = source + })(images[i]) + } } - } } module.exports = PxImage diff --git a/assets/js/app/small-menu.js b/assets/js/app/small-menu.js index 0f06f81..7629fc9 100644 --- a/assets/js/app/small-menu.js +++ b/assets/js/app/small-menu.js @@ -1,24 +1,24 @@ const Routing = require('./routing') class SmallMenu { - constructor(w) { - this.window = w - } + constructor(w) { + this.window = w + } - addEvent() { - const document = this.window.document - const menu = document.querySelector('.small-menu') - const opener = document.querySelector('.menu-opener') + addEvent() { + const document = this.window.document + const menu = document.querySelector('.small-menu') + const opener = document.querySelector('.menu-opener') - opener.addEventListener('click', () => { - menu.classList.toggle('is-open') - opener.classList.toggle('is-open') - }) - } + opener.addEventListener('click', () => { + menu.classList.toggle('is-open') + opener.classList.toggle('is-open') + }) + } - init() { - this.addEvent() - } + init() { + this.addEvent() + } } module.exports = SmallMenu diff --git a/assets/js/app/stats.js b/assets/js/app/stats.js index 9cf8f2a..969018d 100644 --- a/assets/js/app/stats.js +++ b/assets/js/app/stats.js @@ -1,19 +1,19 @@ class Stats { - init() { - (function(f, a, t, h, o, m) { - a[h] = a[h] || function() { - (a[h].q = a[h].q || []).push(arguments) - } - o = f.createElement('script'), - m = f.getElementsByTagName('script')[0] - o.async = 1; - o.src = t; - o.id = 'fathom-script' - m.parentNode.insertBefore(o, m) - })(document, window, '//ftm.deblan.org/tracker.js', 'fathom') - fathom('set', 'siteId', 'HQAWS') - fathom('trackPageview') - } + init() { + (function(f, a, t, h, o, m) { + a[h] = a[h] || function() { + (a[h].q = a[h].q || []).push(arguments) + } + o = f.createElement('script'), + m = f.getElementsByTagName('script')[0] + o.async = 1; + o.src = t; + o.id = 'fathom-script' + m.parentNode.insertBefore(o, m) + })(document, window, '//ftm.deblan.org/tracker.js', 'fathom') + fathom('set', 'siteId', 'HQAWS') + fathom('trackPageview') + } } module.exports = Stats diff --git a/assets/js/app/video-ratio.js b/assets/js/app/video-ratio.js index 96aff4d..27da274 100644 --- a/assets/js/app/video-ratio.js +++ b/assets/js/app/video-ratio.js @@ -1,15 +1,15 @@ class VideoRatio { - constructor (w) { - this.window = w - } - - init () { - const videos = this.window.document.querySelectorAll('.video-ratio') - - for (let i = 0, len = videos.length; i < len; i++) { - videos[i].style.paddingBottom = videos[i].getAttribute('data-ratio') + constructor(w) { + this.window = w + } + + init() { + const videos = this.window.document.querySelectorAll('.video-ratio') + + for (let i = 0, len = videos.length; i < len; i++) { + videos[i].style.paddingBottom = videos[i].getAttribute('data-ratio') + } } - } } module.exports = VideoRatio diff --git a/assets/js/viewer.js b/assets/js/viewer.js index 2742df1..ca2a888 100644 --- a/assets/js/viewer.js +++ b/assets/js/viewer.js @@ -2,11 +2,10 @@ import '../css/viewer.scss' const container = document.getElementById('mesh-viewer') const viewer = new StlViewer( - container, { + container, + { auto_rotate: true, allow_drag_and_drop: true, - models: [{ - filename: container.getAttribute('data-file') - }] + models: [{ filename: container.getAttribute('data-file') }] } ) diff --git a/assets/webapp/favicon.svg b/assets/webapp/favicon.svg deleted file mode 100644 index d31734c..0000000 --- a/assets/webapp/favicon.svg +++ /dev/null @@ -1,85 +0,0 @@ - - diff --git a/bin/messenger b/bin/messenger deleted file mode 100755 index 525afc9..0000000 --- a/bin/messenger +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/sh - -set -eu - -usage() { - printf "Usage: %s [-l DEBUG_LEVEL] [-h] start|stop|restart\n" "$0" -} - -help() { - cat << EOH - SYNOPSIS - $0 [-l DEBUG_LEVEL] [-h] -a start|stop|restart - - DESCRIPTION - - $0 manages symfony messenger - - OPTIONS - - -h Show this help - - -l debug|info|notice|warning|error - Debug level - - -a start|stop|restart|status -EOH -} - -on_interrupt() { - log -l notice "" - log -l notice "Process aborted!" - - exit 130 -} - -start_messenger() { - nohup php8.1 bin/console messenger:consume 2>/dev/null >/dev/null & - log -t -l notice "Started" -} - -stop_messenger() { - php8.1 bin/console messenger:stop-workers 2>/dev/null >/dev/null - log -t -l notice "Stopped" -} - -get_pid() { - pgrep -f messenger:consume -} - -main() { - cd "$(dirname "0")" - - ACTION= - - while getopts "l:ha:" option; do - case "${option}" in - h) help; exit 0;; - l) LOG_VERBOSE="$OPTARG";; - a) ACTION="$OPTARG";; - ?) log -l error "$(usage)"; exit 1;; - esac - done - - if [ "$ACTION" = "start" ]; then - start_messenger - elif [ "$ACTION" = "stop" ]; then - stop_messenger - elif [ "$ACTION" = "restart" ]; then - stop_messenger - start_messenger - elif [ "$ACTION" = "status" ]; then - get_pid - else - log -l error "Action is required." - fi - - exit 0 -} - -log() { - LOG_VERBOSE="${LOG_VERBOSE:-info}" - LEVEL=info - TIME= - - while getopts "tl:" option; do - case "${option}" in - l) LEVEL="$OPTARG"; shift $((OPTIND-1));; - t) TIME="$(printf "[%s] " "$(date +'%Y-%m-%dT%H:%M:%S.%s')")"; shift $((OPTIND-1));; - *) exit 1;; - esac - done - - if [ -t 2 ] && [ -z "${NO_COLOR-}" ]; then - case "${LEVEL}" in - debug) COLOR="$(tput setaf 3)";; - notice) COLOR="$(tput setaf 4)";; - warning) COLOR="$(tput setaf 5)";; - error) COLOR="$(tput setaf 1)";; - *) COLOR="$(tput sgr0)";; - esac - fi - - case "${LEVEL}" in - debug) LEVEL=100;; - notice) LEVEL=250;; - warning) LEVEL=300;; - error) LEVEL=400;; - *) LEVEL=200;; - esac - - case "${LOG_VERBOSE}" in - debug) LOG_VERBOSE_VALUE=100;; - notice) LOG_VERBOSE_VALUE=250;; - warning) LOG_VERBOSE_VALUE=300;; - error) LOG_VERBOSE_VALUE=400;; - *) LOG_VERBOSE_VALUE=200;; - esac - - if [ $LEVEL -ge $LOG_VERBOSE_VALUE ]; then - printf "%s\n" "$*" | while IFS='' read -r LINE; do - printf "%s%s%s\n" "${COLOR:-}" "${TIME:-}" "$LINE" >&2 - done - fi -} - -trap on_interrupt INT - -main "$@" - diff --git a/composer.json b/composer.json index 9f8b4a7..c4c73a4 100644 --- a/composer.json +++ b/composer.json @@ -8,12 +8,9 @@ "beberlei/doctrineextensions": "^1.3", "friendsofsymfony/jsrouting-bundle": "^2.7", "gregwar/captcha-bundle": "^2.2", - "guzzlehttp/guzzle": "^7.8", - "influxdata/influxdb-client-php": "^3.4", "knplabs/knp-markdown-bundle": "^1.9", "knplabs/knp-menu-bundle": "^3.1", - "murph/murph-core": "dev-master", - "symfony/messenger": "5.4.*", + "murph/murph-core": "^1.18", "twig/intl-extra": "^3.5" }, "require-dev": { @@ -34,8 +31,7 @@ "sort-packages": true, "allow-plugins": { "symfony/flex": true, - "symfony/runtime": true, - "php-http/discovery": true + "symfony/runtime": true } }, "autoload": { diff --git a/config/packages/app.yaml b/config/packages/app.yaml index 7287936..8b0d1ad 100644 --- a/config/packages/app.yaml +++ b/config/packages/app.yaml @@ -1,7 +1,7 @@ core: site: name: "Blog" - logo: "build/webapp/favicon.svg" + logo: "build/images/core/logo.svg" controllers: - {name: 'LinkController:links', action: 'App\Controller\LinkController:links'} - {name: 'ContactController::contact', action: 'App\Controller\ContactController::contact'} @@ -81,7 +81,6 @@ core: - image/jpg - image/jpeg - image/gif - - image/webp - image/svg+xml - video/mp4 - audio/mpeg3 diff --git a/config/packages/liip_imagine.yaml b/config/packages/liip_imagine.yaml index 157b0a7..e3cd592 100644 --- a/config/packages/liip_imagine.yaml +++ b/config/packages/liip_imagine.yaml @@ -13,21 +13,18 @@ liip_imagine: max: [600, 600] crop: size: [600, 270] - start: [0, 0] project_preview_filter: filters: downscale: max: [600, 600] crop: size: [600, 270] - start: [0, 0] post_preview_filter: filters: downscale: max: [600, 600] crop: size: [600, 300] - start: [0, 0] site_avatar: filters: downscale: diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml deleted file mode 100644 index ce96395..0000000 --- a/config/packages/messenger.yaml +++ /dev/null @@ -1,7 +0,0 @@ -framework: - messenger: - transports: - async: "%env(MESSENGER_TRANSPORT_DSN)%" - - routing: - 'App\Message\PageViewMessage': async diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 9e21266..e402952 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -1,6 +1,6 @@ twig: 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 paths: '%kernel.project_dir%/templates/core/': Core diff --git a/config/services.yaml b/config/services.yaml index 2fde6d0..832f63b 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -4,11 +4,6 @@ # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: - influxdb_url: '%env(INFLUXDB_URL)%' - influxdb_token: '%env(INFLUXDB_TOKEN)%' - influxdb_bucket: '%env(INFLUXDB_BUCKET)%' - influxdb_org: '%env(INFLUXDB_ORG)%' - influxdb_debug: '%env(INFLUXDB_DEBUG)%' services: # default configuration for services in *this* file @@ -52,14 +47,6 @@ services: resource: '../src/Controller/' tags: ['controller.service_arguments'] - App\Api\InfluxDB: - arguments: - $url: '%influxdb_url%' - $token: '%influxdb_token%' - $bucket: '%influxdb_bucket%' - $org: '%influxdb_org%' - $debug: '%influxdb_debug%' - site.route_loader: class: App\Core\Router\SiteRouteLoader tags: [routing.loader] @@ -82,9 +69,5 @@ services: tags: - {name: markdown.parser, alias: comment} - App\EventListener\StatListener: - tags: - - { name: kernel.event_listener, event: kernel.request } - # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones diff --git a/package.json b/package.json index 4eb7cdd..cd6f247 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,13 @@ "build": "./node_modules/.bin/encore production" }, "dependencies": { - "@kangc/v-md-editor": "^1.7.12", "daisyui": "^2.31.0", - "editorjs-hyperlink": "^1.0.6", - "editorjs-inline-tool": "^0.4.0", "encore": "^0.0.30-beta", "lozad": "^1.16.0", - "mermaid": "^11.0.2", - "murph-project": "^1.9.4", + "murph-project": "^1", "particles.js": "^2.0.0", "prismjs": "^1.23.0", + "simplemde": "^1.11.2", "tingle.js": "^0.16.0", "vanillajs-datepicker": "^1.1.4", "vue": "^2.6.14" @@ -28,6 +25,5 @@ "postcss": "^8.4.16", "postcss-loader": "^7.0.1", "tailwindcss": "^3.1.8" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } diff --git a/src/Analytic/DateRangeAnalytic.php b/src/Analytic/DateRangeAnalytic.php index 7e34011..bf5bb89 100644 --- a/src/Analytic/DateRangeAnalytic.php +++ b/src/Analytic/DateRangeAnalytic.php @@ -29,7 +29,7 @@ class DateRangeAnalytic extends BaseDateRangeAnalytic foreach ($entities as $key => $entity) { if ('view' === $type) { - if (null === $this->path || str_starts_with($entity->getPath(), $this->path)) { + if ($this->path === null || str_starts_with($entity->getPath(), $this->path)) { $newEntities[] = $entity; } } diff --git a/src/Api/InfluxDB.php b/src/Api/InfluxDB.php deleted file mode 100644 index afe854f..0000000 --- a/src/Api/InfluxDB.php +++ /dev/null @@ -1,46 +0,0 @@ - - */ -class InfluxDB -{ - protected ?Client $client = null; - - public function __construct( - protected ?string $url, - protected ?string $token, - protected ?string $bucket, - protected ?string $org, - protected bool $debug = false - ) { - if (isset($this->url, $this->token, $this->bucket, $this->org)) { - $this->client = new Client([ - 'url' => $this->url, - 'token' => $this->token, - 'bucket' => $this->bucket, - 'org' => $this->org, - 'debug' => $this->debug, - 'precision' => WritePrecision::S, - 'timeout' => 1, - ]); - } - } - - public function isAvailable(): bool - { - return null !== $this->getClient(); - } - - public function getClient(): ?Client - { - return $this->client; - } -} diff --git a/src/Api/TTRssClient.php b/src/Api/TTRssClient.php index c5cad19..7c538cc 100644 --- a/src/Api/TTRssClient.php +++ b/src/Api/TTRssClient.php @@ -14,7 +14,7 @@ class TTRssClient $result = @file_get_contents('https://tiny.deblan.org/deblan_api/?itemsPerPage=10&page='.$page); if ($result) { - $result = str_replace('\u0092', "'", $result); + $result = str_replace('\\u0092', "'", $result); $result = str_replace(''', "'", $result); return json_decode($result, true); diff --git a/src/Controller/Blog/CategoryAdminController.php b/src/Controller/Blog/CategoryAdminController.php index 96e52f5..008ccba 100644 --- a/src/Controller/Blog/CategoryAdminController.php +++ b/src/Controller/Blog/CategoryAdminController.php @@ -43,7 +43,6 @@ class CategoryAdminController extends CrudController ->setMaxPerPage('index', 100) ->setView('form', 'blog/category_admin/_form.html.twig') - ->setDoubleClick('index', true) ->setDefaultSort('index', 'title', 'asc') diff --git a/src/Controller/Blog/PostAdminController.php b/src/Controller/Blog/PostAdminController.php index df78833..41d7308 100644 --- a/src/Controller/Blog/PostAdminController.php +++ b/src/Controller/Blog/PostAdminController.php @@ -2,30 +2,27 @@ namespace App\Controller\Blog; -use App\Analytic\DateRangeAnalytic; use App\Core\Controller\Admin\Crud\CrudController; use App\Core\Crud\CrudConfiguration; use App\Core\Crud\Field\DatetimeField; use App\Core\Crud\Field\TextField; -use App\Core\Entity\EntityInterface; use App\Core\Form\FileUploadHandler; 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\Factory\Blog\PostFactory as EntityFactory; use App\Form\Blog\Filter\PostFilterType; use App\Form\Blog\PostType; +use App\Form\Blog\PostType as EntityType; 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\Response; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Validator\Constraints\NotBlank; +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; #[Route(path: '/admin/blog/post')] class PostAdminController extends CrudController @@ -40,7 +37,6 @@ class PostAdminController extends CrudController ->setPageRoute('index', 'admin_blog_post_index') ->setPageRoute('edit', 'admin_blog_post_edit') - ->setPageRoute('inline_edit', 'admin_blog_post_inline_edit') ->setPageRoute('new', 'admin_blog_post_new') ->setPageRoute('show', 'admin_blog_post_show') ->setPageRoute('delete', 'admin_blog_post_delete') @@ -58,7 +54,6 @@ class PostAdminController extends CrudController ->setView('edit', 'blog/post_admin/edit.html.twig') ->setView('show', 'blog/post_admin/show.html.twig') ->setView('index', 'blog/post_admin/index.html.twig') - ->setDoubleClick('index', true) ->setDefaultSort('index', 'id', 'desc') ->setField('index', 'Titre', TextField::class, [ @@ -67,7 +62,7 @@ class PostAdminController extends CrudController 'attr' => ['class' => 'miw-400'], ]) ->setField('index', 'ID', TextField::class, [ - 'property_builder' => function (EntityInterface $entity) { + 'property_builder' => function(EntityInterface $entity) { return sprintf('#%d', $entity->getId()); }, 'sort' => ['id', '.id'], @@ -84,55 +79,19 @@ class PostAdminController extends CrudController 'format' => 'd/m/Y H:i', 'sort' => ['publishedAt', '.publishedAt'], 'attr' => ['class' => 'miw-200'], - 'inline_form' => function (FormBuilderInterface $builder) { - $builder->add( - 'publishedAt', - DateTimeType::class, - [ - 'label' => 'Date de publication', - 'required' => false, - 'html5' => true, - 'widget' => 'single_text', - 'attr' => [ - 'data-datetime' => '', - ], - 'constraints' => [ - ], - ] - ); - }, ]) ->setField('index', 'Status', TextField::class, [ 'view' => 'blog/post_admin/field/status.html.twig', 'sort' => ['status', '.status'], 'attr' => ['class' => 'miw-100'], - 'inline_form' => function (FormBuilderInterface $builder) { - $builder->add( - 'status', - ChoiceType::class, - [ - 'label' => 'Statut', - 'required' => true, - 'choices' => [ - 'Brouillon' => Entity::DRAFT, - 'Publié' => Entity::PUBLISHED, - ], - 'attr' => [ - ], - 'constraints' => [ - new NotBlank(), - ], - ] - ); - }, ]) - ->setBatchAction('index', 'delete', 'Delete', function (EntityInterface $entity, EntityManager $manager) { + ->setBatchAction('index', 'delete', 'Delete', function(EntityInterface $entity, EntityManager $manager) { $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)); }) - ->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)); }) ; @@ -151,7 +110,7 @@ class PostAdminController extends CrudController $factory->create($this->getUser()), $entityManager, $request, - function (Entity $entity, Form $form, Request $request) use ($fileUpload) { + function(Entity $entity, Form $form, Request $request) use ($fileUpload) { $directory = 'uploads/post/'.date('Y'); $fileUpload->handleForm( @@ -172,7 +131,7 @@ class PostAdminController extends CrudController $entity, $entityManager, $request, - function (Entity $entity, Form $form, Request $request) use ($fileUpload) { + function(Entity $entity, Form $form, Request $request) use ($fileUpload) { $directory = 'uploads/post/'.date('Y'); $fileUpload->handleForm( @@ -186,12 +145,6 @@ class PostAdminController extends CrudController ); } - #[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 - { - return $this->doInlineEdit($context, $label, $entity, $entityManager, $request); - } - #[Route(path: '/show/{entity}', name: 'admin_blog_post_show')] public function show(Entity $entity): Response { @@ -267,7 +220,8 @@ class PostAdminController extends CrudController DateRangeAnalytic $analytic, NodeRepository $nodeRepository, string $range = '7days' - ): Response { + ): Response + { if (!in_array($range, ['7days', '30days', '90days', '1year'])) { throw $this->createNotFoundException(); } diff --git a/src/Controller/Blog/PostController.php b/src/Controller/Blog/PostController.php index 73bb564..fe4e369 100644 --- a/src/Controller/Blog/PostController.php +++ b/src/Controller/Blog/PostController.php @@ -7,19 +7,19 @@ use App\Core\Controller\Site\PageController; use App\Core\Manager\EntityManager; use App\Core\Site\SiteRequest; use App\Core\Site\SiteStore; -use App\Core\Twig\Extension\BuilderExtension; -use App\Core\Twig\Extension\EditorJsExtension; use App\Entity\Blog\Category; use App\Entity\Blog\Post; use App\Factory\Blog\CommentFactory; use App\Form\Blog\UserCommentType; -use App\Manager\PostFollowManager; use App\Markdown\Parser\Post as PostParser; use App\Repository\Blog\PostRepositoryQuery; use App\UrlGenerator\PostGenerator; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use App\Factory\Blog\PostFollowFactory; +use App\Manager\PostFollowManager; +use App\Core\Twig\Extension\EditorJsExtension; class PostController extends PageController { @@ -92,9 +92,9 @@ class PostController extends PageController ]); } - public function posts(Request $request, int $page = 1): Response + public function posts(int $page = 1): Response { - $entities = $this->createQuery($request->query->has('preview') && $this->getUser()) + $entities = $this->createQuery() ->paginate($page, 9) ; @@ -149,34 +149,26 @@ class PostController extends PageController ]); } - public function tag(string $tag, int $page = 1): Response {} - - public function createQuery(bool $isPreview = false): PostRepositoryQuery + public function tag(string $tag, int $page = 1): Response { - $query = $this->postQuery->create() - ->orderBy('.publishedAt', 'DESC') - ; - - if (!$isPreview) { - $query->published(); - } - - return $query; } - public function rss( - PostParser $parser, - EditorJsExtension $editorJsExtension, - BuilderExtension $builderExtension - ): Response { + public function createQuery(): PostRepositoryQuery + { + return $this->postQuery->create() + ->orderBy('.publishedAt', 'DESC') + ->published() + ; + } + + public function rss(PostParser $parser, EditorJsExtension $editorJsExtension): Response + { $entities = $this->createQuery()->paginate(1, 20); $items = []; foreach ($entities as $entity) { - if ('editorjs' === $entity->getContentFormat()) { + if ($entity->getContentFormat() === 'editorjs') { $description = $editorJsExtension->buildHtml($entity->getContent()); - } elseif ('builder' === $entity->getContentFormat()) { - $description = $builderExtension->buildHtml($entity->getContent()); } else { $description = $parser->transformMarkdown($entity->getContent()); } @@ -197,7 +189,7 @@ class PostController extends PageController 'post' => $entity->getId(), 'slug' => $entity->getSlug(), ], UrlGeneratorInterface::ABSOLUTE_URL), - 'linkGemini' => sprintf('gemini://deblan.fr/posts/%d.gmi', $entity->getId()), + 'linkGemini' => sprintf('gemini://deblan.io/posts/%d.gmi', $entity->getId()), ]; } diff --git a/src/Controller/ContactController.php b/src/Controller/ContactController.php index 26703f4..dffd8e3 100644 --- a/src/Controller/ContactController.php +++ b/src/Controller/ContactController.php @@ -4,10 +4,10 @@ namespace App\Controller; use App\Core\Controller\Site\PageController; use App\Core\Notification\MailNotifier; -use App\Core\Setting\SettingManager; use App\Form\ContactType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use App\Core\Setting\SettingManager; class ContactController extends PageController { diff --git a/src/Controller/DashboardAdminController.php b/src/Controller/DashboardAdminController.php index 7fea805..833cf1a 100644 --- a/src/Controller/DashboardAdminController.php +++ b/src/Controller/DashboardAdminController.php @@ -3,8 +3,6 @@ namespace App\Controller; use App\Core\Controller\Dashboard\DashboardAdminController as Controller; -use App\Repository\Blog\PostRepositoryQuery; -use App\Repository\ProjectRepositoryQuery; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -12,23 +10,8 @@ use Symfony\Component\Routing\Annotation\Route; class DashboardAdminController extends Controller { #[Route(path: '/', name: 'admin_dashboard_index')] - public function index( - PostRepositoryQuery $postQuery, - ProjectRepositoryQuery $projectQuery - ): Response { - $posts = $postQuery->create() - ->orderBy('.id', 'DESC') - ->paginate(1, 4) - ; - - $projects = $projectQuery->create() - ->orderBy('.id', 'DESC') - ->paginate(1, 3) - ; - - return $this->render('admin/dashboard.html.twig', [ - 'posts' => $posts, - 'projects' => $projects, - ]); + public function index(): Response + { + return $this->render('admin/dashboard.html.twig'); } } diff --git a/src/Controller/ProjectAdminController.php b/src/Controller/ProjectAdminController.php index 83034db..57bbc6a 100644 --- a/src/Controller/ProjectAdminController.php +++ b/src/Controller/ProjectAdminController.php @@ -7,7 +7,6 @@ use App\Core\Crud\CrudConfiguration; use App\Core\Crud\Field; use App\Core\Entity\EntityInterface; use App\Core\Manager\EntityManager; -use App\Entity\Project; use App\Entity\Project as Entity; use App\Factory\ProjectFactory as Factory; use App\Form\ProjectType as Type; @@ -16,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Routing\Annotation\Route; +use App\Entity\Project; class ProjectAdminController extends CrudController { @@ -114,13 +114,13 @@ class ProjectAdminController extends CrudController 'attr' => ['class' => 'miw-100'], ]) - ->setBatchAction('index', 'delete', 'Delete', function (EntityInterface $entity, EntityManager $manager) { + ->setBatchAction('index', 'delete', 'Delete', function(EntityInterface $entity, EntityManager $manager) { $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(Project::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(Project::DRAFT)); }) ; diff --git a/src/Controller/StlMeshAdminController.php b/src/Controller/StlMeshAdminController.php index f9f9614..6b052f5 100644 --- a/src/Controller/StlMeshAdminController.php +++ b/src/Controller/StlMeshAdminController.php @@ -110,7 +110,7 @@ class StlMeshAdminController extends CrudController 'attr' => ['class' => 'col-md-12'], ]) - ->setBatchAction('index', 'delete', 'Delete', function (EntityInterface $entity, EntityManager $manager) { + ->setBatchAction('index', 'delete', 'Delete', function(EntityInterface $entity, EntityManager $manager) { $manager->delete($entity); }) ; diff --git a/src/Controller/StlMeshController.php b/src/Controller/StlMeshController.php index 066552f..594bddf 100644 --- a/src/Controller/StlMeshController.php +++ b/src/Controller/StlMeshController.php @@ -2,11 +2,13 @@ namespace App\Controller; +use App\Api\TTRssClient; use App\Core\Controller\Site\PageController; -use App\Entity\StlMesh; -use App\Repository\StlMeshRepositoryQuery; -use Symfony\Component\HttpFoundation\BinaryFileResponse; +use App\Markdown\Parser\Post as PostParser; use Symfony\Component\HttpFoundation\Response; +use App\Repository\StlMeshRepositoryQuery; +use App\Entity\StlMesh; +use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\Routing\Annotation\Route; @@ -16,8 +18,7 @@ class StlMeshController extends PageController { $pager = $query->create() ->orderBy('.sortOrder') - ->paginate(1, 200) - ; + ->paginate(1, 200); return $this->defaultRender($this->siteRequest->getPage()->getTemplate(), [ 'pager' => $pager, diff --git a/src/Controller/TextController.php b/src/Controller/TextController.php index d72aea3..39cb0a9 100644 --- a/src/Controller/TextController.php +++ b/src/Controller/TextController.php @@ -2,7 +2,9 @@ namespace App\Controller; +use App\Api\TTRssClient; use App\Core\Controller\Site\PageController; +use App\Markdown\Parser\Post as PostParser; use Symfony\Component\HttpFoundation\Response; class TextController extends PageController diff --git a/src/Controller/UserAdminController.php b/src/Controller/UserAdminController.php deleted file mode 100644 index 9970f51..0000000 --- a/src/Controller/UserAdminController.php +++ /dev/null @@ -1,79 +0,0 @@ - '\d+'])] - public function index(RepositoryQuery $query, Request $request, Session $session, int $page = 1): Response - { - return parent::index($query, $request, $session, $page); - } - - #[Route(path: '/admin/user/new', name: 'admin_user_new', methods: ['GET', 'POST'])] - public function new(Factory $factory, EntityManager $entityManager, Request $request, TokenGenerator $tokenGenerator): Response - { - return parent::new($factory, $entityManager, $request, $tokenGenerator); - } - - #[Route(path: '/admin/user/show/{entity}', name: 'admin_user_show', methods: ['GET'])] - public function show(Entity $entity): Response - { - return parent::show($entity); - } - - #[Route(path: '/admin/user/filter', name: 'admin_user_filter', methods: ['GET'])] - public function filter(Session $session): Response - { - return parent::filter($session); - } - - #[Route(path: '/admin/user/edit/{entity}', name: 'admin_user_edit', methods: ['GET', 'POST'])] - public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response - { - return parent::edit($entity, $entityManager, $request); - } - - #[Route(path: '/admin/user/inline_edit/{entity}/{context}/{label}', name: 'admin_user_inline_edit', methods: ['GET', 'POST'])] - public function inlineEdit(string $context, string $label, Entity $entity, EntityManager $entityManager, Request $request): Response - { - return parent::inlineEdit($context, $label, $entity, $entityManager, $request); - } - - #[Route(path: '/admin/user/delete/{entity}', name: 'admin_user_delete', methods: ['DELETE', 'POST'])] - public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response - { - return parent::delete($entity, $entityManager, $request); - } - - #[Route(path: '/admin/user/resetting_request/{entity}', name: 'admin_user_resetting_request', methods: ['POST'])] - public function requestResetting(Entity $entity, EventDispatcherInterface $eventDispatcher, Request $request): Response - { - return parent::requestResetting($entity, $eventDispatcher, $request); - } - - protected function getConfiguration(): CrudConfiguration - { - if ($this->configuration) { - return $this->configuration; - } - - return parent::getConfiguration() - ->setView('form', 'admin/user_admin/_form.html.twig') - ->setView('show_entity', 'admin/user_admin/_show.html.twig') - ; - } -} diff --git a/src/DependencyInjection/AppExtension.php b/src/DependencyInjection/AppExtension.php index 3678680..664ea17 100644 --- a/src/DependencyInjection/AppExtension.php +++ b/src/DependencyInjection/AppExtension.php @@ -7,6 +7,9 @@ use Symfony\Component\DependencyInjection\Extension\Extension; class AppExtension extends Extension { + /** + * {@inheritdoc} + */ public function load(array $configs, ContainerBuilder $container) { $configuration = $this->getConfiguration($configs, $container); @@ -15,6 +18,9 @@ class AppExtension extends Extension $container->setParameter('app', $config); } + /** + * {@inheritdoc} + */ public function getConfiguration(array $configs, ContainerBuilder $container) { return new Configuration(); diff --git a/src/Entity/Blog/Comment.php b/src/Entity/Blog/Comment.php index d471924..b2b108a 100644 --- a/src/Entity/Blog/Comment.php +++ b/src/Entity/Blog/Comment.php @@ -55,16 +55,6 @@ class Comment implements EntityInterface $this->postFollows = new ArrayCollection(); } - public function __toString() - { - return sprintf( - '[%s] (%s) %s', - $this->getAuthor(), - $this->getCreatedAt()->format('d/m/Y'), - substr($this->getContent(), 0, 20).'…' - ); - } - public function getId(): ?int { return $this->id; @@ -199,12 +189,25 @@ class Comment implements EntityInterface */ public function getAvatar(): string { - $mail = $this->getEmail() ?? sprintf('%d@deblan.fr', $this->getId()); + $mail = $this->getEmail() ?? sprintf('%d@deblan.io', $this->getId()); $hash = md5($mail); return 'https://cdn.libravatar.org/avatar/'.$hash.'?s=90&d=retro'; } + /** + * {@inheritdoc} + */ + public function __toString() + { + return sprintf( + '[%s] (%s) %s', + $this->getAuthor(), + $this->getCreatedAt()->format('d/m/Y'), + substr($this->getContent(), 0, 20).'…' + ); + } + /** * @return Collection|PostFollow[] */ diff --git a/src/Entity/Blog/Post.php b/src/Entity/Blog/Post.php index dee2d47..cd8cef5 100644 --- a/src/Entity/Blog/Post.php +++ b/src/Entity/Blog/Post.php @@ -19,8 +19,8 @@ class Post implements EntityInterface { use Timestampable; - public const DRAFT = 0; - public const PUBLISHED = 1; + const DRAFT = 0; + const PUBLISHED = 1; #[ORM\Id] #[ORM\GeneratedValue] @@ -87,21 +87,11 @@ class Post implements EntityInterface #[ORM\Column(type: 'string', length: 255, nullable: true)] private $image2; - #[ORM\Column(type: 'array')] - private $parameters = []; - - #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'deprecatedPosts')] - private $recommandedPost; - - #[ORM\OneToMany(mappedBy: 'recommandedPost', targetEntity: self::class)] - private $deprecatedPosts; - public function __construct() { $this->categories = new ArrayCollection(); $this->comments = new ArrayCollection(); $this->postFollows = new ArrayCollection(); - $this->deprecatedPosts = new ArrayCollection(); } public function getId(): ?int @@ -202,7 +192,7 @@ class Post implements EntityInterface } /** - * @return Category[]|Collection + * @return Collection|Category[] */ public function getCategories(): Collection { @@ -448,80 +438,4 @@ class Post implements EntityInterface return $this; } - - public function getParameters(): ?array - { - $params = is_array($this->parameters) ? $this->parameters : []; - $names = array_map(fn (array $param): string => $param['name'], $params); - $defaultParams = [ - ['name' => 'podcast', 'value' => 0], - ]; - - foreach ($defaultParams as $defaultParam) { - if (!in_array($defaultParam['name'], $names)) { - $params[] = $defaultParam; - } - } - - return $params; - } - - public function setParameters(array $parameters): self - { - $this->parameters = $parameters; - - return $this; - } - - public function getParameter($name): ?string - { - return array_filter( - $this->getParameters(), - function (array $param) use ($name): bool { - return $name === $param['name']; - } - )[0]['value'] ?? null; - } - - public function getRecommandedPost(): ?self - { - return $this->recommandedPost; - } - - public function setRecommandedPost(?self $recommandedPost): self - { - $this->recommandedPost = $recommandedPost; - - return $this; - } - - /** - * @return Collection{$codeblock}";
- } else {
- $codeblock = "{$codeblock}";
- }
+ $codeblock = "{$codeblock}";
return "\n\n".$this->hashBlock($codeblock)."\n\n";
}
diff --git a/src/Message/PageViewMessage.php b/src/Message/PageViewMessage.php
deleted file mode 100644
index 50eace5..0000000
--- a/src/Message/PageViewMessage.php
+++ /dev/null
@@ -1,13 +0,0 @@
-time;
- }
-}
diff --git a/src/MessageHandler/PageViewMessageHandler.php b/src/MessageHandler/PageViewMessageHandler.php
deleted file mode 100644
index ac4e0d0..0000000
--- a/src/MessageHandler/PageViewMessageHandler.php
+++ /dev/null
@@ -1,35 +0,0 @@
-influxDB->isAvailable()) {
- return;
- }
-
- $client = $this->influxDB->getClient();
-
- $writeApi = $client->createWriteApi(['writeType' => WriteType::SYNCHRONOUS]);
- $pageView = new Point('page_view');
- $pageView
- ->addTag('request', 'view')
- ->addField('value', 1)
- ->time($message->getTime())
- ;
-
- $writeApi->write($pageView);
- $writeApi->close();
- $client->close();
- }
-}
diff --git a/src/Middleware/PageViewMiddleware.php b/src/Middleware/PageViewMiddleware.php
deleted file mode 100644
index 1944109..0000000
--- a/src/Middleware/PageViewMiddleware.php
+++ /dev/null
@@ -1,16 +0,0 @@
-next()->handle($envelope, $stack);
- }
-}
diff --git a/src/Repository/AppEntityBlogPostRepository.php b/src/Repository/AppEntityBlogPostRepository.php
deleted file mode 100644
index 51e8e0c..0000000
--- a/src/Repository/AppEntityBlogPostRepository.php
+++ /dev/null
@@ -1,66 +0,0 @@
-
- *
- * @method null|AppEntityBlogPost find($id, $lockMode = null, $lockVersion = null)
- * @method null|AppEntityBlogPost findOneBy(array $criteria, array $orderBy = null)
- * @method AppEntityBlogPost[] findAll()
- * @method AppEntityBlogPost[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
- */
-class AppEntityBlogPostRepository extends ServiceEntityRepository
-{
- public function __construct(ManagerRegistry $registry)
- {
- parent::__construct($registry, AppEntityBlogPost::class);
- }
-
- public function add(AppEntityBlogPost $entity, bool $flush = false): void
- {
- $this->getEntityManager()->persist($entity);
-
- if ($flush) {
- $this->getEntityManager()->flush();
- }
- }
-
- public function remove(AppEntityBlogPost $entity, bool $flush = false): void
- {
- $this->getEntityManager()->remove($entity);
-
- if ($flush) {
- $this->getEntityManager()->flush();
- }
- }
-
- // /**
- // * @return AppEntityBlogPost[] Returns an array of AppEntityBlogPost objects
- // */
- // public function findByExampleField($value): array
- // {
- // return $this->createQueryBuilder('a')
- // ->andWhere('a.exampleField = :val')
- // ->setParameter('val', $value)
- // ->orderBy('a.id', 'ASC')
- // ->setMaxResults(10)
- // ->getQuery()
- // ->getResult()
- // ;
- // }
-
- // public function findOneBySomeField($value): ?AppEntityBlogPost
- // {
- // return $this->createQueryBuilder('a')
- // ->andWhere('a.exampleField = :val')
- // ->setParameter('val', $value)
- // ->getQuery()
- // ->getOneOrNullResult()
- // ;
- // }
-}
diff --git a/src/Repository/Blog/CommentRepository.php b/src/Repository/Blog/CommentRepository.php
index b111fc7..306d21f 100644
--- a/src/Repository/Blog/CommentRepository.php
+++ b/src/Repository/Blog/CommentRepository.php
@@ -7,8 +7,8 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
- * @method null|Comment find($id, $lockMode = null, $lockVersion = null)
- * @method null|Comment findOneBy(array $criteria, array $orderBy = null)
+ * @method Comment|null find($id, $lockMode = null, $lockVersion = null)
+ * @method Comment|null findOneBy(array $criteria, array $orderBy = null)
* @method Comment[] findAll()
* @method Comment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
diff --git a/src/Repository/Blog/PostFollowRepositoryQuery.php b/src/Repository/Blog/PostFollowRepositoryQuery.php
index f528a63..a14240c 100644
--- a/src/Repository/Blog/PostFollowRepositoryQuery.php
+++ b/src/Repository/Blog/PostFollowRepositoryQuery.php
@@ -3,8 +3,8 @@
namespace App\Repository\Blog;
use App\Core\Repository\RepositoryQuery;
-use App\Repository\Blog\PostFollowRepository as Repository;
use Knp\Component\Pager\PaginatorInterface;
+use App\Repository\Blog\PostFollowRepository as Repository;
class PostFollowRepositoryQuery extends RepositoryQuery
{
diff --git a/src/Repository/Blog/PostRepositoryQuery.php b/src/Repository/Blog/PostRepositoryQuery.php
index c8db9e6..0def03f 100644
--- a/src/Repository/Blog/PostRepositoryQuery.php
+++ b/src/Repository/Blog/PostRepositoryQuery.php
@@ -54,13 +54,15 @@ class PostRepositoryQuery extends RepositoryQuery
;
}
+ protected function filterHandler(string $name, $value)
+ {
+ if ('category' === $name) {
+ $this->inCategory($value);
+ }
+ }
+
public function search(?string $keywords, ?string $tag)
{
- $keywords = explode(' ', $keywords);
-
- $filterWords = fn ($keyword) => '' !== trim($keyword) && preg_match('/[a-zA-Z]+/', $keyword);
- $keywords = array_filter($keywords, $filterWords);
-
if ($keywords) {
$conn = $this->repository->getEm()->getConnection();
@@ -68,106 +70,42 @@ class PostRepositoryQuery extends RepositoryQuery
'SELECT
post.id,
post.title,
- post.content,
- post.published_at
+ MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
+ MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
FROM post
WHERE
post.status = 1 AND
post.published_at < :date
- '
- );
+ ORDER BY
+ MATCH_TITLE DESC,
+ MATCH_CONTENT DESC
+ ');
$statement = $query->execute([
+ ':search' => $keywords,
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
]);
$results = $statement->fetchAll();
$ids = [];
- $matches = [];
foreach ($results as $k => $v) {
- $initWords = explode(' ', $v['title']);
- $words = [];
+ $rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
- foreach ($initWords as $initWord) {
- $words = array_merge($words, preg_split('/[:_\'-]+/', $initWord));
- }
-
- $words = array_filter($words, $filterWords);
-
- foreach ($keywords as $keyword) {
- if (str_contains(mb_strtolower($v['content']), mb_strtolower($keyword))) {
- $similarity = 99;
-
- if (isset($matches[$v['id']])) {
- $matches[$v['id']]['similarity'] += $similarity;
- ++$matches[$v['id']]['count'];
- } else {
- $matches[$v['id']] = [
- 'id' => $v['id'],
- 'title' => $v['title'],
- 'published_at' => $v['published_at'],
- 'similarity' => $similarity,
- 'count' => 1,
- ];
- }
- }
-
- foreach ($words as $word) {
- if (str_contains(mb_strtolower($word), mb_strtolower($keyword))) {
- $similarity = 150;
-
- if (isset($matches[$v['id']])) {
- $matches[$v['id']]['similarity'] += $similarity;
- ++$matches[$v['id']]['count'];
- } else {
- $matches[$v['id']] = [
- 'id' => $v['id'],
- 'title' => $v['title'],
- 'published_at' => $v['published_at'],
- 'similarity' => $similarity,
- 'count' => 1,
- ];
- }
- } else {
- $lev = levenshtein($word, $keyword);
- $similarity = 100 - ($lev * 100 / mb_strlen($word));
-
- if ($similarity > 70) {
- if (isset($matches[$v['id']])) {
- $matches[$v['id']]['similarity'] += $similarity;
- } else {
- $matches[$v['id']] = [
- 'id' => $v['id'],
- 'title' => $v['title'],
- 'published_at' => $v['published_at'],
- 'similarity' => $similarity,
- 'count' => 1,
- ];
- }
- }
- }
- }
+ if ($rate >= 7) {
+ $ids[] = $v['id'];
}
}
- $matches = array_filter($matches, function ($match) use ($keywords) {
- return (100 * $match['count'] / count($keywords)) > 80;
- });
+ if (0 == count($ids)) {
+ foreach ($results as $k => $v) {
+ $rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
- usort($matches, function ($a, $b) {
- if ($a['similarity'] > $b['similarity']) {
- return -1;
+ if ($rate >= 6) {
+ $ids[] = $v['id'];
+ }
}
-
- if ($b['similarity'] > $a['similarity']) {
- return 1;
- }
-
- return ($a['published_at'] != $b['published_at']) * -1;
- });
-
- $ids = array_column($matches, 'id');
+ }
if (!$ids) {
$ids = [-1];
@@ -189,11 +127,4 @@ class PostRepositoryQuery extends RepositoryQuery
return $this;
}
-
- protected function filterHandler(string $name, $value)
- {
- if ('category' === $name) {
- $this->inCategory($value);
- }
- }
}
diff --git a/src/Repository/ProjectRepository.php b/src/Repository/ProjectRepository.php
index 8801364..560cb87 100644
--- a/src/Repository/ProjectRepository.php
+++ b/src/Repository/ProjectRepository.php
@@ -9,8 +9,8 @@ use Doctrine\ORM\ORMException;
use Doctrine\Persistence\ManagerRegistry;
/**
- * @method null|Project find($id, $lockMode = null, $lockVersion = null)
- * @method null|Project findOneBy(array $criteria, array $orderBy = null)
+ * @method Project|null find($id, $lockMode = null, $lockVersion = null)
+ * @method Project|null findOneBy(array $criteria, array $orderBy = null)
* @method Project[] findAll()
* @method Project[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
diff --git a/src/Repository/ProjectRepositoryQuery.php b/src/Repository/ProjectRepositoryQuery.php
index 49ae4ad..b4fa818 100644
--- a/src/Repository/ProjectRepositoryQuery.php
+++ b/src/Repository/ProjectRepositoryQuery.php
@@ -3,9 +3,9 @@
namespace App\Repository;
use App\Core\Repository\RepositoryQuery;
-use App\Entity\Project;
-use App\Repository\ProjectRepository as Repository;
use Knp\Component\Pager\PaginatorInterface;
+use App\Repository\ProjectRepository as Repository;
+use App\Entity\Project;
class ProjectRepositoryQuery extends RepositoryQuery
{
diff --git a/src/Repository/StlMeshRepository.php b/src/Repository/StlMeshRepository.php
index 4fa6b4d..ede601b 100644
--- a/src/Repository/StlMeshRepository.php
+++ b/src/Repository/StlMeshRepository.php
@@ -7,8 +7,8 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
- * @method null|StlMesh find($id, $lockMode = null, $lockVersion = null)
- * @method null|StlMesh findOneBy(array $criteria, array $orderBy = null)
+ * @method StlMesh|null find($id, $lockMode = null, $lockVersion = null)
+ * @method StlMesh|null findOneBy(array $criteria, array $orderBy = null)
* @method StlMesh[] findAll()
* @method StlMesh[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
diff --git a/src/Repository/StlMeshRepositoryQuery.php b/src/Repository/StlMeshRepositoryQuery.php
index 95d93a2..25c4bbe 100644
--- a/src/Repository/StlMeshRepositoryQuery.php
+++ b/src/Repository/StlMeshRepositoryQuery.php
@@ -3,8 +3,8 @@
namespace App\Repository;
use App\Core\Repository\RepositoryQuery;
-use App\Repository\StlMeshRepository as Repository;
use Knp\Component\Pager\PaginatorInterface;
+use App\Repository\StlMeshRepository as Repository;
class StlMeshRepositoryQuery extends RepositoryQuery
{
diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php
index 39ecbe4..570efd5 100644
--- a/src/Repository/UserRepository.php
+++ b/src/Repository/UserRepository.php
@@ -6,8 +6,9 @@ use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
-use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
{
diff --git a/src/Twig/Extension/BlogExtension.php b/src/Twig/Extension/BlogExtension.php
index 102099d..3b1467a 100644
--- a/src/Twig/Extension/BlogExtension.php
+++ b/src/Twig/Extension/BlogExtension.php
@@ -40,9 +40,8 @@ class BlogExtension extends AbstractExtension
$text = str_replace('http://upload.deblan.fr', 'https://upload.deblan.org', $text);
$text = str_replace('http://dedi.geneweb.fr', 'http://kim.deblan.fr', $text);
$text = str_replace('http://mediaplayer.deblan.fr', 'https://mediaplayer.deblan.org', $text);
- $text = str_replace('http://blog.deblan.fr', 'https://www.deblan.fr', $text);
- $text = str_replace('http://www.deblan.tv', 'https://www.deblan.fr', $text);
- $text = str_replace('http://www.deblan.io', 'https://www.deblan.fr', $text);
+ $text = str_replace('http://blog.deblan.fr', 'https://www.deblan.io', $text);
+ $text = str_replace('http://www.deblan.tv', 'https://www.deblan.io', $text);
$text = preg_replace_callback(
'`]*)>(.*)
]*)>`isU', @@ -135,12 +134,10 @@ class BlogExtension extends AbstractExtension '#(.*)#isU',
],
function ($data) {
- $lang = strtolower(
- str_replace(
- ['console', 'texte', 'apache'],
- ['bash', 'text', 'html'],
- $data[1]
- )
+ $lang = strtolower(str_replace(
+ ['console', 'texte', 'apache'],
+ ['bash', 'text', 'html'],
+ $data[1])
);
$class = 'language-'.$lang;
diff --git a/src/Twig/Extension/ColorExtension.php b/src/Twig/Extension/ColorExtension.php
index f39a3f6..09311bc 100644
--- a/src/Twig/Extension/ColorExtension.php
+++ b/src/Twig/Extension/ColorExtension.php
@@ -30,9 +30,9 @@ class ColorExtension extends AbstractExtension
return sprintf(
'#%s%s%s',
- 2 != strlen($red) ? '0'.$red : $red,
- 2 != strlen($green) ? '0'.$green : $green,
- 2 != strlen($blue) ? '0'.$blue : $blue,
+ strlen($red) != 2 ? '0'.$red : $red,
+ strlen($green) != 2 ? '0'.$green : $green,
+ strlen($blue) != 2 ? '0'.$blue : $blue,
);
}
}
diff --git a/src/Twig/Extension/LazyLoadExtension.php b/src/Twig/Extension/LazyLoadExtension.php
index 59a660a..167d12a 100644
--- a/src/Twig/Extension/LazyLoadExtension.php
+++ b/src/Twig/Extension/LazyLoadExtension.php
@@ -21,7 +21,7 @@ class LazyLoadExtension extends AbstractExtension
public function lazyLoad($text)
{
- return preg_replace_callback(
+ $text = preg_replace_callback(
'`