mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-12-08 20:19:30 +00:00
Merge branch 'v2'
This commit is contained in:
commit
da11c9b793
272 changed files with 11020 additions and 5206 deletions
17
.editorconfig
Normal file
17
.editorconfig
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{compose.yaml,compose.*.yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
197
.env
197
.env
|
|
@ -32,36 +32,16 @@ DATABASE_EMULATE_NATURAL_SORT=0
|
|||
###################################################################################
|
||||
|
||||
# The language to use serverwide as default (en, de, ru, etc.)
|
||||
DEFAULT_LANG="en"
|
||||
#DEFAULT_LANG="en"
|
||||
# The default timezone to use serverwide (e.g. Europe/Berlin)
|
||||
DEFAULT_TIMEZONE="Europe/Berlin"
|
||||
#DEFAULT_TIMEZONE="Europe/Berlin"
|
||||
# The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
||||
BASE_CURRENCY="EUR"
|
||||
# The name of this installation. This will be shown as title in the browser and in the header of the website
|
||||
INSTANCE_NAME="Part-DB"
|
||||
# Allow users to download attachments to the server by providing an URL
|
||||
# This could be a potential security issue, as the user can retrieve any file the server has access to (via internet)
|
||||
ALLOW_ATTACHMENT_DOWNLOADS=0
|
||||
# Set this to 1, if the "download external files" checkbox should be checked by default for new attachments
|
||||
ATTACHMENT_DOWNLOAD_BY_DEFAULT=0
|
||||
# Use gravatars for user avatars, when user has no own avatar defined
|
||||
USE_GRAVATAR=0
|
||||
# The maximum allowed size for attachment files in bytes (you can use M for megabytes and G for gigabytes)
|
||||
# Please note that the php.ini setting upload_max_filesize also limits the maximum size of uploaded files
|
||||
MAX_ATTACHMENT_FILE_SIZE="100M"
|
||||
#BASE_CURRENCY="EUR"
|
||||
|
||||
# The public reachable URL of this Part-DB installation. This is used for generating links in SAML and email templates
|
||||
# This must end with a slash!
|
||||
DEFAULT_URI="https://partdb.changeme.invalid/"
|
||||
|
||||
# With this option you can configure, where users are enforced to give a change reason, which will be logged
|
||||
# This is a comma separated list of values, see documentation for available values
|
||||
# Leave this empty, to make all change reasons optional
|
||||
ENFORCE_CHANGE_COMMENTS_FOR=""
|
||||
|
||||
# Disable that if you do not want that Part-DB connects to GitHub to check for available updates, or if your server can not connect to the internet
|
||||
CHECK_FOR_UPDATES=1
|
||||
|
||||
###################################################################################
|
||||
# Email settings
|
||||
###################################################################################
|
||||
|
|
@ -78,21 +58,6 @@ EMAIL_SENDER_NAME="Part-DB Mailer"
|
|||
# Set this to 1 to allow reset of a password per email
|
||||
ALLOW_EMAIL_PW_RESET=0
|
||||
|
||||
######################################################################################
|
||||
# History/Eventlog settings
|
||||
######################################################################################
|
||||
# If you want to use full timetrave functionality all values below have to be set to 1
|
||||
|
||||
# Save which fields were changed in a ElementEdited log entry
|
||||
HISTORY_SAVE_CHANGED_FIELDS=1
|
||||
# Save the old data in the ElementEdited log entry (warning this could increase the database size in short time)
|
||||
HISTORY_SAVE_CHANGED_DATA=1
|
||||
# Save the data of an element that gets removed into log entry. This allows to undelete an element
|
||||
HISTORY_SAVE_REMOVED_DATA=1
|
||||
# Save the new data of an element that gets changed or added. This allows an easy comparison of the old and new data on the detail page
|
||||
# This option only becomes active when HISTORY_SAVE_CHANGED_DATA is set to 1
|
||||
HISTORY_SAVE_NEW_DATA=1
|
||||
|
||||
###################################################################################
|
||||
# Error pages settings
|
||||
###################################################################################
|
||||
|
|
@ -102,140 +67,6 @@ ERROR_PAGE_ADMIN_EMAIL=''
|
|||
# If this is set to true, solutions to common problems are shown on error pages. Disable this, if you do not want your users to see them...
|
||||
ERROR_PAGE_SHOW_HELP=1
|
||||
|
||||
##################################################################################
|
||||
# Part table settings
|
||||
##################################################################################
|
||||
|
||||
# The default page size for the part table (set to -1 to show all parts on one page)
|
||||
TABLE_DEFAULT_PAGE_SIZE=50
|
||||
# Configure which columns will be visible by default in the parts table (and in which order).
|
||||
# This is a comma separated list of column names. See documentation for available values.
|
||||
TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
|
||||
|
||||
##################################################################################
|
||||
# Info provider settings
|
||||
##################################################################################
|
||||
|
||||
# Digikey Provider:
|
||||
# You can get your client id and secret from https://developer.digikey.com/
|
||||
PROVIDER_DIGIKEY_CLIENT_ID=
|
||||
PROVIDER_DIGIKEY_SECRET=
|
||||
# The currency to get prices in
|
||||
PROVIDER_DIGIKEY_CURRENCY=EUR
|
||||
# The language to get results in (en, de, fr, it, es, zh, ja, ko)
|
||||
PROVIDER_DIGIKEY_LANGUAGE=en
|
||||
# The country to get results for
|
||||
PROVIDER_DIGIKEY_COUNTRY=DE
|
||||
|
||||
# Farnell Provider:
|
||||
# You can get your API key from https://partner.element14.com/
|
||||
PROVIDER_ELEMENT14_KEY=
|
||||
# Configure the store domain you want to use. This decides the language and currency of results. You can get a list of available stores from https://partner.element14.com/docs/Product_Search_API_REST__Description
|
||||
PROVIDER_ELEMENT14_STORE_ID=de.farnell.com
|
||||
|
||||
# TME Provider:
|
||||
# You can get your API key from https://developers.tme.eu/en/
|
||||
PROVIDER_TME_KEY=
|
||||
PROVIDER_TME_SECRET=
|
||||
# The currency to get prices in
|
||||
PROVIDER_TME_CURRENCY=EUR
|
||||
# The language to get results in (en, de, pl)
|
||||
PROVIDER_TME_LANGUAGE=en
|
||||
# The country to get results for
|
||||
PROVIDER_TME_COUNTRY=DE
|
||||
# [DEPRECATED] Set this to 1 to get gross prices (including VAT) instead of net prices
|
||||
# With private API keys, this option cannot be used anymore is ignored by Part-DB. The VAT inclusion depends on your TME account settings.
|
||||
PROVIDER_TME_GET_GROSS_PRICES=1
|
||||
|
||||
# Octopart / Nexar Provider:
|
||||
# You can get your API key from https://nexar.com/api
|
||||
PROVIDER_OCTOPART_CLIENT_ID=
|
||||
PROVIDER_OCTOPART_SECRET=
|
||||
# The currency and country to get prices for (you have to set both to get meaningful results)
|
||||
# 3 letter ISO currency code (e.g. EUR, USD, GBP)
|
||||
PROVIDER_OCTOPART_CURRENCY=EUR
|
||||
# 2 letter ISO country code (e.g. DE, US, GB)
|
||||
PROVIDER_OCTOPART_COUNTRY=DE
|
||||
# The number of results to get from Octopart while searching (please note that this counts towards your API limits)
|
||||
PROVIDER_OCTOPART_SEARCH_LIMIT=10
|
||||
# Set to false to include non authorized offers in the results
|
||||
PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS=1
|
||||
|
||||
# Mouser Provider API V2:
|
||||
# You can get your API key from https://www.mouser.it/api-hub/
|
||||
PROVIDER_MOUSER_KEY=
|
||||
# Filter search results by RoHS compliance and stock availability:
|
||||
# Available options: None | Rohs | InStock | RohsAndInStock
|
||||
PROVIDER_MOUSER_SEARCH_OPTION='None'
|
||||
# The number of results to get from Mouser while searching (please note that this value is max 50)
|
||||
PROVIDER_MOUSER_SEARCH_LIMIT=50
|
||||
# It is recommended to leave this set to 'true'. The option is not really good doumented by Mouser:
|
||||
# Used when searching for keywords in the language specified when you signed up for Search API.
|
||||
PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE='true'
|
||||
|
||||
# LCSC Provider:
|
||||
# LCSC does not provide an offical API, so this used the API LCSC uses to render their webshop.
|
||||
# LCSC did not intended the use of this API and it could break any time, so use it at your own risk.
|
||||
|
||||
# We dont require an API key for LCSC, just set this to 1 to enable LCSC support
|
||||
PROVIDER_LCSC_ENABLED=0
|
||||
# The currency to get prices in (e.g. EUR, USD, etc.)
|
||||
PROVIDER_LCSC_CURRENCY=EUR
|
||||
|
||||
# Oemsecrets Provider API 3.0.1:
|
||||
# You can get your API key from https://www.oemsecrets.com/api
|
||||
PROVIDER_OEMSECRETS_KEY=
|
||||
# The country you want the output for
|
||||
PROVIDER_OEMSECRETS_COUNTRY_CODE=DE
|
||||
# Available country code are:
|
||||
# AD, AE, AQ, AR, AT, AU, BE, BO, BR, BV, BY, CA, CH, CL, CN, CO, CZ, DE, DK, EC, EE, EH,
|
||||
# ES, FI, FK, FO, FR, GB, GE, GF, GG, GI, GL, GR, GS, GY, HK, HM, HR, HU, IE, IM, IN, IS,
|
||||
# IT, JM, JP, KP, KR, KZ, LI, LK, LT, LU, MC, MD, ME, MK, MT, NL, NO, NZ, PE, PH, PL, PT,
|
||||
# PY, RO, RS, RU, SB, SD, SE, SG, SI, SJ, SK, SM, SO, SR, SY, SZ, TC, TF, TG, TH, TJ, TK,
|
||||
# TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VE, VG, VI, VN, VU, WF, YE,
|
||||
# ZA, ZM, ZW
|
||||
#
|
||||
# The currency you want the prices to be displayed in
|
||||
PROVIDER_OEMSECRETS_CURRENCY=EUR
|
||||
# Available currency are:AUD, CAD, CHF, CNY, DKK, EUR, GBP, HKD, ILS, INR, JPY, KRW, NOK,
|
||||
# NZD, RUB, SEK, SGD, TWD, USD
|
||||
#
|
||||
# If PROVIDER_OEMSECRETS_ZERO_PRICE is set to 0, distributors with zero prices
|
||||
# will be discarded from the creation of a new part (set to 1 otherwise)
|
||||
PROVIDER_OEMSECRETS_ZERO_PRICE=0
|
||||
#
|
||||
# When PROVIDER_OEMSECRETS_SET_PARAM is set to 1 the parameters for the part are generated
|
||||
# from the description transforming unstructured descriptions into structured parameters;
|
||||
# each parameter in description should have the form: "...;name1:value1;name2:value2"
|
||||
PROVIDER_OEMSECRETS_SET_PARAM=1
|
||||
#
|
||||
# This environment variable determines the sorting criteria for product results.
|
||||
# The sorting process first arranges items based on the provided keyword.
|
||||
# Then, if set to 'C', it further sorts by completeness (prioritizing items with the most
|
||||
# detailed information). If set to 'M', it further sorts by manufacturer name.
|
||||
#If unset or set to any other value, no sorting is performed.
|
||||
PROVIDER_OEMSECRETS_SORT_CRITERIA=C
|
||||
|
||||
|
||||
# Reichelt provider:
|
||||
# Reichelt.com offers no official API, so this info provider webscrapes the website to extract info
|
||||
# It could break at any time, use it at your own risk
|
||||
# We dont require an API key for Reichelt, just set this to 1 to enable Reichelt support
|
||||
PROVIDER_REICHELT_ENABLED=0
|
||||
# The country to get prices for
|
||||
PROVIDER_REICHELT_COUNTRY=DE
|
||||
# The language to get results in (en, de, fr, nl, pl, it, es)
|
||||
PROVIDER_REICHELT_LANGUAGE=en
|
||||
# Include VAT in prices (set to 1 to include VAT, 0 to exclude VAT)
|
||||
PROVIDER_REICHELT_INCLUDE_VAT=1
|
||||
# The currency to get prices in (only for countries with countries other than EUR)
|
||||
PROVIDER_REICHELT_CURRENCY=EUR
|
||||
|
||||
# Pollin provider:
|
||||
# Pollin.de offers no official API, so this info provider webscrapes the website to extract info
|
||||
# It could break at any time, use it at your own risk
|
||||
# We dont require an API key for Pollin, just set this to 1 to enable Pollin support
|
||||
PROVIDER_POLLIN_ENABLED=0
|
||||
|
||||
##################################################################################
|
||||
# EDA integration related settings
|
||||
|
|
@ -243,8 +74,8 @@ PROVIDER_POLLIN_ENABLED=0
|
|||
|
||||
# This value determines the depth of the category tree, that is visible inside KiCad
|
||||
# 0 means that only the top level categories are visible. Set to a value > 0 to show more levels.
|
||||
# Set to -1, to show all parts of Part-DB inside a single category in KiCad
|
||||
EDA_KICAD_CATEGORY_DEPTH=0
|
||||
# Set to -1, to show all parts of Part-DB inside a sigle cnategory in KiCad
|
||||
#EDA_KICAD_CATEGORY_DEPTH=0
|
||||
|
||||
###################################################################################
|
||||
# SAML Single sign on-settings
|
||||
|
|
@ -298,19 +129,6 @@ NO_URL_REWRITE_AVAILABLE=0
|
|||
# Set to 1, if Part-DB should redirect all HTTP requests to HTTPS. You dont need to configure this, if your webserver already does this.
|
||||
REDIRECT_TO_HTTPS=0
|
||||
|
||||
# If you want to use fixer.io for currency conversion, you have to set this to your API key
|
||||
FIXER_API_KEY=CHANGEME
|
||||
|
||||
# Override value if you want to show to show a given text on homepage.
|
||||
# When this is empty the content of config/banner.md is used as banner
|
||||
BANNER=""
|
||||
|
||||
# Enable the part image overlay which shows name and filename of the picture
|
||||
SHOW_PART_IMAGE_OVERLAY=1
|
||||
|
||||
APP_ENV=prod
|
||||
APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
|
||||
|
||||
# Set this to zero, if you want to disable the year 2038 bug check on 32-bit systems (it will cause errors with current 32-bit PHP versions)
|
||||
DISABLE_YEAR2038_BUG_CHECK=0
|
||||
|
||||
|
|
@ -328,3 +146,8 @@ LOCK_DSN=flock
|
|||
###> nelmio/cors-bundle ###
|
||||
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
|
||||
###< nelmio/cors-bundle ###
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=prod
|
||||
APP_SECRET=
|
||||
###< symfony/framework-bundle ###
|
||||
|
|
|
|||
4
.env.dev
4
.env.dev
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_SECRET=318b5d659e07a0b3f96d9b3a83b254ca
|
||||
###< symfony/framework-bundle ###
|
||||
|
|
@ -10,4 +10,6 @@ DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"
|
|||
#DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db
|
||||
|
||||
# Disable update checks, as tests would fail, when github is not reachable
|
||||
CHECK_FOR_UPDATES=0
|
||||
CHECK_FOR_UPDATES=0
|
||||
|
||||
INSTANCE_NAME="Part-DB"
|
||||
4
.github/workflows/assets_artifact_build.yml
vendored
4
.github/workflows/assets_artifact_build.yml
vendored
|
|
@ -39,7 +39,7 @@ jobs:
|
|||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-composer-
|
||||
${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress --no-dev -a
|
||||
|
|
@ -59,7 +59,7 @@ jobs:
|
|||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '20'
|
||||
|
||||
- name: Install yarn dependencies
|
||||
run: yarn install
|
||||
|
|
|
|||
38
.github/workflows/tests.yml
vendored
38
.github/workflows/tests.yml
vendored
|
|
@ -9,7 +9,7 @@ on:
|
|||
branches:
|
||||
- '*'
|
||||
- "!l10n_*"
|
||||
|
||||
|
||||
jobs:
|
||||
phpunit:
|
||||
name: PHPUnit and coverage Test (PHP ${{ matrix.php-versions }}, ${{ matrix.db-type }})
|
||||
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: [ '8.1', '8.2', '8.3', '8.4' ]
|
||||
php-versions: ['8.2', '8.3', '8.4' ]
|
||||
db-type: [ 'mysql', 'sqlite', 'postgres' ]
|
||||
|
||||
env:
|
||||
|
|
@ -52,7 +52,7 @@ jobs:
|
|||
coverage: pcov
|
||||
ini-values: xdebug.max_nesting_level=1000
|
||||
extensions: mbstring, intl, gd, xsl, gmp, bcmath, :php-psr
|
||||
|
||||
|
||||
- name: Start MySQL
|
||||
run: sudo systemctl start mysql.service
|
||||
if: matrix.db-type == 'mysql'
|
||||
|
|
@ -71,9 +71,9 @@ jobs:
|
|||
# mysql version: 5.7
|
||||
# mysql database: 'part-db'
|
||||
# mysql root password: '1234'
|
||||
|
||||
|
||||
## Setup caches
|
||||
|
||||
|
||||
- name: Get Composer Cache Directory
|
||||
id: composer-cache
|
||||
run: |
|
||||
|
|
@ -83,8 +83,8 @@ jobs:
|
|||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-composer-
|
||||
|
||||
${{ runner.os }}-composer-
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
|
@ -96,48 +96,48 @@ jobs:
|
|||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
node-version: '20'
|
||||
|
||||
- name: Install yarn dependencies
|
||||
run: yarn install
|
||||
|
||||
|
||||
- name: Build frontend
|
||||
run: yarn build
|
||||
|
||||
|
||||
- name: Create DB
|
||||
run: php bin/console --env test doctrine:database:create --if-not-exists -n
|
||||
if: matrix.db-type == 'mysql' || matrix.db-type == 'postgres'
|
||||
|
||||
|
||||
- name: Do migrations
|
||||
run: php bin/console --env test doctrine:migrations:migrate -n
|
||||
|
||||
# Use our own custom fixtures loading command to circumvent some problems with reset the autoincrement values
|
||||
- name: Load fixtures
|
||||
run: php bin/console --env test partdb:fixtures:load -n
|
||||
|
||||
|
||||
- name: Run PHPunit and generate coverage
|
||||
run: ./bin/phpunit --coverage-clover=coverage.xml
|
||||
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
env_vars: PHP_VERSION,DB_TYPE
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
|
||||
- name: Test app:clean-attachments
|
||||
run: php bin/console partdb:attachments:clean-unused -n
|
||||
|
||||
|
||||
- name: Test app:convert-bbcode
|
||||
run: php bin/console app:convert-bbcode -n
|
||||
|
||||
|
||||
- name: Test app:show-logs
|
||||
run: php bin/console app:show-logs -n
|
||||
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -2,6 +2,7 @@
|
|||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/.env.local.bak
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
|
|
@ -41,7 +42,7 @@ yarn-error.log
|
|||
|
||||
###> phpunit/phpunit ###
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
/.phpunit.cache/
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
###> phpstan/phpstan ###
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
ARG BASE_IMAGE=debian:bookworm-slim
|
||||
ARG PHP_VERSION=8.3
|
||||
ARG PHP_VERSION=8.4
|
||||
|
||||
FROM ${BASE_IMAGE} AS base
|
||||
ARG PHP_VERSION
|
||||
|
|
@ -48,7 +48,7 @@ RUN apt-get update && apt-get -y install \
|
|||
# Install node and yarn
|
||||
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
||||
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||
curl -sL https://deb.nodesource.com/setup_22.x | bash - && \
|
||||
apt-get update && apt-get install -y \
|
||||
nodejs \
|
||||
yarn \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream
|
||||
FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream
|
||||
|
||||
RUN apt-get update && apt-get -y install \
|
||||
curl \
|
||||
|
|
@ -13,13 +13,33 @@ RUN apt-get update && apt-get -y install \
|
|||
zip \
|
||||
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*;
|
||||
|
||||
# Install node and yarn
|
||||
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
||||
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||
apt-get update && apt-get install -y \
|
||||
nodejs yarn \
|
||||
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
|
||||
RUN set -eux; \
|
||||
# Prepare keyrings directory
|
||||
mkdir -p /etc/apt/keyrings; \
|
||||
\
|
||||
# Import Yarn GPG key
|
||||
curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg \
|
||||
| tee /etc/apt/keyrings/yarn.gpg >/dev/null; \
|
||||
chmod 644 /etc/apt/keyrings/yarn.gpg; \
|
||||
\
|
||||
# Add Yarn repo with signed-by
|
||||
echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian stable main" \
|
||||
| tee /etc/apt/sources.list.d/yarn.list; \
|
||||
\
|
||||
# Run NodeSource setup script (unchanged)
|
||||
curl -sL https://deb.nodesource.com/setup_22.x | bash -; \
|
||||
\
|
||||
# Install Node.js + Yarn
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
nodejs \
|
||||
yarn; \
|
||||
\
|
||||
# Cleanup
|
||||
apt-get -y autoremove; \
|
||||
apt-get clean autoclean; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
# Install PHP
|
||||
RUN set -eux; \
|
||||
|
|
|
|||
|
|
@ -75,10 +75,10 @@ Part-DB is also used by small companies and universities for managing their inve
|
|||
|
||||
* A **web server** (like Apache2 or nginx) that is capable of
|
||||
running [Symfony 6](https://symfony.com/doc/current/reference/requirements.html),
|
||||
this includes a minimum PHP version of **PHP 8.1**
|
||||
this includes a minimum PHP version of **PHP 8.2**
|
||||
* A **MySQL** (at least 5.7) /**MariaDB** (at least 10.4) database server, or **PostgreSQL** 10+ if you do not want to use SQLite.
|
||||
* Shell access to your server is highly recommended!
|
||||
* For building the client-side assets **yarn** and **nodejs** (>= 18.0) is needed.
|
||||
* For building the client-side assets **yarn** and **nodejs** (>= 20.0) is needed.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.17.4
|
||||
2.0.0-dev
|
||||
1
assets/ckeditor/emojis.json
Normal file
1
assets/ckeditor/emojis.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,66 +1,63 @@
|
|||
/**
|
||||
* @license Copyright (c) 2014-2022, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
|
||||
import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment.js';
|
||||
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat.js';
|
||||
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter.js';
|
||||
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote.js';
|
||||
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold.js';
|
||||
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
|
||||
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock.js';
|
||||
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
|
||||
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
|
||||
import FontBackgroundColor from '@ckeditor/ckeditor5-font/src/fontbackgroundcolor.js';
|
||||
import FontColor from '@ckeditor/ckeditor5-font/src/fontcolor.js';
|
||||
import FontFamily from '@ckeditor/ckeditor5-font/src/fontfamily.js';
|
||||
import FontSize from '@ckeditor/ckeditor5-font/src/fontsize.js';
|
||||
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';
|
||||
import Heading from '@ckeditor/ckeditor5-heading/src/heading.js';
|
||||
import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js';
|
||||
import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline.js';
|
||||
import HtmlComment from '@ckeditor/ckeditor5-html-support/src/htmlcomment.js';
|
||||
import HtmlEmbed from '@ckeditor/ckeditor5-html-embed/src/htmlembed.js';
|
||||
import Image from '@ckeditor/ckeditor5-image/src/image.js';
|
||||
import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize.js';
|
||||
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle.js';
|
||||
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar.js';
|
||||
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload.js';
|
||||
import Indent from '@ckeditor/ckeditor5-indent/src/indent.js';
|
||||
import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock.js';
|
||||
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js';
|
||||
import Link from '@ckeditor/ckeditor5-link/src/link.js';
|
||||
import LinkImage from '@ckeditor/ckeditor5-link/src/linkimage.js';
|
||||
import List from '@ckeditor/ckeditor5-list/src/list.js';
|
||||
import ListProperties from '@ckeditor/ckeditor5-list/src/listproperties.js';
|
||||
import Markdown from '@ckeditor/ckeditor5-markdown-gfm/src/markdown.js';
|
||||
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed.js';
|
||||
import MediaEmbedToolbar from '@ckeditor/ckeditor5-media-embed/src/mediaembedtoolbar.js';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
|
||||
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js';
|
||||
import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat.js';
|
||||
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
|
||||
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
|
||||
import SpecialCharactersArrows from '@ckeditor/ckeditor5-special-characters/src/specialcharactersarrows.js';
|
||||
import SpecialCharactersCurrency from '@ckeditor/ckeditor5-special-characters/src/specialcharacterscurrency.js';
|
||||
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
|
||||
import SpecialCharactersLatin from '@ckeditor/ckeditor5-special-characters/src/specialcharacterslatin.js';
|
||||
import SpecialCharactersMathematical from '@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical.js';
|
||||
import SpecialCharactersText from '@ckeditor/ckeditor5-special-characters/src/specialcharacterstext.js';
|
||||
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough.js';
|
||||
import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript.js';
|
||||
import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript.js';
|
||||
import Table from '@ckeditor/ckeditor5-table/src/table.js';
|
||||
import TableCaption from '@ckeditor/ckeditor5-table/src/tablecaption.js';
|
||||
import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
|
||||
import TableColumnResize from '@ckeditor/ckeditor5-table/src/tablecolumnresize.js';
|
||||
import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
|
||||
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js';
|
||||
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline.js';
|
||||
import WordCount from '@ckeditor/ckeditor5-word-count/src/wordcount.js';
|
||||
import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog.js';
|
||||
import {ClassicEditor} from 'ckeditor5'
|
||||
import {Alignment} from 'ckeditor5';
|
||||
import {Autoformat} from 'ckeditor5';
|
||||
import {Base64UploadAdapter} from 'ckeditor5';
|
||||
import {BlockQuote} from 'ckeditor5';
|
||||
import {Bold} from 'ckeditor5';
|
||||
import {Code} from 'ckeditor5';
|
||||
import {CodeBlock} from 'ckeditor5';
|
||||
import {Essentials} from 'ckeditor5';
|
||||
import {FindAndReplace} from 'ckeditor5';
|
||||
import {FontBackgroundColor} from 'ckeditor5';
|
||||
import {FontColor} from 'ckeditor5';
|
||||
import {FontFamily} from 'ckeditor5';
|
||||
import {FontSize} from 'ckeditor5';
|
||||
import {GeneralHtmlSupport} from 'ckeditor5';
|
||||
import {Heading} from 'ckeditor5';
|
||||
import {Highlight} from 'ckeditor5';
|
||||
import {HorizontalLine} from 'ckeditor5';
|
||||
import {HtmlComment} from 'ckeditor5';
|
||||
import {HtmlEmbed} from 'ckeditor5';
|
||||
import {Image} from 'ckeditor5';
|
||||
import {ImageResize} from 'ckeditor5';
|
||||
import {ImageStyle} from 'ckeditor5';
|
||||
import {ImageToolbar} from 'ckeditor5';
|
||||
import {ImageUpload} from 'ckeditor5';
|
||||
import {Indent} from 'ckeditor5';
|
||||
import {IndentBlock} from 'ckeditor5';
|
||||
import {Italic} from 'ckeditor5';
|
||||
import {Link} from 'ckeditor5';
|
||||
import {LinkImage} from 'ckeditor5';
|
||||
import {List} from 'ckeditor5';
|
||||
import {ListProperties} from 'ckeditor5';
|
||||
import {Markdown} from 'ckeditor5';
|
||||
import {MediaEmbed} from 'ckeditor5';
|
||||
import {MediaEmbedToolbar} from 'ckeditor5';
|
||||
import {Paragraph} from 'ckeditor5';
|
||||
import {PasteFromOffice} from 'ckeditor5';
|
||||
import {RemoveFormat} from 'ckeditor5';
|
||||
import {SourceEditing} from 'ckeditor5';
|
||||
import {SpecialCharacters} from 'ckeditor5';
|
||||
import {SpecialCharactersArrows} from 'ckeditor5';
|
||||
import {SpecialCharactersCurrency} from 'ckeditor5';
|
||||
import {SpecialCharactersEssentials} from 'ckeditor5';
|
||||
import {SpecialCharactersLatin} from 'ckeditor5';
|
||||
import {SpecialCharactersMathematical} from 'ckeditor5';
|
||||
import {SpecialCharactersText} from 'ckeditor5';
|
||||
import {Strikethrough} from 'ckeditor5';
|
||||
import {Subscript} from 'ckeditor5';
|
||||
import {Superscript} from 'ckeditor5';
|
||||
import {Table} from 'ckeditor5';
|
||||
import {TableCaption} from 'ckeditor5';
|
||||
import {TableCellProperties} from 'ckeditor5';
|
||||
import {TableColumnResize} from 'ckeditor5';
|
||||
import {TableProperties} from 'ckeditor5';
|
||||
import {TableToolbar} from 'ckeditor5';
|
||||
import {Underline} from 'ckeditor5';
|
||||
import {WordCount} from 'ckeditor5';
|
||||
import {EditorWatchdog} from 'ckeditor5';
|
||||
import PartDBLabel from "./plugins/PartDBLabel/PartDBLabel";
|
||||
import SpecialCharactersGreek from "./plugins/special_characters_emoji";
|
||||
|
||||
class Editor extends ClassicEditor {}
|
||||
|
||||
|
|
@ -122,7 +119,8 @@ Editor.builtinPlugins = [
|
|||
Underline,
|
||||
WordCount,
|
||||
|
||||
PartDBLabel
|
||||
PartDBLabel,
|
||||
SpecialCharactersGreek
|
||||
];
|
||||
|
||||
// Editor configuration.
|
||||
|
|
|
|||
|
|
@ -2,68 +2,69 @@
|
|||
* @license Copyright (c) 2014-2022, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
|
||||
import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment.js';
|
||||
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat.js';
|
||||
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter.js';
|
||||
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote.js';
|
||||
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold.js';
|
||||
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
|
||||
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock.js';
|
||||
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
|
||||
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
|
||||
import FontBackgroundColor from '@ckeditor/ckeditor5-font/src/fontbackgroundcolor.js';
|
||||
import FontColor from '@ckeditor/ckeditor5-font/src/fontcolor.js';
|
||||
import FontFamily from '@ckeditor/ckeditor5-font/src/fontfamily.js';
|
||||
import FontSize from '@ckeditor/ckeditor5-font/src/fontsize.js';
|
||||
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';
|
||||
import Heading from '@ckeditor/ckeditor5-heading/src/heading.js';
|
||||
import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js';
|
||||
import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline.js';
|
||||
import HtmlComment from '@ckeditor/ckeditor5-html-support/src/htmlcomment.js';
|
||||
import HtmlEmbed from '@ckeditor/ckeditor5-html-embed/src/htmlembed.js';
|
||||
import Image from '@ckeditor/ckeditor5-image/src/image.js';
|
||||
import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize.js';
|
||||
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle.js';
|
||||
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar.js';
|
||||
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload.js';
|
||||
import Indent from '@ckeditor/ckeditor5-indent/src/indent.js';
|
||||
import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock.js';
|
||||
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js';
|
||||
import Link from '@ckeditor/ckeditor5-link/src/link.js';
|
||||
import LinkImage from '@ckeditor/ckeditor5-link/src/linkimage.js';
|
||||
import List from '@ckeditor/ckeditor5-list/src/list.js';
|
||||
import ListProperties from '@ckeditor/ckeditor5-list/src/listproperties.js';
|
||||
import Markdown from '@ckeditor/ckeditor5-markdown-gfm/src/markdown.js';
|
||||
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed.js';
|
||||
import MediaEmbedToolbar from '@ckeditor/ckeditor5-media-embed/src/mediaembedtoolbar.js';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
|
||||
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js';
|
||||
import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat.js';
|
||||
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
|
||||
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
|
||||
import SpecialCharactersArrows from '@ckeditor/ckeditor5-special-characters/src/specialcharactersarrows.js';
|
||||
import SpecialCharactersCurrency from '@ckeditor/ckeditor5-special-characters/src/specialcharacterscurrency.js';
|
||||
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
|
||||
import SpecialCharactersLatin from '@ckeditor/ckeditor5-special-characters/src/specialcharacterslatin.js';
|
||||
import SpecialCharactersMathematical from '@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical.js';
|
||||
import SpecialCharactersText from '@ckeditor/ckeditor5-special-characters/src/specialcharacterstext.js';
|
||||
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough.js';
|
||||
import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript.js';
|
||||
import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript.js';
|
||||
import Table from '@ckeditor/ckeditor5-table/src/table.js';
|
||||
import TableCaption from '@ckeditor/ckeditor5-table/src/tablecaption.js';
|
||||
import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
|
||||
import TableColumnResize from '@ckeditor/ckeditor5-table/src/tablecolumnresize.js';
|
||||
import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
|
||||
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js';
|
||||
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline.js';
|
||||
import WordCount from '@ckeditor/ckeditor5-word-count/src/wordcount.js';
|
||||
import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog.js';
|
||||
import TodoList from '@ckeditor/ckeditor5-list/src/todolist';
|
||||
import {ClassicEditor} from 'ckeditor5';
|
||||
import {Alignment} from 'ckeditor5';
|
||||
import {Autoformat} from 'ckeditor5';
|
||||
import {Base64UploadAdapter} from 'ckeditor5';
|
||||
import {BlockQuote} from 'ckeditor5';
|
||||
import {Bold} from 'ckeditor5';
|
||||
import {Code} from 'ckeditor5';
|
||||
import {CodeBlock} from 'ckeditor5';
|
||||
import {Essentials} from 'ckeditor5';
|
||||
import {FindAndReplace} from 'ckeditor5';
|
||||
import {FontBackgroundColor} from 'ckeditor5';
|
||||
import {FontColor} from 'ckeditor5';
|
||||
import {FontFamily} from 'ckeditor5';
|
||||
import {FontSize} from 'ckeditor5';
|
||||
import {GeneralHtmlSupport} from 'ckeditor5';
|
||||
import {Heading} from 'ckeditor5';
|
||||
import {Highlight} from 'ckeditor5';
|
||||
import {HorizontalLine} from 'ckeditor5';
|
||||
import {HtmlComment} from 'ckeditor5';
|
||||
import {HtmlEmbed} from 'ckeditor5';
|
||||
import {Image} from 'ckeditor5';
|
||||
import {ImageResize} from 'ckeditor5';
|
||||
import {ImageStyle} from 'ckeditor5';
|
||||
import {ImageToolbar} from 'ckeditor5';
|
||||
import {ImageUpload} from 'ckeditor5';
|
||||
import {Indent} from 'ckeditor5';
|
||||
import {IndentBlock} from 'ckeditor5';
|
||||
import {Italic} from 'ckeditor5';
|
||||
import {Link} from 'ckeditor5';
|
||||
import {LinkImage} from 'ckeditor5';
|
||||
import {List} from 'ckeditor5';
|
||||
import {ListProperties} from 'ckeditor5';
|
||||
import {Markdown} from 'ckeditor5';
|
||||
import {MediaEmbed} from 'ckeditor5';
|
||||
import {MediaEmbedToolbar} from 'ckeditor5';
|
||||
import {Paragraph} from 'ckeditor5';
|
||||
import {PasteFromOffice} from 'ckeditor5';
|
||||
import {RemoveFormat} from 'ckeditor5';
|
||||
import {SourceEditing} from 'ckeditor5';
|
||||
import {SpecialCharacters} from 'ckeditor5';
|
||||
import {SpecialCharactersArrows} from 'ckeditor5';
|
||||
import {SpecialCharactersCurrency} from 'ckeditor5';
|
||||
import {SpecialCharactersEssentials} from 'ckeditor5';
|
||||
import {SpecialCharactersLatin} from 'ckeditor5';
|
||||
import {SpecialCharactersMathematical} from 'ckeditor5';
|
||||
import {SpecialCharactersText} from 'ckeditor5';
|
||||
import {Strikethrough} from 'ckeditor5';
|
||||
import {Subscript} from 'ckeditor5';
|
||||
import {Superscript} from 'ckeditor5';
|
||||
import {Table} from 'ckeditor5';
|
||||
import {TableCaption} from 'ckeditor5';
|
||||
import {TableCellProperties} from 'ckeditor5';
|
||||
import {TableColumnResize} from 'ckeditor5';
|
||||
import {TableProperties} from 'ckeditor5';
|
||||
import {TableToolbar} from 'ckeditor5';
|
||||
import {Underline} from 'ckeditor5';
|
||||
import {WordCount} from 'ckeditor5';
|
||||
import {EditorWatchdog} from 'ckeditor5';
|
||||
import {TodoList} from 'ckeditor5';
|
||||
|
||||
import ExtendedMarkdown from "./plugins/extendedMarkdown.js";
|
||||
import SpecialCharactersEmoji from "./plugins/special_characters_emoji";
|
||||
import SpecialCharactersGreek from "./plugins/special_characters_emoji";
|
||||
import {Mention, Emoji} from "ckeditor5";
|
||||
|
||||
class Editor extends ClassicEditor {}
|
||||
|
||||
|
|
@ -117,9 +118,11 @@ Editor.builtinPlugins = [
|
|||
Underline,
|
||||
TodoList,
|
||||
|
||||
Mention, Emoji,
|
||||
|
||||
//Our own extensions
|
||||
ExtendedMarkdown,
|
||||
SpecialCharactersEmoji
|
||||
SpecialCharactersGreek
|
||||
];
|
||||
|
||||
// Editor configuration.
|
||||
|
|
@ -148,6 +151,7 @@ Editor.defaultConfig = {
|
|||
'indent',
|
||||
'|',
|
||||
'specialCharacters',
|
||||
"emoji",
|
||||
'horizontalLine',
|
||||
'|',
|
||||
'imageUpload',
|
||||
|
|
|
|||
|
|
@ -2,35 +2,36 @@
|
|||
* @license Copyright (c) 2014-2022, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
|
||||
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat.js';
|
||||
import AutoLink from '@ckeditor/ckeditor5-link/src/autolink.js';
|
||||
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold.js';
|
||||
import Code from '@ckeditor/ckeditor5-basic-styles/src/code.js';
|
||||
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
|
||||
import FindAndReplace from '@ckeditor/ckeditor5-find-and-replace/src/findandreplace.js';
|
||||
import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js';
|
||||
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js';
|
||||
import Link from '@ckeditor/ckeditor5-link/src/link.js';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
|
||||
import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat.js';
|
||||
import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting.js';
|
||||
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters.js';
|
||||
import SpecialCharactersArrows from '@ckeditor/ckeditor5-special-characters/src/specialcharactersarrows.js';
|
||||
import SpecialCharactersCurrency from '@ckeditor/ckeditor5-special-characters/src/specialcharacterscurrency.js';
|
||||
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js';
|
||||
import SpecialCharactersLatin from '@ckeditor/ckeditor5-special-characters/src/specialcharacterslatin.js';
|
||||
import SpecialCharactersMathematical from '@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical.js';
|
||||
import SpecialCharactersText from '@ckeditor/ckeditor5-special-characters/src/specialcharacterstext.js';
|
||||
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough.js';
|
||||
import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript.js';
|
||||
import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript.js';
|
||||
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline.js';
|
||||
import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog.js';
|
||||
import {ClassicEditor} from 'ckeditor5';
|
||||
import {Autoformat} from 'ckeditor5';
|
||||
import {AutoLink} from 'ckeditor5';
|
||||
import {Bold} from 'ckeditor5';
|
||||
import {Code} from 'ckeditor5';
|
||||
import {Essentials} from 'ckeditor5';
|
||||
import {FindAndReplace} from 'ckeditor5';
|
||||
import {Highlight} from 'ckeditor5';
|
||||
import {Italic} from 'ckeditor5';
|
||||
import {Link} from 'ckeditor5';
|
||||
import {Paragraph} from 'ckeditor5';
|
||||
import {RemoveFormat} from 'ckeditor5';
|
||||
import {SourceEditing} from 'ckeditor5';
|
||||
import {SpecialCharacters} from 'ckeditor5';
|
||||
import {SpecialCharactersArrows} from 'ckeditor5';
|
||||
import {SpecialCharactersCurrency} from 'ckeditor5';
|
||||
import {SpecialCharactersEssentials} from 'ckeditor5';
|
||||
import {SpecialCharactersLatin} from 'ckeditor5';
|
||||
import {SpecialCharactersMathematical} from 'ckeditor5';
|
||||
import {SpecialCharactersText} from 'ckeditor5';
|
||||
import {Strikethrough} from 'ckeditor5';
|
||||
import {Subscript} from 'ckeditor5';
|
||||
import {Superscript} from 'ckeditor5';
|
||||
import {Underline} from 'ckeditor5';
|
||||
import {EditorWatchdog} from 'ckeditor5';
|
||||
import {Mention, Emoji} from "ckeditor5";
|
||||
|
||||
import ExtendedMarkdownInline from "./plugins/extendedMarkdownInline";
|
||||
import SingleLinePlugin from "./plugins/singleLine";
|
||||
import SpecialCharactersEmoji from "./plugins/special_characters_emoji";
|
||||
import SpecialCharactersGreek from "./plugins/special_characters_emoji";
|
||||
|
||||
class Editor extends ClassicEditor {}
|
||||
|
||||
|
|
@ -62,7 +63,8 @@ Editor.builtinPlugins = [
|
|||
|
||||
ExtendedMarkdownInline,
|
||||
SingleLinePlugin,
|
||||
SpecialCharactersEmoji
|
||||
SpecialCharactersGreek,
|
||||
Mention, Emoji
|
||||
];
|
||||
|
||||
// Editor configuration.
|
||||
|
|
@ -81,6 +83,7 @@ Editor.defaultConfig = {
|
|||
'link',
|
||||
'code',
|
||||
'specialCharacters',
|
||||
'emoji',
|
||||
'|',
|
||||
'undo',
|
||||
'redo',
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import PartDBLabelEditing from "./PartDBLabelEditing";
|
|||
|
||||
import "./PartDBLabel.css";
|
||||
|
||||
import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
|
||||
import {Plugin} from "ckeditor5";
|
||||
|
||||
export default class PartDBLabel extends Plugin {
|
||||
static get requires() {
|
||||
|
|
@ -32,4 +32,4 @@ export default class PartDBLabel extends Plugin {
|
|||
static get pluginName() {
|
||||
return 'PartDBLabel';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Command from '@ckeditor/ckeditor5-core/src/command';
|
||||
import {Command} from 'ckeditor5';
|
||||
|
||||
export default class PartDBLabelCommand extends Command {
|
||||
execute( { value } ) {
|
||||
|
|
@ -47,4 +47,4 @@ export default class PartDBLabelCommand extends Command {
|
|||
|
||||
this.isEnabled = isAllowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
||||
import {Plugin} from 'ckeditor5';
|
||||
import PartDBLabelCommand from "./PartDBLabelCommand";
|
||||
|
||||
import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
|
||||
import Widget from '@ckeditor/ckeditor5-widget/src/widget';
|
||||
import { toWidget } from 'ckeditor5';
|
||||
import {Widget} from 'ckeditor5';
|
||||
|
||||
export default class PartDBLabelEditing extends Plugin {
|
||||
static get requires() { // ADDED
|
||||
|
|
@ -102,4 +102,4 @@ export default class PartDBLabelEditing extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
||||
import {Plugin} from 'ckeditor5';
|
||||
|
||||
require('./lang/de.js');
|
||||
|
||||
import { addListToDropdown, createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
|
||||
import { addListToDropdown, createDropdown } from 'ckeditor5';
|
||||
|
||||
import Collection from '@ckeditor/ckeditor5-utils/src/collection';
|
||||
import Model from '@ckeditor/ckeditor5-ui/src/model';
|
||||
import {Collection} from 'ckeditor5';
|
||||
import {Model} from 'ckeditor5';
|
||||
|
||||
export default class PartDBLabelUI extends Plugin {
|
||||
init() {
|
||||
|
|
@ -187,4 +187,4 @@ function getDropdownItemsDefinitions(t) {
|
|||
}
|
||||
|
||||
return itemDefinitions;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Plugin } from 'ckeditor5/src/core';
|
||||
import GFMDataProcessor from '@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor';
|
||||
import { Plugin, MarkdownGfmDataProcessor } from 'ckeditor5';
|
||||
|
||||
const ALLOWED_TAGS = [
|
||||
//Common elements
|
||||
|
|
@ -34,7 +33,6 @@ const ALLOWED_TAGS = [
|
|||
|
||||
//Block elements
|
||||
'span',
|
||||
'p',
|
||||
'img',
|
||||
|
||||
|
||||
|
|
@ -57,7 +55,7 @@ export default class ExtendedMarkdown extends Plugin {
|
|||
constructor( editor ) {
|
||||
super( editor );
|
||||
|
||||
editor.data.processor = new GFMDataProcessor( editor.data.viewDocument );
|
||||
editor.data.processor = new MarkdownGfmDataProcessor( editor.data.viewDocument );
|
||||
for (const tag of ALLOWED_TAGS) {
|
||||
editor.data.processor.keepHtml(tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Plugin } from 'ckeditor5/src/core';
|
||||
import GFMDataProcessor from '@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor';
|
||||
import {Plugin} from 'ckeditor5';
|
||||
import {MarkdownGfmDataProcessor} from 'ckeditor5';
|
||||
|
||||
const ALLOWED_TAGS = [
|
||||
//Common elements
|
||||
|
|
@ -46,7 +46,7 @@ export default class ExtendedMarkdownInline extends Plugin {
|
|||
constructor( editor ) {
|
||||
super( editor );
|
||||
|
||||
editor.data.processor = new GFMDataProcessor( editor.data.viewDocument );
|
||||
editor.data.processor = new MarkdownGfmDataProcessor( editor.data.viewDocument );
|
||||
for (const tag of ALLOWED_TAGS) {
|
||||
editor.data.processor.keepHtml(tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
||||
import {Plugin} from 'ckeditor5';
|
||||
|
||||
export default class SingleLinePlugin extends Plugin {
|
||||
init() {
|
||||
|
|
@ -42,7 +42,7 @@ export default class SingleLinePlugin extends Plugin {
|
|||
//We can not use the dataTransfer.setData method because the old object is somehow protected
|
||||
data.dataTransfer = new DataTransfer();
|
||||
data.dataTransfer.setData("text", cleaned);
|
||||
|
||||
|
||||
}, { priority: 'high' } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,12 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import SpecialCharacters from '@ckeditor/ckeditor5-special-characters/src/specialcharacters';
|
||||
import SpecialCharactersEssentials from '@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials';
|
||||
import SpecialCharacters from 'ckeditor5';
|
||||
import SpecialCharactersEssentials from 'ckeditor5';
|
||||
|
||||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
||||
import {Plugin} from 'ckeditor5';
|
||||
|
||||
const emoji = require('emoji.json');
|
||||
|
||||
export default class SpecialCharactersEmoji extends Plugin {
|
||||
export default class SpecialCharactersGreek extends Plugin {
|
||||
|
||||
init() {
|
||||
const editor = this.editor;
|
||||
|
|
@ -32,9 +30,6 @@ export default class SpecialCharactersEmoji extends Plugin {
|
|||
|
||||
//Add greek characters to special characters
|
||||
specialCharsPlugin.addItems('Greek', this.getGreek());
|
||||
|
||||
//Add Emojis to special characters
|
||||
specialCharsPlugin.addItems('Emoji', this.getEmojis());
|
||||
}
|
||||
|
||||
getGreek() {
|
||||
|
|
@ -96,14 +91,4 @@ export default class SpecialCharactersEmoji extends Plugin {
|
|||
{ title: 'san', character: 'Ϻ' },
|
||||
];
|
||||
}
|
||||
|
||||
getEmojis() {
|
||||
//Map our emoji data to the format the plugin expects
|
||||
return emoji.map(emoji => {
|
||||
return {
|
||||
title: emoji.name,
|
||||
character: emoji.char
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
{
|
||||
"controllers": {
|
||||
"@symfony/ux-toggle-password": {
|
||||
"toggle-password": {
|
||||
"enabled": true,
|
||||
"fetch": "eager",
|
||||
"autoimport": {
|
||||
"@symfony/ux-toggle-password/dist/style.min.css": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@symfony/ux-turbo": {
|
||||
"turbo-core": {
|
||||
"enabled": true,
|
||||
|
|
|
|||
79
assets/controllers/csrf_protection_controller.js
Normal file
79
assets/controllers/csrf_protection_controller.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
|
||||
const tokenCheck = /^[-_/+a-zA-Z0-9]{24,}$/;
|
||||
|
||||
// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
|
||||
document.addEventListener('submit', function (event) {
|
||||
generateCsrfToken(event.target);
|
||||
}, true);
|
||||
|
||||
// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
|
||||
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
|
||||
document.addEventListener('turbo:submit-start', function (event) {
|
||||
const h = generateCsrfHeaders(event.detail.formSubmission.formElement);
|
||||
Object.keys(h).map(function (k) {
|
||||
event.detail.formSubmission.fetchRequest.headers[k] = h[k];
|
||||
});
|
||||
});
|
||||
|
||||
// When @hotwired/turbo handles form submissions, remove the CSRF cookie once a form has been submitted
|
||||
document.addEventListener('turbo:submit-end', function (event) {
|
||||
removeCsrfToken(event.detail.formSubmission.formElement);
|
||||
});
|
||||
|
||||
export function generateCsrfToken (formElement) {
|
||||
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
|
||||
|
||||
if (!csrfField) {
|
||||
return;
|
||||
}
|
||||
|
||||
let csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
|
||||
let csrfToken = csrfField.value;
|
||||
|
||||
if (!csrfCookie && nameCheck.test(csrfToken)) {
|
||||
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
|
||||
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
|
||||
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
|
||||
if (csrfCookie && tokenCheck.test(csrfToken)) {
|
||||
const cookie = csrfCookie + '_' + csrfToken + '=' + csrfCookie + '; path=/; samesite=strict';
|
||||
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
|
||||
}
|
||||
}
|
||||
|
||||
export function generateCsrfHeaders (formElement) {
|
||||
const headers = {};
|
||||
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
|
||||
|
||||
if (!csrfField) {
|
||||
return headers;
|
||||
}
|
||||
|
||||
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
|
||||
|
||||
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
|
||||
headers[csrfCookie] = csrfField.value;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
export function removeCsrfToken (formElement) {
|
||||
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
|
||||
|
||||
if (!csrfField) {
|
||||
return;
|
||||
}
|
||||
|
||||
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
|
||||
|
||||
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
|
||||
const cookie = csrfCookie + '_' + csrfField.value + '=0; path=/; samesite=strict; max-age=0';
|
||||
|
||||
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
|
||||
}
|
||||
}
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
export default 'csrf-protection-controller';
|
||||
|
|
@ -23,8 +23,9 @@ import { default as FullEditor } from "../../ckeditor/markdown_full";
|
|||
import { default as SingleLineEditor} from "../../ckeditor/markdown_single_line";
|
||||
import { default as HTMLLabelEditor } from "../../ckeditor/html_label";
|
||||
|
||||
import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog';
|
||||
import {EditorWatchdog} from 'ckeditor5';
|
||||
|
||||
import "ckeditor5/ckeditor5.css";;
|
||||
import "../../css/components/ckeditor.css";
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
|
|
@ -51,9 +52,15 @@ export default class extends Controller {
|
|||
|
||||
const language = document.body.dataset.locale ?? "en";
|
||||
|
||||
const emojiURL = new URL('../../ckeditor/emojis.json', import.meta.url).href;
|
||||
|
||||
const config = {
|
||||
language: language,
|
||||
licenseKey: "GPL",
|
||||
|
||||
emoji: {
|
||||
definitionsUrl: emojiURL
|
||||
}
|
||||
}
|
||||
|
||||
const watchdog = new EditorWatchdog();
|
||||
|
|
@ -84,4 +91,4 @@ export default class extends Controller {
|
|||
console.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export default class extends Controller {
|
|||
|
||||
|
||||
let settings = {
|
||||
plugins: ["clear_button"],
|
||||
allowEmptyOption: true,
|
||||
selectOnTab: true,
|
||||
maxOptions: null,
|
||||
|
|
@ -50,7 +51,24 @@ export default class extends Controller {
|
|||
}
|
||||
};
|
||||
|
||||
//Load the drag_drop plugin if the select is ordered
|
||||
if (this.element.dataset.orderedValue) {
|
||||
settings.plugins.push('drag_drop');
|
||||
settings.plugins.push("caret_position");
|
||||
}
|
||||
|
||||
//If multiple items can be selected, enable the remove_button plugin
|
||||
if (this.element.multiple) {
|
||||
settings.plugins.push('remove_button');
|
||||
}
|
||||
|
||||
this._tomSelect = new TomSelect(this.element, settings);
|
||||
|
||||
//If the select is ordered, we need to update the value field (with the decoded value from the orderedValue field)
|
||||
if (this.element.dataset.orderedValue) {
|
||||
const data = JSON.parse(this.element.dataset.orderedValue);
|
||||
this._tomSelect.setValue(data);
|
||||
}
|
||||
}
|
||||
|
||||
getTomSelect() {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
import {Controller} from "@hotwired/stimulus";
|
||||
import TomSelect from "tom-select";
|
||||
|
||||
// TODO: Merge with select_controller.js
|
||||
|
||||
export default class extends Controller {
|
||||
_tomSelect;
|
||||
|
||||
|
|
|
|||
|
|
@ -120,4 +120,11 @@ ins {
|
|||
del {
|
||||
background-color: #f09595;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Password toggle
|
||||
****************************************/
|
||||
.toggle-password-button {
|
||||
top: 0.7rem !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ window.$ = window.jQuery = require("jquery");
|
|||
//Use the local WASM file for the ZXing library
|
||||
import {
|
||||
setZXingModuleOverrides,
|
||||
} from "barcode-detector/pure";
|
||||
} from "barcode-detector/ponyfill";
|
||||
import wasmFile from "../../node_modules/zxing-wasm/dist/reader/zxing_reader.wasm";
|
||||
setZXingModuleOverrides({
|
||||
locateFile: (path, prefix) => {
|
||||
|
|
@ -58,4 +58,4 @@ setZXingModuleOverrides({
|
|||
}
|
||||
return prefix + path;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"type": "project",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"php": "^8.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
|
|
@ -12,9 +12,11 @@
|
|||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"amphp/http-client": "^5.1",
|
||||
"api-platform/core": "^3.1",
|
||||
"api-platform/doctrine-orm": "^4.1",
|
||||
"api-platform/json-api": "^4.0.0",
|
||||
"api-platform/symfony": "^4.0.0",
|
||||
"beberlei/doctrineextensions": "^1.2",
|
||||
"brick/math": "0.12.1 as 0.11.0",
|
||||
"brick/math": "^0.13.1",
|
||||
"composer/ca-bundle": "^1.5",
|
||||
"composer/package-versions-deprecated": "^1.11.99.5",
|
||||
"doctrine/data-fixtures": "^2.0.0",
|
||||
|
|
@ -23,66 +25,69 @@
|
|||
"doctrine/doctrine-migrations-bundle": "^3.0",
|
||||
"doctrine/orm": "^3.2.0",
|
||||
"dompdf/dompdf": "^v3.0.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"florianv/swap": "^4.0",
|
||||
"florianv/swap-bundle": "dev-master",
|
||||
"gregwar/captcha-bundle": "^2.1.0",
|
||||
"hshn/base64-encoded-file": "^5.0",
|
||||
"jbtronics/2fa-webauthn": "^v2.2.0",
|
||||
"jbtronics/2fa-webauthn": "^3.0.0",
|
||||
"jbtronics/dompdf-font-loader-bundle": "^1.0.0",
|
||||
"jbtronics/settings-bundle": "^3.0.0",
|
||||
"jfcherng/php-diff": "^6.14",
|
||||
"knpuniversity/oauth2-client-bundle": "^2.15",
|
||||
"league/commonmark": "^2.7",
|
||||
"league/csv": "^9.8.0",
|
||||
"league/html-to-markdown": "^5.0.1",
|
||||
"liip/imagine-bundle": "^2.2",
|
||||
"nbgrp/onelogin-saml-bundle": "^1.3",
|
||||
"nbgrp/onelogin-saml-bundle": "^v2.0.2",
|
||||
"nelexa/zip": "^4.0",
|
||||
"nelmio/cors-bundle": "^2.3",
|
||||
"nelmio/security-bundle": "^3.0",
|
||||
"nyholm/psr7": "^1.1",
|
||||
"omines/datatables-bundle": "^0.9.1",
|
||||
"omines/datatables-bundle": "^0.10.0",
|
||||
"paragonie/sodium_compat": "^1.21",
|
||||
"part-db/label-fonts": "^1.0",
|
||||
"rhukster/dom-sanitizer": "^1.0",
|
||||
"runtime/frankenphp-symfony": "^0.2.0",
|
||||
"s9e/text-formatter": "^2.1",
|
||||
"scheb/2fa-backup-code": "^6.8.0",
|
||||
"scheb/2fa-bundle": "^6.8.0",
|
||||
"scheb/2fa-google-authenticator": "^6.8.0",
|
||||
"scheb/2fa-trusted-device": "^6.8.0",
|
||||
"scheb/2fa-backup-code": "^v7.11.0",
|
||||
"scheb/2fa-bundle": "^v7.11.0",
|
||||
"scheb/2fa-google-authenticator": "^v7.11.0",
|
||||
"scheb/2fa-trusted-device": "^v7.11.0",
|
||||
"shivas/versioning-bundle": "^4.0",
|
||||
"spatie/db-dumper": "^3.3.1",
|
||||
"symfony/apache-pack": "^1.0",
|
||||
"symfony/asset": "6.4.*",
|
||||
"symfony/console": "6.4.*",
|
||||
"symfony/css-selector": "6.4.*",
|
||||
"symfony/dom-crawler": "6.4.*",
|
||||
"symfony/dotenv": "6.4.*",
|
||||
"symfony/expression-language": "6.4.*",
|
||||
"symfony/asset": "7.3.*",
|
||||
"symfony/console": "7.3.*",
|
||||
"symfony/css-selector": "7.3.*",
|
||||
"symfony/dom-crawler": "7.3.*",
|
||||
"symfony/dotenv": "7.3.*",
|
||||
"symfony/expression-language": "7.3.*",
|
||||
"symfony/flex": "^v2.3.1",
|
||||
"symfony/form": "6.4.*",
|
||||
"symfony/framework-bundle": "6.4.*",
|
||||
"symfony/http-client": "6.4.*",
|
||||
"symfony/http-kernel": "6.4.*",
|
||||
"symfony/mailer": "6.4.*",
|
||||
"symfony/form": "7.3.*",
|
||||
"symfony/framework-bundle": "7.3.*",
|
||||
"symfony/http-client": "7.3.*",
|
||||
"symfony/http-kernel": "7.3.*",
|
||||
"symfony/mailer": "7.3.*",
|
||||
"symfony/monolog-bundle": "^3.1",
|
||||
"symfony/polyfill-php82": "^1.28",
|
||||
"symfony/process": "6.4.*",
|
||||
"symfony/property-access": "6.4.*",
|
||||
"symfony/property-info": "6.4.*",
|
||||
"symfony/rate-limiter": "6.4.*",
|
||||
"symfony/runtime": "6.4.*",
|
||||
"symfony/security-bundle": "6.4.*",
|
||||
"symfony/serializer": "6.4.*",
|
||||
"symfony/string": "6.4.*",
|
||||
"symfony/translation": "6.4.*",
|
||||
"symfony/twig-bundle": "6.4.*",
|
||||
"symfony/process": "7.3.*",
|
||||
"symfony/property-access": "7.3.*",
|
||||
"symfony/property-info": "7.3.*",
|
||||
"symfony/rate-limiter": "7.3.*",
|
||||
"symfony/runtime": "7.3.*",
|
||||
"symfony/security-bundle": "7.3.*",
|
||||
"symfony/serializer": "7.3.*",
|
||||
"symfony/string": "7.3.*",
|
||||
"symfony/translation": "7.3.*",
|
||||
"symfony/twig-bundle": "7.3.*",
|
||||
"symfony/ux-toggle-password": "^2.29",
|
||||
"symfony/ux-translator": "^2.10",
|
||||
"symfony/ux-turbo": "^2.0",
|
||||
"symfony/validator": "6.4.*",
|
||||
"symfony/web-link": "6.4.*",
|
||||
"symfony/validator": "7.3.*",
|
||||
"symfony/web-link": "7.3.*",
|
||||
"symfony/webpack-encore-bundle": "^v2.0.1",
|
||||
"symfony/yaml": "6.4.*",
|
||||
"symfony/yaml": "7.3.*",
|
||||
"symplify/easy-coding-standard": "^12.5.20",
|
||||
"tecnickcom/tc-lib-barcode": "^2.1.4",
|
||||
"twig/cssinliner-extra": "^3.0",
|
||||
"twig/extra-bundle": "^3.8",
|
||||
|
|
@ -91,7 +96,7 @@
|
|||
"twig/intl-extra": "^3.8",
|
||||
"twig/markdown-extra": "^3.8",
|
||||
"twig/string-extra": "^3.8",
|
||||
"web-auth/webauthn-symfony-bundle": "^4.0.0"
|
||||
"web-auth/webauthn-symfony-bundle": "^5.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dama/doctrine-test-bundle": "^v8.0.0",
|
||||
|
|
@ -103,16 +108,15 @@
|
|||
"phpstan/phpstan-doctrine": "^2.0.1",
|
||||
"phpstan/phpstan-strict-rules": "^2.0.1",
|
||||
"phpstan/phpstan-symfony": "^2.0.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"phpunit/phpunit": "^11.5.0",
|
||||
"rector/rector": "^2.0.4",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"symfony/browser-kit": "6.4.*",
|
||||
"symfony/debug-bundle": "6.4.*",
|
||||
"symfony/browser-kit": "7.3.*",
|
||||
"symfony/debug-bundle": "7.3.*",
|
||||
"symfony/maker-bundle": "^1.13",
|
||||
"symfony/phpunit-bridge": "6.4.*",
|
||||
"symfony/stopwatch": "6.4.*",
|
||||
"symfony/web-profiler-bundle": "6.4.*",
|
||||
"symplify/easy-coding-standard": "^12.0"
|
||||
"symfony/phpunit-bridge": "7.3.*",
|
||||
"symfony/stopwatch": "7.3.*",
|
||||
"symfony/web-profiler-bundle": "7.3.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Used to improve price calculation performance",
|
||||
|
|
@ -123,7 +127,7 @@
|
|||
"*": "dist"
|
||||
},
|
||||
"platform": {
|
||||
"php": "8.1.0"
|
||||
"php": "8.2.0"
|
||||
},
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
|
|
@ -163,7 +167,7 @@
|
|||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "6.4.*",
|
||||
"require": "7.3.*",
|
||||
"docker": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5754
composer.lock
generated
5754
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,14 +1,4 @@
|
|||
Welcome to Part-DB.
|
||||
|
||||
<small>If you want to change this banner, edit `config/banner.md` file or set the `BANNER` environment variable.</small>
|
||||
**Attention**:
|
||||
Since Version 2.0.0 this file is no longer used.
|
||||
|
||||
<blockquote class="pb-0">
|
||||
<p style="font-size: 12px">
|
||||
And God said <br>
|
||||
$\nabla \cdot \vec{D} = \rho$,
|
||||
$\nabla \cdot \vec{B} = 0$,
|
||||
$\nabla \times \vec{E} = -\frac{\partial \vec{B}}{\partial t}$,
|
||||
$\nabla \times \vec{H} = \vec{j} + \frac{\partial \vec{D}}{\partial t}$, <br>
|
||||
and then there was light.
|
||||
</p>
|
||||
</blockquote>
|
||||
You can now set the banner text directly in the admin interface, or by setting the `BANNER` environment variable.
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ return [
|
|||
Jbtronics\DompdfFontLoaderBundle\DompdfFontLoaderBundle::class => ['all' => true],
|
||||
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
|
||||
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||
Jbtronics\SettingsBundle\JbtronicsSettingsBundle::class => ['all' => true],
|
||||
Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
|
||||
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||
Symfony\UX\TogglePassword\TogglePasswordBundle::class => ['all' => true],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -32,10 +32,9 @@ api_platform:
|
|||
|
||||
pagination_client_items_per_page: true # Allow clients to override the default items per page
|
||||
|
||||
keep_legacy_inflector: false
|
||||
# Need to be true, or some tests will fail
|
||||
use_symfony_listeners: true
|
||||
|
||||
serializer:
|
||||
# Change this to false later, to remove the hydra prefix on the API
|
||||
hydra_prefix: true
|
||||
hydra_prefix: true
|
||||
|
|
|
|||
12
config/packages/csrf.yaml
Normal file
12
config/packages/csrf.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Enable stateless CSRF protection for forms and logins/logouts
|
||||
framework:
|
||||
form:
|
||||
csrf_protection:
|
||||
token_id: submit
|
||||
|
||||
csrf_protection:
|
||||
check_header: true
|
||||
stateless_token_ids:
|
||||
- submit
|
||||
- authenticate
|
||||
- logout
|
||||
|
|
@ -9,7 +9,8 @@ datatables:
|
|||
# Set options, as documented at https://datatables.net/reference/option/
|
||||
options:
|
||||
lengthMenu : [[10, 25, 50, 100], [10, 25, 50, 100]] # We add the "All" option, when part tables are generated
|
||||
pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
|
||||
#pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
|
||||
pageLength: 50 #TODO
|
||||
dom: " <'row' <'col mb-2 input-group flex-nowrap' B l > <'col-auto mb-2' < p >>>
|
||||
<'card'
|
||||
rt
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ doctrine:
|
|||
tinyint:
|
||||
class: App\Doctrine\Types\TinyIntType
|
||||
|
||||
# This was removed in doctrine/orm 4.0 but we need it for the WebauthnKey entity
|
||||
array:
|
||||
class: App\Doctrine\Types\ArrayType
|
||||
|
||||
schema_filter: ~^(?!internal)~
|
||||
# Only enable this when needed
|
||||
profiling_collect_backtrace: false
|
||||
|
|
@ -39,6 +35,8 @@ doctrine:
|
|||
report_fields_where_declared: true
|
||||
validate_xml_mapping: true
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||
identity_generation_preferences:
|
||||
Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
|
||||
auto_mapping: true
|
||||
controller_resolver:
|
||||
auto_mapping: true
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
csrf_protection: true
|
||||
annotations: false
|
||||
handle_all_throwables: true
|
||||
|
||||
# We set this header by ourselves, so we can disable it here
|
||||
disallow_search_engine_index: false
|
||||
|
|
@ -30,8 +27,11 @@ framework:
|
|||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
|
||||
form: { csrf_protection: { token_id: 'submit' } }
|
||||
csrf_protection:
|
||||
stateless_token_ids: ['submit', 'authenticate', 'logout']
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ knpu_oauth2_client:
|
|||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_DIGIKEY_SECRET)%'
|
||||
client_id: '%env(settings:digikey:clientId)%'
|
||||
client_secret: '%env(settings:digikey:secret)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: {name: 'ip_digikey_oauth'}
|
||||
|
|
@ -26,8 +26,8 @@ knpu_oauth2_client:
|
|||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_OCTOPART_SECRET)%'
|
||||
client_id: '%env(settings:octopart:clientId)%'
|
||||
client_secret: '%env(settings:octopart:secret)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: { name: 'ip_octopart_oauth' }
|
||||
|
|
|
|||
3
config/packages/property_info.yaml
Normal file
3
config/packages/property_info.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
framework:
|
||||
property_info:
|
||||
with_constructor_extractor: true
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
default_uri: '%env(DEFAULT_URI)%'
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ security:
|
|||
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js|\.well-known)/
|
||||
security: false
|
||||
main:
|
||||
provider: app_user_provider
|
||||
|
|
|
|||
8
config/packages/settings.yaml
Normal file
8
config/packages/settings.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
jbtronics_settings:
|
||||
default_storage_adapter: Jbtronics\SettingsBundle\Storage\ORMStorageAdapter
|
||||
|
||||
cache:
|
||||
default_cacheable: true
|
||||
|
||||
orm_storage:
|
||||
default_entity_class: App\Entity\SettingsEntry
|
||||
|
|
@ -6,5 +6,5 @@ florianv_swap:
|
|||
providers:
|
||||
european_central_bank: ~ # European Central Bank (only works for EUR base currency)
|
||||
fixer: # Fixer.io (needs an API key)
|
||||
access_key: "%env(FIXER_API_KEY)%"
|
||||
access_key: "%env(string:default:settings:exchange_rate:fixerApiKey:INVALID)%"
|
||||
#exchange_rates_api: ~
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
framework:
|
||||
default_locale: '%partdb.locale%'
|
||||
default_locale: 'en'
|
||||
# Just enable the locales we need for performance reasons.
|
||||
enabled_locale: '%partdb.locale_menu%'
|
||||
translator:
|
||||
default_path: '%kernel.project_dir%/translations'
|
||||
fallbacks:
|
||||
- '%partdb.locale%'
|
||||
- 'en'
|
||||
providers:
|
||||
# crowdin:
|
||||
|
|
|
|||
|
|
@ -6,22 +6,17 @@ twig:
|
|||
'%kernel.project_dir%/assets/css': css
|
||||
|
||||
globals:
|
||||
partdb_title: '%partdb.title%'
|
||||
default_currency: '%partdb.default_currency%'
|
||||
global_theme: '%partdb.global_theme%'
|
||||
allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
||||
locale_menu: '%partdb.locale_menu%'
|
||||
attachment_manager: '@App\Services\Attachments\AttachmentManager'
|
||||
label_profile_dropdown_helper: '@App\Services\LabelSystem\LabelProfileDropdownHelper'
|
||||
error_page_admin_email: '%partdb.error_pages.admin_email%'
|
||||
error_page_show_help: '%partdb.error_pages.show_help%'
|
||||
sidebar_items: '%partdb.sidebar.items%'
|
||||
sidebar_tree_updater: '@App\Services\Trees\SidebarTreeUpdater'
|
||||
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
|
||||
available_themes: '%partdb.available_themes%'
|
||||
saml_enabled: '%partdb.saml.enabled%'
|
||||
part_preview_generator: '@App\Services\Attachments\PartPreviewGenerator'
|
||||
img_overlay: '%partdb.show_part_image_overlay%'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
framework:
|
||||
uid:
|
||||
default_uuid_version: 7
|
||||
time_based_uuid_version: 7
|
||||
4
config/packages/ux_turbo.yaml
Normal file
4
config/packages/ux_turbo.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Enable stateless CSRF protection for forms and logins/logouts
|
||||
framework:
|
||||
csrf_protection:
|
||||
check_header: true
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
framework:
|
||||
validation:
|
||||
email_validation_mode: html5
|
||||
|
||||
# Enables validator auto-mapping support.
|
||||
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
|
||||
#auto_mapping:
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
when@dev:
|
||||
web_profiler:
|
||||
toolbar: true
|
||||
intercept_redirects: false
|
||||
toolbar:
|
||||
ajax_replace: true
|
||||
|
||||
framework:
|
||||
profiler:
|
||||
only_exceptions: false
|
||||
collect_serializer_data: true
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { collect: false }
|
||||
profiler:
|
||||
collect: false
|
||||
collect_serializer_data: true
|
||||
|
|
|
|||
|
|
@ -5,14 +5,10 @@ parameters:
|
|||
######################################################################################################################
|
||||
# Common
|
||||
######################################################################################################################
|
||||
partdb.locale: '%env(string:DEFAULT_LANG)%' # The default language to use serverwide
|
||||
partdb.timezone: '%env(string:DEFAULT_TIMEZONE)%' # The default timezone
|
||||
partdb.title: '%env(trim:string:INSTANCE_NAME)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
|
||||
partdb.banner: '%env(trim:string:BANNER)%' # The info text shown in the homepage, if empty config/banner.md is used
|
||||
partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
||||
partdb.global_theme: '' # The theme to use globally (see public/build/themes/ for choices, use name without .css). Set to '' for default bootstrap theme
|
||||
|
||||
# This is used as workaround for places where we can not access the settings directly (like the 2FA application names)
|
||||
partdb.title: '%env(string:settings:customization:instanceName)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
|
||||
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh', 'pl'] # The languages that are shown in user drop down menu
|
||||
partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all.
|
||||
|
||||
partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails
|
||||
|
||||
|
|
@ -22,11 +18,8 @@ parameters:
|
|||
# Users and Privacy
|
||||
######################################################################################################################
|
||||
partdb.gdpr_compliance: true # If this option is activated, IP addresses are anonymized to be GDPR compliant
|
||||
partdb.users.use_gravatar: '%env(bool:USE_GRAVATAR)%' # Set to false, if no Gravatar images should be used for user profiles.
|
||||
partdb.users.email_pw_reset: '%env(bool:ALLOW_EMAIL_PW_RESET)%' # Config if users are able, to reset their password by email. By default this enabled, when a mail server is configured.
|
||||
|
||||
partdb.check_for_updates: '%env(bool:CHECK_FOR_UPDATES)' # Set to false, if Part-DB should not contact the GitHub API to check for updates
|
||||
|
||||
######################################################################################################################
|
||||
# Mail settings
|
||||
######################################################################################################################
|
||||
|
|
@ -36,11 +29,8 @@ parameters:
|
|||
######################################################################################################################
|
||||
# Attachments and files
|
||||
######################################################################################################################
|
||||
partdb.attachments.allow_downloads: '%env(bool:ALLOW_ATTACHMENT_DOWNLOADS)%' # Allow users to download attachments to server. Warning: This can be dangerous, because via that feature attackers maybe can access ressources on your intranet!
|
||||
partdb.attachments.download_by_default: '%env(bool:ATTACHMENT_DOWNLOAD_BY_DEFAULT)%' # If this is set the 'download external files' checkbox is set by default for new attachments (only if allow_downloads is set to true)
|
||||
partdb.attachments.dir.media: 'public/media/' # The folder where uploaded attachment files are saved (must be in public folder)
|
||||
partdb.attachments.dir.secure: 'uploads/' # The folder where secured attachment files are saved (must not be in public/)
|
||||
partdb.attachments.max_file_size: '%env(string:MAX_ATTACHMENT_FILE_SIZE)%' # The maximum size of an attachment file (in bytes, you can use M for megabytes and G for gigabytes)
|
||||
|
||||
######################################################################################################################
|
||||
# Error pages
|
||||
|
|
@ -53,28 +43,11 @@ parameters:
|
|||
######################################################################################################################
|
||||
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
||||
|
||||
######################################################################################################################
|
||||
# Table settings
|
||||
######################################################################################################################
|
||||
partdb.table.default_page_size: '%env(int:TABLE_DEFAULT_PAGE_SIZE)%' # The default number of entries shown per page in tables
|
||||
partdb.table.parts.default_columns: '%env(trim:string:TABLE_PARTS_DEFAULT_COLUMNS)%' # The default columns in part tables and their order
|
||||
|
||||
######################################################################################################################
|
||||
# Sidebar
|
||||
######################################################################################################################
|
||||
# You can configures the default shown tree items in the sidebar here. You can add or remove entries here, to change the number of trees in the sidebar. The possible entries are: categories, locations, footprints, manufacturers, suppliers, devices, tools
|
||||
partdb.sidebar.items:
|
||||
- categories
|
||||
- devices
|
||||
- tools
|
||||
partdb.sidebar.root_expanded: true # If this is set to true, the root node of the sidebar is expanded by default
|
||||
partdb.sidebar.root_node_enable: true # Put all entities below a root node in the sidebar
|
||||
|
||||
######################################################################################################################
|
||||
# Miscellaneous
|
||||
######################################################################################################################
|
||||
partdb.demo_mode: '%env(bool:DEMO_MODE)%' # If set to true, all potentially dangerous things are disabled (like changing passwords of the own user)
|
||||
partdb.show_part_image_overlay: '%env(bool:SHOW_PART_IMAGE_OVERLAY)%' # If set to false, the filename overlay of the part image will be disabled
|
||||
|
||||
# Set the themes from which the user can choose from in the settings.
|
||||
# Themes commented here by default, are not really usable, because of display problems. Enable them at your own risk!
|
||||
|
|
@ -111,30 +84,18 @@ parameters:
|
|||
# Env default values
|
||||
######################################################################################################################
|
||||
|
||||
env(DEFAULT_LANG): 'en'
|
||||
env(DEFAULT_TIMEZONE): 'Europe/Berlin'
|
||||
env(INSTANCE_NAME): 'Part-DB'
|
||||
env(BASE_CURRENCY): 'EUR'
|
||||
env(USE_GRAVATAR): '0'
|
||||
env(MAX_ATTACHMENT_FILE_SIZE): '100M'
|
||||
|
||||
env(REDIRECT_TO_HTTPS): 0
|
||||
|
||||
env(ENFORCE_CHANGE_COMMENTS_FOR): ''
|
||||
|
||||
env(ERROR_PAGE_ADMIN_EMAIL): ''
|
||||
env(ERROR_PAGE_SHOW_HELP): 1
|
||||
|
||||
env(DEMO_MODE): 0
|
||||
env(BANNER): ''
|
||||
|
||||
|
||||
env(EMAIL_SENDER_EMAIL): 'noreply@partdb.changeme'
|
||||
env(EMAIL_SENDER_NAME): 'Part-DB Mailer'
|
||||
env(ALLOW_EMAIL_PW_RESET): 0
|
||||
|
||||
env(TABLE_DEFAULT_PAGE_SIZE): 50
|
||||
|
||||
env(TRUSTED_PROXIES): '127.0.0.1' #By default trust only our own server
|
||||
env(TRUSTED_HOSTS): '' # Trust all host names by default
|
||||
|
||||
|
|
@ -142,11 +103,4 @@ parameters:
|
|||
|
||||
env(SAML_ROLE_MAPPING): '{}'
|
||||
|
||||
env(HISTORY_SAVE_CHANGED_DATA): 1
|
||||
env(HISTORY_SAVE_CHANGED_FIELDS): 1
|
||||
env(HISTORY_SAVE_REMOVED_DATA): 1
|
||||
env(HISTORY_SAVE_NEW_DATA): 1
|
||||
|
||||
env(EDA_KICAD_CATEGORY_DEPTH): 0
|
||||
|
||||
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
||||
|
|
|
|||
|
|
@ -265,17 +265,13 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
|||
# label: "perm.database.write_db_settings"
|
||||
# alsoSet: ['read_db_settings', 'see_status']
|
||||
|
||||
#config:
|
||||
# label: "perm.config"
|
||||
# group: "system"
|
||||
# operations:
|
||||
# read_config:
|
||||
# label: "perm.config.read_config"
|
||||
# edit_config:
|
||||
# label: "perm.config.edit_config"
|
||||
# alsoSet: 'read_config'
|
||||
# server_info:
|
||||
# label: "perm.config.server_info"
|
||||
config:
|
||||
label: "perm.config"
|
||||
group: "system"
|
||||
operations:
|
||||
change_system_settings:
|
||||
label: "perm.config.change_system_settings"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
|
||||
system:
|
||||
label: "perm.system"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
when@dev:
|
||||
_errors:
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.php'
|
||||
prefix: /_error
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
when@dev:
|
||||
web_profiler_wdt:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'
|
||||
prefix: /_wdt
|
||||
|
||||
web_profiler_profiler:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.php'
|
||||
prefix: /_profiler
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ services:
|
|||
bool $gdpr_compliance: '%partdb.gdpr_compliance%'
|
||||
bool $kernel_debug_enabled: '%kernel.debug%'
|
||||
string $kernel_cache_dir: '%kernel.cache_dir%'
|
||||
string $partdb_title: '%partdb.title%'
|
||||
string $base_currency: '%partdb.default_currency%'
|
||||
|
||||
_instanceof:
|
||||
App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
|
||||
|
|
@ -31,10 +29,6 @@ services:
|
|||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
# controllers are imported separately to make sure services can be injected
|
||||
# as action arguments even if you don't extend any base controller class
|
||||
|
|
@ -76,28 +70,10 @@ services:
|
|||
# Only the event classes specified here are saved to DB (set to []) to log all events
|
||||
$whitelist: []
|
||||
|
||||
App\EventListener\LogSystem\EventLoggerListener:
|
||||
arguments:
|
||||
$save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
|
||||
$save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
|
||||
$save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
|
||||
$save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%'
|
||||
|
||||
App\Form\AttachmentFormType:
|
||||
arguments:
|
||||
$allow_attachments_download: '%partdb.attachments.allow_downloads%'
|
||||
$max_file_size: '%partdb.attachments.max_file_size%'
|
||||
$download_by_default: '%partdb.attachments.download_by_default%'
|
||||
|
||||
App\Services\Attachments\AttachmentSubmitHandler:
|
||||
arguments:
|
||||
$allow_attachments_downloads: '%partdb.attachments.allow_downloads%'
|
||||
$mimeTypes: '@mime_types'
|
||||
$max_upload_size: '%partdb.attachments.max_file_size%'
|
||||
|
||||
App\Services\LogSystem\EventCommentNeededHelper:
|
||||
arguments:
|
||||
$enforce_change_comments_for: '%partdb.enforce_change_comments_for%'
|
||||
|
||||
####################################################################################################################
|
||||
# Attachment system
|
||||
|
|
@ -156,29 +132,6 @@ services:
|
|||
tags:
|
||||
- { name: doctrine.orm.entity_listener }
|
||||
|
||||
####################################################################################################################
|
||||
# Price system
|
||||
####################################################################################################################
|
||||
App\Command\Currencies\UpdateExchangeRatesCommand:
|
||||
arguments:
|
||||
$base_current: '%partdb.default_currency%'
|
||||
|
||||
App\Form\Type\CurrencyEntityType:
|
||||
arguments:
|
||||
$base_currency: '%partdb.default_currency%'
|
||||
|
||||
App\Services\Parts\PricedetailHelper:
|
||||
arguments:
|
||||
$base_currency: '%partdb.default_currency%'
|
||||
|
||||
App\Services\Formatters\MoneyFormatter:
|
||||
arguments:
|
||||
$base_currency: '%partdb.default_currency%'
|
||||
|
||||
App\Services\Tools\ExchangeRateUpdater:
|
||||
arguments:
|
||||
$base_currency: '%partdb.default_currency%'
|
||||
|
||||
###################################################################################################################
|
||||
# User system
|
||||
####################################################################################################################
|
||||
|
|
@ -186,10 +139,6 @@ services:
|
|||
arguments:
|
||||
$demo_mode: '%partdb.demo_mode%'
|
||||
|
||||
App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber:
|
||||
arguments:
|
||||
$default_timezone: '%partdb.timezone%'
|
||||
|
||||
App\Controller\SecurityController:
|
||||
arguments:
|
||||
$allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
||||
|
|
@ -203,10 +152,6 @@ services:
|
|||
tags:
|
||||
- { name: 'translation.extractor', alias: 'permissionExtractor'}
|
||||
|
||||
App\Services\UserSystem\UserAvatarHelper:
|
||||
arguments:
|
||||
$use_gravatar: '%partdb.users.use_gravatar%'
|
||||
|
||||
App\Form\Type\ThemeChoiceType:
|
||||
arguments:
|
||||
$available_themes: '%partdb.available_themes%'
|
||||
|
|
@ -222,9 +167,6 @@ services:
|
|||
####################################################################################################################
|
||||
# Table settings
|
||||
####################################################################################################################
|
||||
App\DataTables\PartsDataTable:
|
||||
arguments:
|
||||
$visible_columns: '%partdb.table.parts.default_columns%'
|
||||
|
||||
App\DataTables\Helpers\ColumnSortHelper:
|
||||
shared: false # Service has a state so not share it between different tables
|
||||
|
|
@ -246,14 +188,6 @@ services:
|
|||
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
|
||||
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
|
||||
|
||||
####################################################################################################################
|
||||
# Trees
|
||||
####################################################################################################################
|
||||
App\Services\Trees\TreeViewGenerator:
|
||||
arguments:
|
||||
$rootNodeExpandedByDefault: '%partdb.sidebar.root_expanded%'
|
||||
$rootNodeEnabled: '%partdb.sidebar.root_node_enable%'
|
||||
|
||||
####################################################################################################################
|
||||
# Part info provider system
|
||||
####################################################################################################################
|
||||
|
|
@ -261,76 +195,12 @@ services:
|
|||
arguments:
|
||||
$providers: !tagged_iterator 'app.info_provider'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\Element14Provider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_ELEMENT14_KEY)%'
|
||||
$store_id: '%env(string:PROVIDER_ELEMENT14_STORE_ID)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\DigikeyProvider:
|
||||
arguments:
|
||||
$clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||
$currency: '%env(string:PROVIDER_DIGIKEY_CURRENCY)%'
|
||||
$language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
|
||||
$country: '%env(string:PROVIDER_DIGIKEY_COUNTRY)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\TMEClient:
|
||||
arguments:
|
||||
$secret: '%env(string:PROVIDER_TME_SECRET)%'
|
||||
$token: '%env(string:PROVIDER_TME_KEY)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\TMEProvider:
|
||||
arguments:
|
||||
$currency: '%env(string:PROVIDER_TME_CURRENCY)%'
|
||||
$country: '%env(string:PROVIDER_TME_COUNTRY)%'
|
||||
$language: '%env(string:PROVIDER_TME_LANGUAGE)%'
|
||||
$get_gross_prices: '%env(bool:PROVIDER_TME_GET_GROSS_PRICES)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\OctopartProvider:
|
||||
arguments:
|
||||
$clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||
$secret: '%env(string:PROVIDER_OCTOPART_SECRET)%'
|
||||
$country: '%env(string:PROVIDER_OCTOPART_COUNTRY)%'
|
||||
$currency: '%env(string:PROVIDER_OCTOPART_CURRENCY)%'
|
||||
$search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
|
||||
$onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\MouserProvider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_MOUSER_KEY)%'
|
||||
$language: '%env(string:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE)%'
|
||||
$options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%'
|
||||
$search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\LCSCProvider:
|
||||
arguments:
|
||||
$enabled: '%env(bool:PROVIDER_LCSC_ENABLED)%'
|
||||
$currency: '%env(string:PROVIDER_LCSC_CURRENCY)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\OEMSecretsProvider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_OEMSECRETS_KEY)%'
|
||||
$country_code: '%env(string:PROVIDER_OEMSECRETS_COUNTRY_CODE)%'
|
||||
$currency: '%env(PROVIDER_OEMSECRETS_CURRENCY)%'
|
||||
$zero_price: '%env(PROVIDER_OEMSECRETS_ZERO_PRICE)%'
|
||||
$set_param: '%env(PROVIDER_OEMSECRETS_SET_PARAM)%'
|
||||
$sort_criteria: '%env(PROVIDER_OEMSECRETS_SORT_CRITERIA)%'
|
||||
|
||||
|
||||
####################################################################################################################
|
||||
# API system
|
||||
####################################################################################################################
|
||||
App\State\PartDBInfoProvider:
|
||||
arguments:
|
||||
$default_uri: '%partdb.default_uri%'
|
||||
$global_locale: '%partdb.locale%'
|
||||
$global_timezone: '%partdb.timezone%'
|
||||
|
||||
####################################################################################################################
|
||||
# EDA system
|
||||
####################################################################################################################
|
||||
App\Services\EDA\KiCadHelper:
|
||||
arguments:
|
||||
$category_depth: '%env(int:EDA_KICAD_CATEGORY_DEPTH)%'
|
||||
|
||||
####################################################################################################################
|
||||
# Symfony overrides
|
||||
|
|
@ -355,7 +225,6 @@ services:
|
|||
####################################################################################################################
|
||||
App\Controller\RedirectController:
|
||||
arguments:
|
||||
$default_locale: '%partdb.locale%'
|
||||
$enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%'
|
||||
|
||||
App\Doctrine\Purger\ResetAutoIncrementPurgerFactory:
|
||||
|
|
@ -370,14 +239,6 @@ services:
|
|||
arguments:
|
||||
$project_dir: '%kernel.project_dir%'
|
||||
|
||||
App\Services\System\UpdateAvailableManager:
|
||||
arguments:
|
||||
$check_for_updates: '%partdb.check_for_updates%'
|
||||
|
||||
App\Services\System\BannerHelper:
|
||||
arguments:
|
||||
$partdb_banner: '%partdb.banner%'
|
||||
$project_dir: '%kernel.project_dir%'
|
||||
|
||||
App\Doctrine\Middleware\MySQLSSLConnectionMiddlewareWrapper:
|
||||
arguments:
|
||||
|
|
|
|||
BIN
docs/assets/getting_started/system_settings.png
Normal file
BIN
docs/assets/getting_started/system_settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
|
|
@ -10,7 +10,7 @@ Part-DBs behavior can be configured to your needs. There are different kinds of
|
|||
user-changeable (changeable dynamically via frontend), options that can be configured by environment variables, and
|
||||
options that are only configurable via Symfony config files.
|
||||
|
||||
## User changeable
|
||||
## User configruation
|
||||
|
||||
The following things can be changed for every user and a user can change it for himself (if he has the correct permission
|
||||
for it). Configuration is either possible via the user's own settings page (where you can also change the password) or via
|
||||
|
|
@ -24,15 +24,34 @@ the user admin page:
|
|||
* **Preferred currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with
|
||||
other currencies will be converted to the price selected here
|
||||
|
||||
## System configuration (via web interface)
|
||||
|
||||
Many common configuration options can be changed via the web interface. You can find the settings page in the sidebar under
|
||||
"System" -> "Settings". You need to have the "Change system settings" permission to access this page.
|
||||
|
||||
If a setting is greyed out and cannot be changed, it means that this setting is currently overwritten by an environment
|
||||
variable. You can either change the environment variable to change the setting, or you can migrate the setting to the
|
||||
database, so that it can be changed via the web interface. To do this, you can use the `php bin/console settings:migrate-env-to-settings` command
|
||||
and remove the environment variable afterward.
|
||||
|
||||
## Environment variables (.env.local)
|
||||
|
||||
The following configuration options can only be changed by the server administrator, by either changing the server
|
||||
variables, changing the `.env.local` file or setting env for your docker container. Here are just the most important
|
||||
options listed, see `.env` file for the full list of possible env variables.
|
||||
|
||||
Environment variables allow to overwrite settings in the web interface. This is useful, if you want to enforce certain
|
||||
settings to be unchangable by users, or if you want to configure settings in a central place in a deployed environment.
|
||||
On the settings page, you can hover over a setting to see, which environment variable can be used to overwrite it, it
|
||||
is shown as tooltip. API keys or similar sensitve data which is overwritten by env variables, are redacted on the web
|
||||
interface, so that even administrators cannot see them (only the last 2 characters and the length).
|
||||
|
||||
For technical and security reasons some settings can only be configured via environment variables and not via the web
|
||||
interface. These settings are marked with "(env only)" in the description below.
|
||||
|
||||
### General options
|
||||
|
||||
* `DATABASE_URL`: Configures the database which Part-DB uses:
|
||||
* `DATABASE_URL` (env only): Configures the database which Part-DB uses:
|
||||
* For MySQL (or MariaDB) use a string in the form of `mysql://<USERNAME>:<PASSWORD>@<HOST>:<PORT>/<TABLE_NAME>` here
|
||||
(e.g. `DATABASE_URL=mysql://user:password@127.0.0.1:3306/part-db`).
|
||||
* For SQLite use the following format to specify the
|
||||
|
|
@ -42,10 +61,10 @@ options listed, see `.env` file for the full list of possible env variables.
|
|||
|
||||
Please note that **`serverVersion=x.y`** variable is required due to dependency of Symfony framework.
|
||||
|
||||
* `DATABASE_MYSQL_USE_SSL_CA`: If this value is set to `1` or `true` and a MySQL connection is used, then the connection
|
||||
* `DATABASE_MYSQL_USE_SSL_CA` (env only): If this value is set to `1` or `true` and a MySQL connection is used, then the connection
|
||||
is encrypted by SSL/TLS and the server certificate is verified against the system CA certificates or the CA certificate
|
||||
bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept all certificates.
|
||||
* `DATABASE_EMULATE_NATURAL_SORT` (default 0): If set to 1, Part-DB will emulate natural sorting, even if the database
|
||||
* `DATABASE_EMULATE_NATURAL_SORT` (default 0) (env only): If set to 1, Part-DB will emulate natural sorting, even if the database
|
||||
does not support it natively. However this is much slower than the native sorting, and contain bugs or quirks, so use
|
||||
it only, if you have to.
|
||||
* `DEFAULT_LANG`: The default language to use server-wide (when no language is explicitly specified by a user or via
|
||||
|
|
@ -74,7 +93,7 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
to specify the size in kilobytes, megabytes or gigabytes. By default `100M` (100 megabytes). Please note that this is
|
||||
only the limit of Part-DB. You still need to configure the php.ini `upload_max_filesize` and `post_max_size` to allow
|
||||
bigger files to be uploaded.
|
||||
* `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
|
||||
* `DEFAULT_URI` (env only): The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
|
||||
This should be the primary URL/Domain, which is used to access Part-DB. This value is used to create correct links in
|
||||
emails and other places, where the URL is needed. It is also used, when SAML is enabled.s If you are using a reverse
|
||||
proxy, you should set this to the URL of the reverse proxy (e.g. `https://part-db.example.com`). **This value must end
|
||||
|
|
@ -91,14 +110,14 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
* `datastructure_create`: Creation of a new datastructure (e.g. category, manufacturer, ...)
|
||||
* `CHECK_FOR_UPDATES` (default `1`): Set this to 0, if you do not want Part-DB to connect to GitHub to check for new
|
||||
versions, or if your server can not connect to the internet.
|
||||
* `APP_SECRET`: This variable is a configuration parameter used for various security-related purposes,
|
||||
* `APP_SECRET` (env only): This variable is a configuration parameter used for various security-related purposes,
|
||||
particularly for securing and protecting various aspects of your application. It's a secret key that is used for
|
||||
cryptographic operations and security measures (session management, CSRF protection, etc..). Therefore this
|
||||
value should be handled as confidential data and not shared publicly.
|
||||
* `SHOW_PART_IMAGE_OVERLAY`: Set to 0 to disable the part image overlay, which appears if you hover over an image in the
|
||||
part image gallery
|
||||
|
||||
### E-Mail settings
|
||||
### E-Mail settings (all env only)
|
||||
|
||||
* `MAILER_DSN`: You can configure the mail provider which should be used for email delivery (
|
||||
see https://symfony.com/doc/current/components/mailer.html for full documentation). If you just want to use an SMTP
|
||||
|
|
@ -138,7 +157,7 @@ The following options are used to configure, which (and how much) data is writte
|
|||
If you want to use want to revert changes or view older revisions of entities,
|
||||
then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAVE_REMOVED_DATA` all have to be true.
|
||||
|
||||
### Error pages settings
|
||||
### Error pages settings (all env only)
|
||||
|
||||
* `ERROR_PAGE_ADMIN_EMAIL`: You can set an email address here, which is shown on the error page, who should be contacted
|
||||
about the issue (e.g. an IT support email of your company)
|
||||
|
|
@ -153,7 +172,7 @@ then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAV
|
|||
All parts in the selected category and all subcategories are shown in KiCad. Set this to a higher value, if you want to show more categories in KiCad.
|
||||
When you set this value to -1, all parts are shown inside a single category in KiCad.
|
||||
|
||||
### SAML SSO settings
|
||||
### SAML SSO settings (all env only)
|
||||
|
||||
The following settings can be used to enable and configure Single-Sign on via SAML. This allows users to log in to
|
||||
Part-DB without entering a username and password, but instead they are redirected to a SAML Identity Provider (IdP) and
|
||||
|
|
@ -201,26 +220,26 @@ See the [information providers]({% link usage/information_provider_system.md %})
|
|||
|
||||
### Other / less-used options
|
||||
|
||||
* `TRUSTED_PROXIES`: Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct
|
||||
* `TRUSTED_PROXIES` (env only): Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct
|
||||
IP information (see [here](https://symfony.com/doc/current/deployment/proxies.html) for more info).
|
||||
* `TRUSTED_HOSTS`: To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB
|
||||
* `TRUSTED_HOSTS` (env only): To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB
|
||||
should be accessible. If accessed via the wrong hostname, an error will be shown.
|
||||
* `DEMO_MODE`: Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo
|
||||
* `DEMO_MODE` (env only): Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo
|
||||
instance. This should not be needed for normal installations.
|
||||
* `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`): Set this value to true, if your webserver does not
|
||||
* `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`) (env only): Set this value to true, if your webserver does not
|
||||
support rewrite. In this case, all URL paths will contain index.php/, which is needed then. Normally this setting does
|
||||
not need to be changed.
|
||||
* `REDIRECT_TO_HTTPS`: If this is set to true, all requests to http will be redirected to https. This is useful if your
|
||||
* `REDIRECT_TO_HTTPS` (env only): If this is set to true, all requests to http will be redirected to https. This is useful if your
|
||||
web server does not already do this (like the one used in the demo instance). If your web server already redirects to
|
||||
https, you don't need to set this. Ensure that Part-DB is accessible via HTTPS before you enable this setting.
|
||||
* `FIXER_API_KEY`: If you want to automatically retrieve exchange rates for base currencies other than euros, you have to
|
||||
configure an exchange rate provider API. [Fixer.io](https://fixer.io/) is preconfigured, and you just have to register
|
||||
there and set the retrieved API key in this environment variable.
|
||||
* `APP_ENV`: This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development
|
||||
* `APP_ENV` (env only): This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development
|
||||
mode. (**You should not do this on a publicly accessible server, as it will leak sensitive information!**)
|
||||
* `BANNER`: You can configure the text that should be shown as the banner on the homepage. Useful especially for docker
|
||||
containers. In all other applications you can just change the `config/banner.md` file.
|
||||
* `DISABLE_YEAR2038_BUG_CHECK`: If set to `1`, the year 2038 bug check is disabled on 32-bit systems, and dates after
|
||||
* `DISABLE_YEAR2038_BUG_CHECK` (env only): If set to `1`, the year 2038 bug check is disabled on 32-bit systems, and dates after
|
||||
2038 are no longer forbidden. However this will lead to 500 error messages when rendering dates after 2038 as all current
|
||||
32-bit PHP versions can not format these dates correctly. This setting is for the case that future PHP versions will
|
||||
handle this correctly on 32-bit systems. 64-bit systems are not affected by this bug, and the check is always disabled.
|
||||
|
|
@ -228,7 +247,7 @@ handle this correctly on 32-bit systems. 64-bit systems are not affected by this
|
|||
## Banner
|
||||
|
||||
To change the banner you can find on the homepage, you can either set the `BANNER` environment variable to the text you
|
||||
want to show, or you can edit the `config/banner.md` file. The banner is written in markdown, so you can use all
|
||||
want to show, or change it in the system settings webinterface. The banner is written in markdown, so you can use all
|
||||
markdown (and even some subset of HTML) syntax to format the text.
|
||||
|
||||
## parameters.yaml
|
||||
|
|
@ -243,8 +262,6 @@ command `bin/console cache:clear`.
|
|||
|
||||
The following options are available:
|
||||
|
||||
* `partdb.global_theme`: The default theme to use, when no user specific theme is set. Should be one of the themes from
|
||||
the `partdb.available_themes` config option.
|
||||
* `partdb.locale_menu`: The codes of the languages, which should be shown in the language chooser menu (the one with the
|
||||
user icon in the navbar). The first language in the list will be the default language.
|
||||
* `partdb.gdpr_compliance`: When set to true (default value), IP addresses which are saved in the database will be
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
title: Direct Installation on Debian 11
|
||||
title: Direct Installation on Debian 12
|
||||
layout: default
|
||||
parent: Installation
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Part-DB installation guide for Debian 11 (Bullseye)
|
||||
# Part-DB installation guide for Debian 12 (Bookworm)
|
||||
|
||||
This guide shows you how to install Part-DB directly on Debian 11 using apache2 and SQLite. This guide should work with
|
||||
This guide shows you how to install Part-DB directly on Debian 12 using apache2 and SQLite. This guide should work with
|
||||
recent Ubuntu and other Debian-based distributions with little to no changes.
|
||||
Depending on what you want to do, using the prebuilt docker images may be a better choice, as you don't need to install
|
||||
this many dependencies. See [here]({% link installation/installation_docker.md %}) for more information on the docker
|
||||
|
|
@ -33,35 +33,22 @@ sudo apt install git curl zip ca-certificates software-properties-common apt-tra
|
|||
|
||||
### Install PHP and apache2
|
||||
|
||||
Part-DB is written in [PHP](https://php.net) and therefore needs a PHP interpreter to run. Part-DB needs PHP 8.1 or
|
||||
Part-DB is written in [PHP](https://php.net) and therefore needs a PHP interpreter to run. Part-DB needs PHP 8.2 or
|
||||
higher. However, it is recommended to use the most recent version of PHP for performance reasons and future
|
||||
compatibility.
|
||||
|
||||
As Debian 11 does not ship PHP 8.1 in its default repositories, we have to add a repository for it. You can skip this
|
||||
step if your distribution is shipping a recent version of PHP or you want to use the built-in PHP version. If you are
|
||||
using Debian 12, you can skip this step, as PHP 8.1 is already included in the default repositories.
|
||||
Install PHP with required extensions and apache2:
|
||||
|
||||
```bash
|
||||
# Add sury repository for PHP 8.1
|
||||
sudo curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
|
||||
|
||||
# Update package list
|
||||
sudo apt update && sudo apt upgrade
|
||||
sudo apt install apache2 php8.2 libapache2-mod-php8.2 \
|
||||
php8.2-opcache php8.2-curl php8.2-gd php8.2-mbstring \
|
||||
php8.2-xml php8.2-bcmath php8.2-intl php8.2-zip php8.2-xsl \
|
||||
php8.2-sqlite3 php8.2-mysql
|
||||
```
|
||||
|
||||
Now you can install PHP 8.1 and the required packages (change the 8.1 in the package version according to the version you
|
||||
want to use):
|
||||
|
||||
```bash
|
||||
sudo apt install php8.1 libapache2-mod-php8.1 php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql
|
||||
```
|
||||
|
||||
The apache2 webserver should be already installed with this command and configured basically.
|
||||
|
||||
### Install composer
|
||||
|
||||
Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. As the version shipped in the
|
||||
repositories is pretty old, we will install it manually:
|
||||
Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. Install the latest version manually:
|
||||
|
||||
```bash
|
||||
# Download composer installer script
|
||||
|
|
@ -78,10 +65,9 @@ To build the front end (the user interface) Part-DB uses [yarn](https://yarnpkg.
|
|||
shipped versions are pretty old, we install new versions from the official Node.js repository:
|
||||
|
||||
```bash
|
||||
# Add recent node repository (nodejs 18 is supported until 2025)
|
||||
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
# Install nodejs
|
||||
sudo apt install nodejs
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
```
|
||||
|
||||
We can install yarn with the following commands:
|
||||
|
|
@ -117,8 +103,8 @@ Alternatively, you can check out a specific version by running (
|
|||
see [GitHub Releases page](https://github.com/Part-DB/Part-DB-server/releases) for a list of available versions):
|
||||
|
||||
```bash
|
||||
# This checks out the version 1.5.2
|
||||
git checkout v1.5.2
|
||||
# This checks out the version 2.0.0
|
||||
git checkout v2.0.0
|
||||
```
|
||||
|
||||
Change ownership of the files to the apache user:
|
||||
|
|
@ -142,11 +128,10 @@ configuration:
|
|||
cp .env .env.local
|
||||
```
|
||||
|
||||
In your `.env.local` you can configure Part-DB according to your wishes. A full list of configuration options can be
|
||||
found [here](../configuration.md).
|
||||
Other configuration options like the default language or default currency can be found in `config/parameters.yaml`.
|
||||
In your `.env.local` you can configure Part-DB according to your wishes and overwrite web interface settings.
|
||||
A full list of configuration options can be found [here](../configuration.md).
|
||||
|
||||
Please check that the `partdb.default_currency` value in `config/parameters.yaml` matches your mainly used currency, as
|
||||
Please check that the configured base currency matches your mainly used currency, as
|
||||
this can not be changed after creating price information.
|
||||
|
||||
### Install dependencies for Part-DB and build frontend
|
||||
|
|
@ -256,6 +241,7 @@ network to point to the server).
|
|||
|
||||
Navigate to the Part-DB web interface and login via the user icon in the top right corner. You can log in using the
|
||||
username `admin` and the password you have written down earlier.
|
||||
As first steps, you should check out the system settings and check if everything is correct.
|
||||
|
||||
## Update Part-DB
|
||||
|
||||
|
|
@ -291,7 +277,7 @@ sudo -u www-data php bin/console cache:clear
|
|||
## MySQL/MariaDB database
|
||||
|
||||
To use a MySQL database, follow the steps from above (except the creation of the database, we will do this later).
|
||||
Debian 11 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead:
|
||||
Debian 12 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead:
|
||||
|
||||
1. Install maria-db with:
|
||||
|
||||
|
|
|
|||
88
docs/upgrade/1_to_2.md
Normal file
88
docs/upgrade/1_to_2.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
---
|
||||
layout: default
|
||||
title: Upgrade from Part-DB 1.x to 2.x
|
||||
nav_order: 1
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Upgrade from Part-DB 1.x to 2.x
|
||||
|
||||
Part-DB 2.0 is a major release that changes a lot of things internally, but it is still compatible with Part-DB 1.x.
|
||||
Depending on your preferences, you will have to do some changes to your Part-DB installation, this document will guide
|
||||
you through the upgrade process.
|
||||
|
||||
## New requirements
|
||||
*If you are running Part-DB inside a docker container, you can skip this section, as the new requirements are already
|
||||
fulfilled by the official Part-DB docker image.*
|
||||
|
||||
Part-DB 2.0 requires at least PHP 8.2 (newer versions are recommended). So if your existing Part-DB installation is still
|
||||
running PHP 8.1, you will have to upgrade your PHP version first.
|
||||
The minimum required version of node.js is now 20.0 or newer, so if you are using 18.0, you will have to upgrade it too.
|
||||
|
||||
Most distributions should have the possibility to get backports for PHP 8.4 and modern nodejs, so you should be able to
|
||||
easily upgrade your system to the new requirements. Otherwise, you can use the official Part-DB docker image, which
|
||||
ships all required dependencies and is always up to date with the latest requirements, so that you do not have to worry
|
||||
about the requirements at all.
|
||||
|
||||
## Changes
|
||||
* Configuration is now preferably done via a web settings interface. You can still use environment variables, these overwrite
|
||||
the settings in the web interface. Existing configuration will still work, but you should consider migriting them to the
|
||||
web interface as described below.
|
||||
* The `config/banner.md` file that could been used to customize the banner text, was removed. You can now set the banner text
|
||||
directly in the admin interface, or by setting the `BANNER` environment variable. If you want to keep your existing
|
||||
banner text, you will have to copy it from the `config/banner.md` file to the admin interface or set the `BANNER`
|
||||
environment variable.
|
||||
* The parameters `partdb.sidebar.items`, `partdb.sidebar.root_node_enable` and `partdb.sidebar.root_expanded` in `config/parameters.yaml`,
|
||||
were removed. You can configure them now directly in the admin interface.
|
||||
* Updated icon set. As fontawesome 7 is now used, some icons have changed slightly.
|
||||
|
||||
## Upgrade installation
|
||||
|
||||
The upgrade process works very similar to a normal (minor release) upgrade.
|
||||
|
||||
### Direct installation
|
||||
|
||||
**Be sure to execute the following steps as the user that owns the Part-DB files (e.g. `www-data`, or your webserver user). So prepend a `sudo -u wwww-data` where necessary.**
|
||||
|
||||
1. Make a backup of your existing Part-DB installation, including the database, data directories and the configuration files and `.env.local` file.
|
||||
The `php bin/console partdb:backup` command can help you with this.
|
||||
2. Pull the v2 version. For git installation you can do this with `git checkout v2.0.0` (or newer version)
|
||||
3. Run `composer install --no-dev -o` to update the dependencies.
|
||||
4. Run `yarn install` and `yarn build` to update the frontend assets.
|
||||
5. Rund `php bin/console doctrine:migrations:migrate` to update the database schema.
|
||||
6. Clear the cache with `php bin/console cache:clear`.
|
||||
7. Open your Part-DB instance in the browser and log in as an admin user.
|
||||
8. Go to the user or group permissions page, and give yourself (and other administrators) the right to change system settings (under "System" and "Configuration").
|
||||
9. You can now go to the settings page (under "System" and "Settings") and check if all settings are correct.
|
||||
10. Parameters which were previously set via environment variables are greyed out and cannot be changed in the web interface.
|
||||
If you want to change them, you must migrate them to the settings interface as described below.
|
||||
|
||||
### Docker installation
|
||||
1. Make a backup of your existing Part-DB installation, including the database, data directories and the configuration files and the file where you configure the docker environment variables.
|
||||
2. Stop the existing Part-DB container with `docker compose down`
|
||||
3. Ensure that your docker compose file uses the new latest images (either `latest` or `2` tag).
|
||||
4. Pull the new images with `docker compose pull` and start the container with `docker compose up -d`
|
||||
5. If you have database automigration disabled, run `docker exec --user=www-data partdb php bin/console doctrine:migrations:migrate` to update the database schema.
|
||||
6. Open your Part-DB instance in the browser and log in as an admin user.
|
||||
7. Go to the user or group permissions page, and give yourself (and other administrators)
|
||||
the right to change system settings (under "System" and "Configuration").
|
||||
8. You can now go to the settings page (under "System" and "Settings")
|
||||
9. Parameters which were previously set via environment variables are greyed out and cannot be changed in the web interface.
|
||||
If you want to change them, you must migrate them to the settings interface as described below.
|
||||
|
||||
## Migrate environment variable configuration to settings interface
|
||||
As described above, configuration can now be done via the web interface, and can be overwritten by environment variables, so
|
||||
that existing configuration should still work. However, if a parameter is set via an environment variable, it cannot be changed in the web interface.
|
||||
To change it, you must migrate your environment variable configuration to the new system.
|
||||
|
||||
For this there is the new console command `settings:migrate-env-to-settings`, which reads in all environment variables used to overwrite
|
||||
settings and write them to the database, so that you can safely delete them from your environment variable configuration afterwards, without
|
||||
loosing your configuration.
|
||||
|
||||
To run the command, execute `php bin/console settings:migrate-env-to-settings --all` as webserver user (or run `docker exec --user=www-data -it partdb php bin/console settings:migrate-env-to-settings --all` for docker containers).
|
||||
It will list you all environment variables, it found and ask you for confirmation to migrate them. Answer with `yes` to migrate them and hit enter.
|
||||
|
||||
After the migration run successfully, the contents of your environment variables are now stored in the database and you can safely remove them from your environment variable configuration.
|
||||
Go through the environment variables listed by the command and remove them from your environment variable configuration (e.g. `.env.local` file or docker compose file), or just comment them out for now.
|
||||
|
||||
If you want to keep some environment variables, just leave them as they are, they will still work as before, the migration command only affects the settings stored in the database.
|
||||
9
docs/upgrade/index.md
Normal file
9
docs/upgrade/index.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: default
|
||||
title: Upgrade
|
||||
nav_order: 7
|
||||
has_children: true
|
||||
---
|
||||
|
||||
This section provides information on how to upgrade Part-DB to the latest version.
|
||||
This is intended for major release upgrades, where requirements or things changes significantly.
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
layout: default
|
||||
title: Upgrade from legacy Part-DB version (<1.0)
|
||||
nav_order: 100
|
||||
redirect_from: /upgrade_legacy
|
||||
---
|
||||
|
||||
# Upgrade from legacy Part-DB version
|
||||
|
|
@ -16,8 +17,8 @@ sections carefully before proceeding to upgrade.
|
|||
|
||||
## Changes
|
||||
|
||||
* PHP 8.1 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0).
|
||||
Releases are available for Windows too, so almost everybody should be able to use PHP 8.1
|
||||
* PHP 8.2 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0).
|
||||
Releases are available for Windows too, so almost everybody should be able to use PHP 8.2
|
||||
* **Console access is highly recommended.** The installation of composer and frontend dependencies require console access,
|
||||
also more sensitive stuff like database migration works via CLI now, so you should have console access on your server.
|
||||
* Markdown/HTML is now used instead of BBCode for rich text in description and command fields.
|
||||
|
|
@ -66,6 +66,8 @@ docker exec --user=www-data partdb php bin/console cache:clear
|
|||
* `partdb:migrations:import-partkeepr`: Imports a mysqldump XML dump of a PartKeepr database into Part-DB. This is only
|
||||
needed for users, which want to migrate from PartKeepr to Part-DB. *All existing data in the Part-DB database is
|
||||
deleted!*
|
||||
* `settings:migrate-env-to-settings`: Migrate configuration from environment variables to the settings interface.
|
||||
The value of the environment variable is copied to the settings database, so the environment variable can be removed afterwards without losing the configuration.
|
||||
|
||||
## Database commands
|
||||
|
||||
|
|
@ -76,4 +78,4 @@ docker exec --user=www-data partdb php bin/console cache:clear
|
|||
|
||||
* `php bin/console partdb:attachments:download`: Download all attachments, which are not already downloaded, to the
|
||||
local filesystem. This is useful to create local backups of the attachments, no matter what happens on the remote and
|
||||
also makes pictures thumbnails available for the frontend for them
|
||||
also makes pictures thumbnails available for the frontend for them
|
||||
|
|
|
|||
|
|
@ -12,11 +12,19 @@ Before starting, it's useful to read a bit about the [concepts of Part-DB]({% li
|
|||
1. TOC
|
||||
{:toc}
|
||||
|
||||
## Customize config files
|
||||
## Customize system settings
|
||||
|
||||
Before you start creating data structures, you should configure Part-DB to your needs by changing possible configuration
|
||||
options.
|
||||
This is done either via changing the `.env.local` file in a direct installation or by changing the env variables in
|
||||
Before starting creating datastructures, you should check the system settings to ensure that they fit your needs.
|
||||
After login as an administrator, you can find the settings in the sidebar under `Tools -> System -> Settings`.
|
||||

|
||||
|
||||
Here you can change various settings, like the name of your Part-DB instance (which is shown in the title bar of the
|
||||
browser), the default language (which is used if no user preference is set), the default timezone (which is used to
|
||||
display times correctly), the default currency (which is used to display prices correctly), and many more.
|
||||
|
||||
Some more fundamental settings like database connection, mail server settings, SSO, etc. are configured via environment variables.
|
||||
Environment variables also allow to overwrite various settings from the web interface.
|
||||
Environment variables can be changed by editing the `.env.local` file in a direct installation or by changing the env variables in
|
||||
your `docker-compose.yaml` file.
|
||||
A list of possible configuration options can be found [here]({% link configuration.md %}).
|
||||
|
||||
|
|
@ -44,8 +52,8 @@ used.
|
|||
|
||||
## (Optional) Customize homepage banner
|
||||
|
||||
The banner which is shown on the homepage, can be customized/changed by changing the `config/banner.md` file with a text
|
||||
editor. You can use markdown and (safe) HTML here, to style and customize the banner.
|
||||
The banner which is shown on the homepage, can be customized/changed via the homepage banner setting in system settings.
|
||||
You can use markdown and (safe) HTML here, to style and customize the banner.
|
||||
You can even use LaTeX-style equations by wrapping the expressions into `$` (like `$E=mc^2$`, which is rendered inline:
|
||||
$E=mc^2$) or `$$` (like `$$E=mc^2$$`) which will be rendered as a block, like so: $$E=mc^2$$
|
||||
|
||||
|
|
@ -202,4 +210,4 @@ later.
|
|||
You can choose from your created datastructures to add manufacturer information, supplier information, etc. to the part.
|
||||
You can also create new datastructures on the fly, if you want to add additional information to the part, by typing the
|
||||
name of the new datastructure in the field and select the "New ..." option in the dropdown menu. See [tips]({% link
|
||||
usage/tips_tricks.md %}) for more information.
|
||||
usage/tips_tricks.md %}) for more information.
|
||||
|
|
|
|||
|
|
@ -80,6 +80,11 @@ Normally the providers utilize an API of a service, and you need to create an ac
|
|||
Also, there are limits on how many requests you can do per day or month, depending on the provider and your contract
|
||||
with them.
|
||||
|
||||
Data providers can be either configured in the system settings (in the info provider tab) or on the settings page which is
|
||||
reachable via the cogwheel symbol next to the provider in the provider list. It is also possible to configure them via
|
||||
environment variables. See below for the available configuration options. API keys configured via environment variables
|
||||
are redacted in the settings interface.
|
||||
|
||||
The following providers are currently available and shipped with Part-DB:
|
||||
|
||||
(All trademarks are property of their respective owners. Part-DB is not affiliated with any of the companies.)
|
||||
|
|
|
|||
|
|
@ -95,4 +95,9 @@ It is only be shown to users which has the `Show available Part-DB updates` perm
|
|||
For the notification to work, Part-DB queries the GitHub API every 2 days to check for new releases. No data is sent to
|
||||
GitHub besides the metadata required for the connection (so the public IP address of your computer running Part-DB).
|
||||
If you don't want Part-DB to query the GitHub API, or if your server can not reach the internet, you can disable the
|
||||
update notifications by setting the `CHECK_FOR_UPDATES` option to `false`.
|
||||
update notifications by setting the `CHECK_FOR_UPDATES` option to `false`.
|
||||
|
||||
## Internet access via proxy
|
||||
If you server running Part-DB does not have direct access to the internet, but has to use a proxy server, you can configure
|
||||
the proxy settings in the `.env.local` file (or docker env config). You can set the `HTTP_PROXY` and `HTTPS_PROXY` environment
|
||||
variables to the URL of your proxy server. If your proxy server requires authentication, you can include the username and password in the URL.
|
||||
|
|
|
|||
|
|
@ -4,18 +4,15 @@ declare(strict_types=1);
|
|||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use App\Doctrine\Migration\ContainerAwareMigrationInterface;
|
||||
use App\Migration\AbstractMultiPlatformMigration;
|
||||
use App\Migration\WithPermPresetsTrait;
|
||||
use App\Services\UserSystem\PermissionPresetsHelper;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20221114193325 extends AbstractMultiPlatformMigration implements ContainerAwareInterface
|
||||
final class Version20221114193325 extends AbstractMultiPlatformMigration implements ContainerAwareMigrationInterface
|
||||
{
|
||||
use WithPermPresetsTrait;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ declare(strict_types=1);
|
|||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use App\Doctrine\Migration\ContainerAwareMigrationInterface;
|
||||
use App\Migration\AbstractMultiPlatformMigration;
|
||||
use App\Migration\WithPermPresetsTrait;
|
||||
use App\Services\UserSystem\PermissionPresetsHelper;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20240606203053 extends AbstractMultiPlatformMigration implements ContainerAwareInterface
|
||||
final class Version20240606203053 extends AbstractMultiPlatformMigration implements ContainerAwareMigrationInterface
|
||||
{
|
||||
use WithPermPresetsTrait;
|
||||
|
||||
|
|
|
|||
49
migrations/Version20250706201121.php
Normal file
49
migrations/Version20250706201121.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use App\Migration\AbstractMultiPlatformMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
final class Version20250706201121 extends AbstractMultiPlatformMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add settings_entry table for storing settings';
|
||||
}
|
||||
|
||||
public function mySQLUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry (`key` VARCHAR(255) NOT NULL, `data` JSON DEFAULT NULL, id INT AUTO_INCREMENT NOT NULL, UNIQUE INDEX UNIQ_93F8DB394E645A7E (`key`), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci`');
|
||||
|
||||
}
|
||||
|
||||
public function mySQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
|
||||
public function sqLiteUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" CLOB DEFAULT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
|
||||
}
|
||||
|
||||
public function sqLiteDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
|
||||
public function postgreSQLUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" JSON DEFAULT NULL, id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
|
||||
}
|
||||
|
||||
public function postgreSQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
}
|
||||
75
migrations/Version20250813214628.php
Normal file
75
migrations/Version20250813214628.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use App\Migration\AbstractMultiPlatformMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20250813214628 extends AbstractMultiPlatformMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Migrate webauthn_keys transports and other_ui fields to JSON type';
|
||||
}
|
||||
|
||||
public function convertArrayToJson(): void
|
||||
{
|
||||
$connection = $this->connection;
|
||||
$rows = $connection->fetchAllAssociative('SELECT id, transports, other_ui FROM webauthn_keys');
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$id = $row['id'];
|
||||
$new_transports = json_encode(unserialize($row['transports'], ['allowed_classes' => false]),
|
||||
JSON_THROW_ON_ERROR);
|
||||
$new_other_ui = json_encode(unserialize($row['other_ui'], ['allowed_classes' => false]),
|
||||
JSON_THROW_ON_ERROR);
|
||||
|
||||
$connection->executeStatement(
|
||||
'UPDATE webauthn_keys SET transports = :transports, other_ui = :other_ui WHERE id = :id',
|
||||
[
|
||||
'transports' => $new_transports,
|
||||
'other_ui' => $new_other_ui,
|
||||
'id' => $id,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function mySQLUp(Schema $schema): void
|
||||
{
|
||||
$this->convertArrayToJson();
|
||||
$this->addSql('ALTER TABLE webauthn_keys CHANGE transports transports JSON NOT NULL, CHANGE other_ui other_ui JSON DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function mySQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE webauthn_keys CHANGE transports transports LONGTEXT NOT NULL, CHANGE other_ui other_ui LONGTEXT DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function sqLiteUp(Schema $schema): void
|
||||
{
|
||||
//As there is no JSON type in SQLite, we only need to convert the data.
|
||||
$this->convertArrayToJson();
|
||||
}
|
||||
|
||||
public function sqLiteDown(Schema $schema): void
|
||||
{
|
||||
//Nothing to do here, as SQLite does not support JSON type and we are not changing the column type.
|
||||
}
|
||||
|
||||
public function postgreSQLUp(Schema $schema): void
|
||||
{
|
||||
$this->convertArrayToJson();
|
||||
$this->addSql('ALTER TABLE webauthn_keys ALTER transports TYPE JSON USING transports::JSON');
|
||||
$this->addSql('ALTER TABLE webauthn_keys ALTER other_ui TYPE JSON USING other_ui::JSON');
|
||||
}
|
||||
|
||||
public function postgreSQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE webauthn_keys ALTER transports TYPE TEXT');
|
||||
$this->addSql('ALTER TABLE webauthn_keys ALTER other_ui TYPE TEXT');
|
||||
}
|
||||
}
|
||||
50
package.json
50
package.json
|
|
@ -2,11 +2,12 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.19.6",
|
||||
"@babel/preset-env": "^7.19.4",
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
"@fortawesome/fontawesome-free": "^7.0.0",
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@hotwired/turbo": "^8.0.1",
|
||||
"@popperjs/core": "^2.10.2",
|
||||
"@symfony/stimulus-bridge": "^3.2.0",
|
||||
"@symfony/stimulus-bridge": "^4.0.0",
|
||||
"@symfony/ux-toggle-password": "file:vendor/symfony/ux-toggle-password/assets",
|
||||
"@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets",
|
||||
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/assets",
|
||||
"@symfony/webpack-encore": "^5.0.0",
|
||||
|
|
@ -29,54 +30,28 @@
|
|||
"watch": "encore dev --watch",
|
||||
"build": "encore production --progress"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-js": "^1.17.0",
|
||||
"@algolia/autocomplete-plugin-recent-searches": "^1.17.0",
|
||||
"@algolia/autocomplete-theme-classic": "^1.17.0",
|
||||
"@ckeditor/ckeditor5-alignment": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-autoformat": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-basic-styles": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-block-quote": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-code-block": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-dev-translations": "^43.0.1",
|
||||
"@ckeditor/ckeditor5-dev-utils": "43.0.*",
|
||||
"@ckeditor/ckeditor5-editor-classic": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-essentials": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-find-and-replace": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-font": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-heading": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-highlight": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-horizontal-line": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-html-embed": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-html-support": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-image": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-indent": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-link": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-list": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-markdown-gfm": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-media-embed": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-paragraph": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-paste-from-office": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-remove-format": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-source-editing": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-special-characters": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-table": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-theme-lark": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-upload": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-watchdog": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-word-count": "^44.0.0",
|
||||
"@ckeditor/ckeditor5-dev-utils": "^43.0.1",
|
||||
"@jbtronics/bs-treeview": "^1.0.1",
|
||||
"@part-db/html5-qrcode": "^3.1.0",
|
||||
"@part-db/html5-qrcode": "^4.0.0",
|
||||
"@zxcvbn-ts/core": "^3.0.2",
|
||||
"@zxcvbn-ts/language-common": "^3.0.3",
|
||||
"@zxcvbn-ts/language-de": "^3.0.1",
|
||||
"@zxcvbn-ts/language-en": "^3.0.1",
|
||||
"@zxcvbn-ts/language-fr": "^3.0.1",
|
||||
"@zxcvbn-ts/language-ja": "^3.0.1",
|
||||
"barcode-detector": "^2.3.1",
|
||||
"barcode-detector": "^3.0.5",
|
||||
"bootbox": "^6.0.0",
|
||||
"bootswatch": "^5.1.3",
|
||||
"bs-custom-file-input": "^1.3.4",
|
||||
"ckeditor5": "^46.0.0",
|
||||
"clipboard": "^2.0.4",
|
||||
"compression-webpack-plugin": "^11.1.0",
|
||||
"datatables.net": "^2.0.0",
|
||||
|
|
@ -85,14 +60,13 @@
|
|||
"datatables.net-colreorder-bs5": "^2.0.0",
|
||||
"datatables.net-fixedheader-bs5": "^4.0.0",
|
||||
"datatables.net-responsive-bs5": "^3.0.0",
|
||||
"datatables.net-select-bs5": "^2.0.0",
|
||||
"datatables.net-select-bs5": "^3.0.1",
|
||||
"dompurify": "^3.0.3",
|
||||
"emoji.json": "^15.0.0",
|
||||
"exports-loader": "^5.0.0",
|
||||
"json-formatter-js": "^2.3.4",
|
||||
"jszip": "^3.2.0",
|
||||
"katex": "^0.16.0",
|
||||
"marked": "^15.0.4",
|
||||
"marked": "^16.1.1",
|
||||
"marked-gfm-heading-id": "^4.1.1",
|
||||
"marked-mangle": "^1.0.1",
|
||||
"pdfmake": "^0.2.2",
|
||||
|
|
|
|||
|
|
@ -1,36 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
convertDeprecationsToExceptions="false"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
<server name="APP_ENV" value="test" force="true"/>
|
||||
<server name="SHELL_VERBOSITY" value="-1"/>
|
||||
<server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
|
||||
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5"/>
|
||||
<ini name="memory_limit" value="1G"/>
|
||||
<ini name="display_errors" value="1"/>
|
||||
</php>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<extensions>
|
||||
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
|
||||
</extensions>
|
||||
<listeners>
|
||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
|
||||
</listeners>
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
failOnDeprecation="true"
|
||||
failOnNotice="true"
|
||||
failOnWarning="true"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
cacheDirectory=".phpunit.cache"
|
||||
backupGlobals="false"
|
||||
>
|
||||
<php>
|
||||
<ini name="display_errors" value="1" />
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
<server name="APP_ENV" value="test" force="true"/>
|
||||
<server name="SHELL_VERBOSITY" value="-1"/>
|
||||
<ini name="memory_limit" value="1G"/>
|
||||
<ini name="display_errors" value="1"/>
|
||||
</php>
|
||||
<coverage includeUncoveredFiles="true">
|
||||
</coverage>
|
||||
<source ignoreIndirectDeprecations="true" restrictNotices="true" restrictWarnings="true">
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
</source>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<extensions>
|
||||
<bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
|
||||
<bootstrap class="Symfony\Bridge\PhpUnit\SymfonyExtension">
|
||||
<parameter name="clock-mock-namespaces" value="App" />
|
||||
<parameter name="dns-mock-namespaces" value="App" />
|
||||
</bootstrap>
|
||||
</extensions>
|
||||
</phpunit>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ DirectoryIndex index.php
|
|||
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
|
||||
# following RewriteCond (best solution)
|
||||
RewriteCond %{ENV:REDIRECT_STATUS} =""
|
||||
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
|
||||
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=308,L]
|
||||
|
||||
# If the requested filename exists, simply serve it.
|
||||
# We only want to let Apache serve files and not directories.
|
||||
|
|
|
|||
57
rector.php
57
rector.php
|
|
@ -7,6 +7,7 @@ use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
|
|||
use Rector\Config\RectorConfig;
|
||||
use Rector\Doctrine\Set\DoctrineSetList;
|
||||
use Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitThisCallRector;
|
||||
use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertEmptyNullableObjectToAssertInstanceofRector;
|
||||
use Rector\PHPUnit\Set\PHPUnitSetList;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
|
|
@ -16,6 +17,61 @@ use Rector\Symfony\CodeQuality\Rector\MethodCall\LiteralGetToRequestClassConstan
|
|||
use Rector\Symfony\Set\SymfonySetList;
|
||||
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
|
||||
|
||||
return RectorConfig::configure()
|
||||
->withComposerBased(phpunit: true)
|
||||
|
||||
->withSymfonyContainerPhp(__DIR__ . '/tests/symfony-container.php')
|
||||
->withSymfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml')
|
||||
|
||||
->withImportNames(importShortClasses: false)
|
||||
->withPaths([
|
||||
__DIR__ . '/config',
|
||||
__DIR__ . '/public',
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
|
||||
->withSets([
|
||||
PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
|
||||
PHPUnitSetList::PHPUNIT_90,
|
||||
PHPUnitSetList::PHPUNIT_110,
|
||||
PHPUnitSetList::PHPUNIT_CODE_QUALITY,
|
||||
|
||||
|
||||
])
|
||||
|
||||
->withRules([
|
||||
DeclareStrictTypesRector::class
|
||||
])
|
||||
|
||||
->withSkip([
|
||||
//Leave our AssertNull tests alone
|
||||
AssertEmptyNullableObjectToAssertInstanceofRector::class,
|
||||
|
||||
|
||||
CountArrayToEmptyArrayComparisonRector::class,
|
||||
//Leave our !== null checks alone
|
||||
FlipTypeControlToUseExclusiveTypeRector::class,
|
||||
//Leave our PartList TableAction alone
|
||||
ActionSuffixRemoverRector::class,
|
||||
//We declare event listeners via attributes, therefore no need to migrate them to subscribers
|
||||
EventListenerToEventSubscriberRector::class,
|
||||
PreferPHPUnitThisCallRector::class,
|
||||
//Do not replace 'GET' with class constant,
|
||||
LiteralGetToRequestClassConstantRector::class,
|
||||
])
|
||||
|
||||
//Do not apply rules to Symfony own files
|
||||
->withSkip([
|
||||
__DIR__ . '/public/index.php',
|
||||
__DIR__ . '/src/Kernel.php',
|
||||
__DIR__ . '/config/preload.php',
|
||||
__DIR__ . '/config/bundles.php',
|
||||
])
|
||||
|
||||
;
|
||||
|
||||
/*
|
||||
return static function (RectorConfig $rectorConfig): void {
|
||||
$rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml');
|
||||
$rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php');
|
||||
|
|
@ -79,3 +135,4 @@ return static function (RectorConfig $rectorConfig): void {
|
|||
__DIR__ . '/config/bundles.php',
|
||||
]);
|
||||
};
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -70,4 +70,4 @@ class PropertyMetadataFactory implements PropertyMetadataFactoryInterface
|
|||
|
||||
return $metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ class CheckRequirementsCommand extends Command
|
|||
if ($io->isVerbose()) {
|
||||
$io->comment('Checking PHP version...');
|
||||
}
|
||||
//We recommend PHP 8.2, but 8.1 is the minimum
|
||||
if (PHP_VERSION_ID < 80200) {
|
||||
//We recommend PHP 8.2, but 8.2 is the minimum
|
||||
if (PHP_VERSION_ID < 80400) {
|
||||
$io->warning('You are using PHP '. PHP_VERSION .'. This will work, but a newer version is recommended.');
|
||||
} elseif (!$only_issues) {
|
||||
$io->success('PHP version is sufficient.');
|
||||
|
|
@ -84,7 +84,7 @@ class CheckRequirementsCommand extends Command
|
|||
$io->success('You are using a 64-bit system.');
|
||||
}
|
||||
} else {
|
||||
$io->warning('You are using a system with an unknown bit size. That is interesting xD');
|
||||
$io->warning(' areYou using a system with an unknown bit size. That is interesting xD');
|
||||
}
|
||||
|
||||
//Check if opcache is enabled
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Command\Currencies;
|
||||
|
||||
use App\Settings\SystemSettings\LocalizationSettings;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Services\Tools\ExchangeRateUpdater;
|
||||
|
|
@ -39,7 +40,7 @@ use function strlen;
|
|||
#[AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')]
|
||||
class UpdateExchangeRatesCommand extends Command
|
||||
{
|
||||
public function __construct(protected string $base_current, protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater)
|
||||
public function __construct(protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater, private readonly LocalizationSettings $localizationSettings)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
@ -54,13 +55,13 @@ class UpdateExchangeRatesCommand extends Command
|
|||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
//Check for valid base current
|
||||
if (3 !== strlen($this->base_current)) {
|
||||
if (3 !== strlen($this->localizationSettings->baseCurrency)) {
|
||||
$io->error('Chosen Base current is not valid. Check your settings!');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$io->note('Update currency exchange rates with base currency: '.$this->base_current);
|
||||
$io->note('Update currency exchange rates with base currency: '.$this->localizationSettings->baseCurrency);
|
||||
|
||||
//Check what currencies we need to update:
|
||||
$iso_code = $input->getArgument('iso_code');
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class ImportPartKeeprCommand extends Command
|
|||
protected PKDatastructureImporter $datastructureImporter, protected PKPartImporter $partImporter, protected PKImportHelper $importHelper,
|
||||
protected PKOptionalImporter $optionalImporter)
|
||||
{
|
||||
parent::__construct(self::$defaultName);
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
|
|
|
|||
|
|
@ -39,14 +39,7 @@ final class UpgradePermissionsSchemaCommand extends Command
|
|||
{
|
||||
public function __construct(private readonly PermissionSchemaUpdater $permissionSchemaUpdater, private readonly EntityManagerInterface $em, private readonly EventCommentHelper $eventCommentHelper)
|
||||
{
|
||||
parent::__construct(self::$defaultName);
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->setDescription(self::$defaultDescription)
|
||||
;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class UsersPermissionsCommand extends Command
|
|||
{
|
||||
$this->userRepository = $entityManager->getRepository(User::class);
|
||||
|
||||
parent::__construct(self::$defaultName);
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ use App\Entity\Attachments\Attachment;
|
|||
use App\Form\Filters\AttachmentFilterType;
|
||||
use App\Services\Attachments\AttachmentManager;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use App\Settings\BehaviorSettings\TableSettings;
|
||||
use Omines\DataTablesBundle\DataTableFactory;
|
||||
use RuntimeException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
|
@ -98,7 +99,8 @@ class AttachmentFileController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route(path: '/attachment/list', name: 'attachment_list')]
|
||||
public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder): Response
|
||||
public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder,
|
||||
TableSettings $tableSettings): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@attachments.list_attachments');
|
||||
|
||||
|
|
@ -110,7 +112,7 @@ class AttachmentFileController extends AbstractController
|
|||
|
||||
$filterForm->handleRequest($formRequest);
|
||||
|
||||
$table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter])
|
||||
$table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter], ['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||
->handleRequest($request);
|
||||
|
||||
if ($table->isCallback()) {
|
||||
|
|
|
|||
|
|
@ -29,10 +29,14 @@ use App\Form\InfoProviderSystem\PartSearchType;
|
|||
use App\Services\InfoProviderSystem\ExistingPartFinder;
|
||||
use App\Services\InfoProviderSystem\PartInfoRetriever;
|
||||
use App\Services\InfoProviderSystem\ProviderRegistry;
|
||||
use App\Settings\AppSettings;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Jbtronics\SettingsBundle\Form\SettingsFormFactoryInterface;
|
||||
use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpClient\Exception\ClientException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
|
@ -46,7 +50,9 @@ class InfoProviderController extends AbstractController
|
|||
|
||||
public function __construct(private readonly ProviderRegistry $providerRegistry,
|
||||
private readonly PartInfoRetriever $infoRetriever,
|
||||
private readonly ExistingPartFinder $existingPartFinder
|
||||
private readonly ExistingPartFinder $existingPartFinder,
|
||||
private readonly SettingsManagerInterface $settingsManager,
|
||||
private readonly SettingsFormFactoryInterface $settingsFormFactory
|
||||
)
|
||||
{
|
||||
|
||||
|
|
@ -63,6 +69,48 @@ class InfoProviderController extends AbstractController
|
|||
]);
|
||||
}
|
||||
|
||||
#[Route('/provider/{provider}/settings', name: 'info_providers_provider_settings')]
|
||||
public function providerSettings(string $provider, Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@config.change_system_settings');
|
||||
$this->denyAccessUnlessGranted('@info_providers.create_parts');
|
||||
|
||||
$providerInstance = $this->providerRegistry->getProviderByKey($provider);
|
||||
$settingsClass = $providerInstance->getProviderInfo()['settings_class'] ?? throw new \LogicException('Provider ' . $provider . ' does not have a settings class defined');
|
||||
|
||||
//Create a clone of the settings object
|
||||
$settings = $this->settingsManager->createTemporaryCopy($settingsClass);
|
||||
|
||||
//Create a form builder for the settings object
|
||||
$builder = $this->settingsFormFactory->createSettingsFormBuilder($settings);
|
||||
|
||||
//Add a submit button to the form
|
||||
$builder->add('submit', SubmitType::class, ['label' => 'save']);
|
||||
|
||||
//Create the form
|
||||
$form = $builder->getForm();
|
||||
$form->handleRequest($request);
|
||||
|
||||
//If the form was submitted and is valid, save the settings
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->settingsManager->mergeTemporaryCopy($settings);
|
||||
$this->settingsManager->save($settings);
|
||||
|
||||
$this->addFlash('success', t('settings.flash.saved'));
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && !$form->isValid()) {
|
||||
$this->addFlash('error', t('settings.flash.invalid'));
|
||||
}
|
||||
|
||||
//Render the form
|
||||
return $this->render('info_providers/settings/provider_settings.html.twig', [
|
||||
'form' => $form,
|
||||
'info_provider_key' => $provider,
|
||||
'info_provider_info' => $providerInstance->getProviderInfo(),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/search', name: 'info_providers_search')]
|
||||
#[Route('/update/{target}', name: 'info_providers_update_part_search')]
|
||||
public function search(Request $request, #[MapEntity(id: 'target')] ?Part $update_target, LoggerInterface $exceptionLogger): Response
|
||||
|
|
@ -128,4 +176,4 @@ class InfoProviderController extends AbstractController
|
|||
'update_target' => $update_target
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ use App\Services\LogSystem\LogEntryExtraFormatter;
|
|||
use App\Services\LogSystem\LogLevelHelper;
|
||||
use App\Services\LogSystem\LogTargetHelper;
|
||||
use App\Services\LogSystem\TimeTravel;
|
||||
use App\Settings\BehaviorSettings\TableSettings;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use InvalidArgumentException;
|
||||
use Omines\DataTablesBundle\DataTableFactory;
|
||||
|
|
@ -58,7 +59,7 @@ class LogController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route(path: '/', name: 'log_view')]
|
||||
public function showLogs(Request $request, DataTableFactory $dataTable): Response
|
||||
public function showLogs(Request $request, DataTableFactory $dataTable, TableSettings $tableSettings): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@system.show_logs');
|
||||
|
||||
|
|
@ -72,7 +73,7 @@ class LogController extends AbstractController
|
|||
|
||||
$table = $dataTable->createFromType(LogDataTable::class, [
|
||||
'filter' => $filter,
|
||||
])
|
||||
], ['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||
->handleRequest($request);
|
||||
|
||||
if ($table->isCallback()) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use App\Exceptions\InvalidRegexException;
|
|||
use App\Form\Filters\PartFilterType;
|
||||
use App\Services\Parts\PartsTableActionHandler;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use App\Settings\BehaviorSettings\TableSettings;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Omines\DataTablesBundle\DataTableFactory;
|
||||
|
|
@ -51,7 +52,12 @@ use function Symfony\Component\Translation\t;
|
|||
|
||||
class PartListsController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager, private readonly NodesListBuilder $nodesListBuilder, private readonly DataTableFactory $dataTableFactory, private readonly TranslatorInterface $translator)
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager,
|
||||
private readonly NodesListBuilder $nodesListBuilder,
|
||||
private readonly DataTableFactory $dataTableFactory,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly TableSettings $tableSettings
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -155,11 +161,7 @@ class PartListsController extends AbstractController
|
|||
|
||||
$filterForm->handleRequest($formRequest);
|
||||
|
||||
$table = $this->dataTableFactory->createFromType(
|
||||
PartsDataTable::class,
|
||||
array_merge(['filter' => $filter], $additional_table_vars),
|
||||
['lengthMenu' => PartsDataTable::LENGTH_MENU]
|
||||
)
|
||||
$table = $this->dataTableFactory->createFromType(PartsDataTable::class, array_merge(['filter' => $filter], $additional_table_vars), ['pageLength' => $this->tableSettings->fullDefaultPageSize])
|
||||
->handleRequest($request);
|
||||
|
||||
if ($table->isCallback()) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use App\Form\ProjectSystem\ProjectBuildType;
|
|||
use App\Helpers\Projects\ProjectBuildRequest;
|
||||
use App\Services\ImportExportSystem\BOMImporter;
|
||||
use App\Services\ProjectSystem\ProjectBuildHelper;
|
||||
use App\Settings\BehaviorSettings\TableSettings;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use League\Csv\SyntaxError;
|
||||
|
|
@ -55,11 +56,12 @@ class ProjectController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])]
|
||||
public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper): Response
|
||||
public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper, TableSettings $tableSettings): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $project);
|
||||
|
||||
$table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project])
|
||||
$table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project],
|
||||
['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||
->handleRequest($request);
|
||||
|
||||
if ($table->isCallback()) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||
namespace App\Controller;
|
||||
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Settings\SystemSettings\LocalizationSettings;
|
||||
use function function_exists;
|
||||
use function in_array;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
|
@ -35,7 +36,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||
*/
|
||||
class RedirectController extends AbstractController
|
||||
{
|
||||
public function __construct(protected string $default_locale, protected TranslatorInterface $translator, protected bool $enforce_index_php)
|
||||
public function __construct(private readonly LocalizationSettings $localizationSettings, protected TranslatorInterface $translator, protected bool $enforce_index_php)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ class RedirectController extends AbstractController
|
|||
public function addLocalePart(Request $request): RedirectResponse
|
||||
{
|
||||
//By default, we use the global default locale
|
||||
$locale = $this->default_locale;
|
||||
$locale = $this->localizationSettings->locale;
|
||||
|
||||
//Check if a user has set a preferred language setting:
|
||||
$user = $this->getUser();
|
||||
|
|
|
|||
81
src/Controller/SettingsController.php
Normal file
81
src/Controller/SettingsController.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use App\Settings\AppSettings;
|
||||
use Jbtronics\SettingsBundle\Form\SettingsFormFactoryInterface;
|
||||
use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
|
||||
use function Symfony\Component\Translation\t;
|
||||
|
||||
class SettingsController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly SettingsManagerInterface $settingsManager, private readonly SettingsFormFactoryInterface $settingsFormFactory)
|
||||
{}
|
||||
|
||||
#[Route("/settings", name: "system_settings")]
|
||||
public function systemSettings(Request $request, TagAwareCacheInterface $cache): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@config.change_system_settings');
|
||||
|
||||
//Create a clone of the settings object
|
||||
$settings = $this->settingsManager->createTemporaryCopy(AppSettings::class);
|
||||
|
||||
//Create a form builder for the settings object
|
||||
$builder = $this->settingsFormFactory->createSettingsFormBuilder($settings);
|
||||
|
||||
//Add a submit button to the form
|
||||
$builder->add('submit', SubmitType::class, ['label' => 'save']);
|
||||
|
||||
//Create the form
|
||||
$form = $builder->getForm();
|
||||
$form->handleRequest($request);
|
||||
|
||||
//If the form was submitted and is valid, save the settings
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->settingsManager->mergeTemporaryCopy($settings);
|
||||
$this->settingsManager->save($settings);
|
||||
|
||||
//It might be possible, that the tree settings have changed, so clear the cache
|
||||
$cache->invalidateTags(['tree_treeview', 'sidebar_tree_update']);
|
||||
|
||||
$this->addFlash('success', t('settings.flash.saved'));
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && !$form->isValid()) {
|
||||
$this->addFlash('error', t('settings.flash.invalid'));
|
||||
}
|
||||
|
||||
//Render the form
|
||||
return $this->render('settings/settings.html.twig', [
|
||||
'form' => $form
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ use App\Services\Doctrine\DBInfoHelper;
|
|||
use App\Services\Doctrine\NatsortDebugHelper;
|
||||
use App\Services\Misc\GitVersionInfo;
|
||||
use App\Services\System\UpdateAvailableManager;
|
||||
use App\Settings\AppSettings;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
|
@ -47,7 +48,8 @@ class ToolsController extends AbstractController
|
|||
|
||||
#[Route(path: '/server_infos', name: 'tools_server_infos')]
|
||||
public function systemInfos(GitVersionInfo $versionInfo, DBInfoHelper $DBInfoHelper, NatsortDebugHelper $natsortDebugHelper,
|
||||
AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager): Response
|
||||
AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager,
|
||||
AppSettings $settings): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@system.server_infos');
|
||||
|
||||
|
|
@ -55,23 +57,23 @@ class ToolsController extends AbstractController
|
|||
//Part-DB section
|
||||
'git_branch' => $versionInfo->getGitBranchName(),
|
||||
'git_commit' => $versionInfo->getGitCommitHash(),
|
||||
'default_locale' => $this->getParameter('partdb.locale'),
|
||||
'default_timezone' => $this->getParameter('partdb.timezone'),
|
||||
'default_currency' => $this->getParameter('partdb.default_currency'),
|
||||
'default_theme' => $this->getParameter('partdb.global_theme'),
|
||||
'default_locale' => $settings->system->localization->locale,
|
||||
'default_timezone' => $settings->system->localization->timezone,
|
||||
'default_currency' => $settings->system->localization->baseCurrency,
|
||||
'default_theme' => $settings->system->customization->theme,
|
||||
'enabled_locales' => $this->getParameter('partdb.locale_menu'),
|
||||
'demo_mode' => $this->getParameter('partdb.demo_mode'),
|
||||
'use_gravatar' => $settings->system->privacy->useGravatar,
|
||||
'gdpr_compliance' => $this->getParameter('partdb.gdpr_compliance'),
|
||||
'use_gravatar' => $this->getParameter('partdb.users.use_gravatar'),
|
||||
'email_password_reset' => $this->getParameter('partdb.users.email_pw_reset'),
|
||||
'environment' => $this->getParameter('kernel.environment'),
|
||||
'is_debug' => $this->getParameter('kernel.debug'),
|
||||
'email_sender' => $this->getParameter('partdb.mail.sender_email'),
|
||||
'email_sender_name' => $this->getParameter('partdb.mail.sender_name'),
|
||||
'allow_attachments_downloads' => $this->getParameter('partdb.attachments.allow_downloads'),
|
||||
'allow_attachments_downloads' => $settings->system->attachments->allowDownloads,
|
||||
'detailed_error_pages' => $this->getParameter('partdb.error_pages.show_help'),
|
||||
'error_page_admin_email' => $this->getParameter('partdb.error_pages.admin_email'),
|
||||
'configured_max_file_size' => $this->getParameter('partdb.attachments.max_file_size'),
|
||||
'configured_max_file_size' => $settings->system->attachments->maxFileSize,
|
||||
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumAllowedUploadSize(),
|
||||
'saml_enabled' => $this->getParameter('partdb.saml.enabled'),
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ class ColumnSortHelper
|
|||
* Apply the visibility configuration to the given DataTable and configure the columns.
|
||||
* @param DataTable $dataTable
|
||||
* @param string|array $visible_columns Either a list or a comma separated string of column names, which should
|
||||
* be visible by default. If a column is not listed here, it will be hidden by default.
|
||||
* be visible by default. If a column is not listed here, it will be hidden by default. If an array of enum values are passed,
|
||||
* their value will be used as the column name.
|
||||
* @return void
|
||||
*/
|
||||
public function applyVisibilityAndConfigureColumns(DataTable $dataTable, string|array $visible_columns,
|
||||
|
|
@ -83,6 +84,14 @@ class ColumnSortHelper
|
|||
$visible_columns = array_map(trim(...), explode(",", $visible_columns));
|
||||
}
|
||||
|
||||
//If $visible_columns is a list of enum values, convert them to the column names
|
||||
foreach ($visible_columns as &$value) {
|
||||
if ($value instanceof \BackedEnum) {
|
||||
$value = $value->value;
|
||||
}
|
||||
}
|
||||
unset ($value);
|
||||
|
||||
$processed_columns = [];
|
||||
|
||||
//First add all columns which visibility is not configurable
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ use App\Entity\Parts\PartLot;
|
|||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Services\EntityURLGenerator;
|
||||
use App\Services\Formatters\AmountFormatter;
|
||||
use App\Settings\BehaviorSettings\TableSettings;
|
||||
use Doctrine\ORM\AbstractQuery;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
|
||||
|
|
@ -65,8 +66,8 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
private readonly AmountFormatter $amountFormatter,
|
||||
private readonly PartDataTableHelper $partDataTableHelper,
|
||||
private readonly Security $security,
|
||||
private readonly string $visible_columns,
|
||||
private readonly ColumnSortHelper $csh,
|
||||
private readonly TableSettings $tableSettings,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +247,7 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
]);
|
||||
|
||||
//Apply the user configured order and visibility and add the columns to the table
|
||||
$this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
|
||||
$this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->tableSettings->partsDefaultColumns,
|
||||
"TABLE_PARTS_DEFAULT_COLUMNS");
|
||||
|
||||
$dataTable->addOrderBy('name')
|
||||
|
|
|
|||
55
src/Doctrine/Migration/ContainerAwareMigrationFactory.php
Normal file
55
src/Doctrine/Migration/ContainerAwareMigrationFactory.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Doctrine\Migration;
|
||||
|
||||
use App\Services\UserSystem\PermissionPresetsHelper;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\Migrations\Version\MigrationFactory;
|
||||
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
|
||||
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
#[AsDecorator("doctrine.migrations.migrations_factory")]
|
||||
class ContainerAwareMigrationFactory implements MigrationFactory
|
||||
{
|
||||
public function __construct(private readonly MigrationFactory $decorated,
|
||||
//List all services that should be available in migrations here
|
||||
#[AutowireLocator([
|
||||
PermissionPresetsHelper::class
|
||||
])]
|
||||
private readonly ContainerInterface $container)
|
||||
{
|
||||
}
|
||||
|
||||
public function createVersion(string $migrationClassName): AbstractMigration
|
||||
{
|
||||
$migration = $this->decorated->createVersion($migrationClassName);
|
||||
|
||||
if ($migration instanceof ContainerAwareMigrationInterface) {
|
||||
$migration->setContainer($this->container);
|
||||
}
|
||||
|
||||
return $migration;
|
||||
}
|
||||
}
|
||||
31
src/Doctrine/Migration/ContainerAwareMigrationInterface.php
Normal file
31
src/Doctrine/Migration/ContainerAwareMigrationInterface.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Doctrine\Migration;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
interface ContainerAwareMigrationInterface
|
||||
{
|
||||
public function setContainer(?ContainerInterface $container = null): void;
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\Types;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\Exception\SerializationFailed;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
use function is_resource;
|
||||
use function restore_error_handler;
|
||||
use function serialize;
|
||||
use function set_error_handler;
|
||||
use function stream_get_contents;
|
||||
use function unserialize;
|
||||
|
||||
use const E_DEPRECATED;
|
||||
use const E_USER_DEPRECATED;
|
||||
|
||||
/**
|
||||
* This class is taken from doctrine ORM 3.8. https://github.com/doctrine/dbal/blob/3.8.x/src/Types/ArrayType.php
|
||||
*
|
||||
* It was removed in doctrine ORM 4.0. However, we require it for backward compatibility with WebauthnKey.
|
||||
* Therefore, we manually added it here as a custom type as a forward compatibility layer.
|
||||
*/
|
||||
class ArrayType extends Type
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
|
||||
{
|
||||
return $platform->getClobTypeDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): string
|
||||
{
|
||||
return serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = is_resource($value) ? stream_get_contents($value) : $value;
|
||||
|
||||
set_error_handler(function (int $code, string $message): bool {
|
||||
if ($code === E_DEPRECATED || $code === E_USER_DEPRECATED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Change to original code. Use SerializationFailed instead of ConversionException.
|
||||
throw new SerializationFailed("Serialization failed (Code $code): " . $message);
|
||||
});
|
||||
|
||||
try {
|
||||
//Change to original code. Use false for allowed_classes, to avoid unsafe unserialization of objects.
|
||||
return unserialize($value, ['allowed_classes' => false]);
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return "array";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/5509',
|
||||
'%s is deprecated.',
|
||||
__METHOD__,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ use App\Entity\Attachments\SupplierAttachment;
|
|||
use App\Entity\Attachments\UserAttachment;
|
||||
use App\Entity\Parameters\AbstractParameter;
|
||||
use App\Entity\Parts\Category;
|
||||
use App\Entity\PriceInformations\Pricedetail;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Entity\ProjectSystem\ProjectBOMEntry;
|
||||
use App\Entity\Parts\Footprint;
|
||||
|
|
@ -67,7 +68,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
|||
* Every database table which are managed with this class (or a subclass of it)
|
||||
* must have the table row "id"!! The ID is the unique key to identify the elements.
|
||||
*/
|
||||
#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => AttachmentType::class, 'attachment' => Attachment::class, 'attachment_type_attachment' => AttachmentTypeAttachment::class, 'category_attachment' => CategoryAttachment::class, 'currency_attachment' => CurrencyAttachment::class, 'footprint_attachment' => FootprintAttachment::class, 'group_attachment' => GroupAttachment::class, 'label_attachment' => LabelAttachment::class, 'manufacturer_attachment' => ManufacturerAttachment::class, 'measurement_unit_attachment' => MeasurementUnitAttachment::class, 'part_attachment' => PartAttachment::class, 'project_attachment' => ProjectAttachment::class, 'storelocation_attachment' => StorageLocationAttachment::class, 'supplier_attachment' => SupplierAttachment::class, 'user_attachment' => UserAttachment::class, 'category' => Category::class, 'project' => Project::class, 'project_bom_entry' => ProjectBOMEntry::class, 'footprint' => Footprint::class, 'group' => Group::class, 'manufacturer' => Manufacturer::class, 'orderdetail' => Orderdetail::class, 'part' => Part::class, 'pricedetail' => 'App\Entity\PriceInformation\Pricedetail', 'storelocation' => StorageLocation::class, 'part_lot' => PartLot::class, 'currency' => Currency::class, 'measurement_unit' => MeasurementUnit::class, 'parameter' => AbstractParameter::class, 'supplier' => Supplier::class, 'user' => User::class])]
|
||||
#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => AttachmentType::class, 'attachment' => Attachment::class, 'attachment_type_attachment' => AttachmentTypeAttachment::class, 'category_attachment' => CategoryAttachment::class, 'currency_attachment' => CurrencyAttachment::class, 'footprint_attachment' => FootprintAttachment::class, 'group_attachment' => GroupAttachment::class, 'label_attachment' => LabelAttachment::class, 'manufacturer_attachment' => ManufacturerAttachment::class, 'measurement_unit_attachment' => MeasurementUnitAttachment::class, 'part_attachment' => PartAttachment::class, 'project_attachment' => ProjectAttachment::class, 'storelocation_attachment' => StorageLocationAttachment::class, 'supplier_attachment' => SupplierAttachment::class, 'user_attachment' => UserAttachment::class, 'category' => Category::class, 'project' => Project::class, 'project_bom_entry' => ProjectBOMEntry::class, 'footprint' => Footprint::class, 'group' => Group::class, 'manufacturer' => Manufacturer::class, 'orderdetail' => Orderdetail::class, 'part' => Part::class, 'pricedetail' => Pricedetail::class, 'storelocation' => StorageLocation::class, 'part_lot' => PartLot::class, 'currency' => Currency::class, 'measurement_unit' => MeasurementUnit::class, 'parameter' => AbstractParameter::class, 'supplier' => Supplier::class, 'user' => User::class])]
|
||||
#[ORM\MappedSuperclass(repositoryClass: DBElementRepository::class)]
|
||||
abstract class AbstractDBElement implements JsonSerializable
|
||||
{
|
||||
|
|
|
|||
35
src/Entity/SettingsEntry.php
Normal file
35
src/Entity/SettingsEntry.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Jbtronics\SettingsBundle\Entity\AbstractSettingsORMEntry;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
class SettingsEntry extends AbstractSettingsORMEntry
|
||||
{
|
||||
#[ORM\Id, ORM\GeneratedValue, ORM\Column(type: Types::INTEGER)]
|
||||
protected int $id;
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
|||
/**
|
||||
* @var string|null The language/locale the user prefers
|
||||
*/
|
||||
#[Assert\Language]
|
||||
#[Assert\Locale]
|
||||
#[Groups(['full', 'import', 'user:read'])]
|
||||
#[ORM\Column(name: 'config_language', type: Types::STRING, nullable: true)]
|
||||
protected ?string $language = '';
|
||||
|
|
|
|||
|
|
@ -100,16 +100,19 @@ class WebauthnKey extends BasePublicKeyCredentialSource implements TimeStampable
|
|||
public static function fromRegistration(BasePublicKeyCredentialSource $registration): self
|
||||
{
|
||||
return new self(
|
||||
$registration->getPublicKeyCredentialId(),
|
||||
$registration->getType(),
|
||||
$registration->getTransports(),
|
||||
$registration->getAttestationType(),
|
||||
$registration->getTrustPath(),
|
||||
$registration->getAaguid(),
|
||||
$registration->getCredentialPublicKey(),
|
||||
$registration->getUserHandle(),
|
||||
$registration->getCounter(),
|
||||
$registration->getOtherUI()
|
||||
publicKeyCredentialId: $registration->publicKeyCredentialId,
|
||||
type: $registration->type,
|
||||
transports: $registration->transports,
|
||||
attestationType: $registration->attestationType,
|
||||
trustPath: $registration->trustPath,
|
||||
aaguid: $registration->aaguid,
|
||||
credentialPublicKey: $registration->credentialPublicKey,
|
||||
userHandle: $registration->userHandle,
|
||||
counter: $registration->counter,
|
||||
otherUI: $registration->otherUI,
|
||||
backupEligible: $registration->backupEligible,
|
||||
backupStatus: $registration->backupStatus,
|
||||
uvInitialized: $registration->uvInitialized,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ use App\Services\LogSystem\EventCommentHelper;
|
|||
use App\Services\LogSystem\EventLogger;
|
||||
use App\Services\LogSystem\EventUndoHelper;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
|
||||
use App\Settings\SystemSettings\HistorySettings;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||
use Doctrine\ORM\Event\PostFlushEventArgs;
|
||||
|
|
@ -74,14 +76,15 @@ class EventLoggerListener
|
|||
];
|
||||
|
||||
protected const MAX_STRING_LENGTH = 2000;
|
||||
protected bool $save_new_data;
|
||||
|
||||
public function __construct(protected EventLogger $logger, protected SerializerInterface $serializer, protected EventCommentHelper $eventCommentHelper,
|
||||
protected bool $save_changed_fields, protected bool $save_changed_data, protected bool $save_removed_data, bool $save_new_data,
|
||||
protected PropertyAccessorInterface $propertyAccessor, protected EventUndoHelper $eventUndoHelper)
|
||||
public function __construct(
|
||||
protected EventLogger $logger,
|
||||
protected SerializerInterface $serializer,
|
||||
protected EventCommentHelper $eventCommentHelper,
|
||||
private readonly HistorySettings $settings,
|
||||
protected PropertyAccessorInterface $propertyAccessor,
|
||||
protected EventUndoHelper $eventUndoHelper)
|
||||
{
|
||||
//This option only makes sense if save_changed_data is true
|
||||
$this->save_new_data = $save_new_data && $save_changed_data;
|
||||
}
|
||||
|
||||
public function onFlush(OnFlushEventArgs $eventArgs): void
|
||||
|
|
@ -200,14 +203,14 @@ class EventLoggerListener
|
|||
if ($this->eventUndoHelper->isUndo()) {
|
||||
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
|
||||
}
|
||||
if ($this->save_removed_data) {
|
||||
if ($this->settings->saveRemovedData) {
|
||||
//The 4th param is important here, as we delete the element...
|
||||
$this->saveChangeSet($entity, $log, $em, true);
|
||||
}
|
||||
$this->logger->logFromOnFlush($log);
|
||||
|
||||
//Check if we have to log CollectionElementDeleted entries
|
||||
if ($this->save_changed_data) {
|
||||
if ($this->settings->saveOldData) {
|
||||
$metadata = $em->getClassMetadata($entity::class);
|
||||
$mappings = $metadata->getAssociationMappings();
|
||||
//Check if class is whitelisted for CollectionElementDeleted entry
|
||||
|
|
@ -243,9 +246,9 @@ class EventLoggerListener
|
|||
}
|
||||
|
||||
$log = new ElementEditedLogEntry($entity);
|
||||
if ($this->save_changed_data) {
|
||||
if ($this->settings->saveOldData) {
|
||||
$this->saveChangeSet($entity, $log, $em);
|
||||
} elseif ($this->save_changed_fields) {
|
||||
} elseif ($this->settings->saveChangedFields) {
|
||||
$changed_fields = array_keys($uow->getEntityChangeSet($entity));
|
||||
//Remove lastModified field, as this is always changed (gives us no additional info)
|
||||
$changed_fields = array_diff($changed_fields, ['lastModified']);
|
||||
|
|
@ -313,7 +316,7 @@ class EventLoggerListener
|
|||
$changeSet = $uow->getEntityChangeSet($entity);
|
||||
$old_data = array_combine(array_keys($changeSet), array_column($changeSet, 0));
|
||||
//If save_new_data is enabled, we extract it from the change set
|
||||
if ($this->save_new_data) {
|
||||
if ($this->settings->saveNewData && $this->settings->saveOldData) { //Only useful if we save old data too
|
||||
$new_data = array_combine(array_keys($changeSet), array_column($changeSet, 1));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\EventSubscriber;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
|
||||
/**
|
||||
* This subscriber sets a Header in Debug mode that signals the Symfony Profiler to also update on Ajax requests.
|
||||
*/
|
||||
final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public function __construct(private readonly bool $kernel_debug_enabled)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* The array keys are event names and the value can be:
|
||||
*
|
||||
* * The method name to call (priority defaults to 0)
|
||||
* * An array composed of the method name to call and the priority
|
||||
* * An array of arrays composed of the method names to call and respective
|
||||
* priorities, or 0 if unset
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* * ['eventName' => 'methodName']
|
||||
* * ['eventName' => ['methodName', $priority]]
|
||||
* * ['eventName' => [['methodName1', $priority], ['methodName2']]]
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['kernel.response' => 'onKernelResponse'];
|
||||
}
|
||||
|
||||
public function onKernelResponse(ResponseEvent $event): void
|
||||
{
|
||||
if (!$this->kernel_debug_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
$response->headers->set('Symfony-Debug-Toolbar-Replace', '1');
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||
namespace App\EventSubscriber\UserSystem;
|
||||
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Settings\SystemSettings\LocalizationSettings;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\ControllerEvent;
|
||||
|
|
@ -33,7 +34,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
|||
*/
|
||||
final class SetUserTimezoneSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public function __construct(private readonly string $default_timezone, private readonly Security $security)
|
||||
public function __construct(private readonly LocalizationSettings $localizationSettings, private readonly Security $security)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,8 +49,8 @@ final class SetUserTimezoneSubscriber implements EventSubscriberInterface
|
|||
}
|
||||
|
||||
//Fill with default value if needed
|
||||
if (null === $timezone && $this->default_timezone !== '') {
|
||||
$timezone = $this->default_timezone;
|
||||
if (null === $timezone && $this->localizationSettings->timezone !== '') {
|
||||
$timezone = $this->localizationSettings->timezone;
|
||||
}
|
||||
|
||||
//If timezone was configured anywhere set it, otherwise just use the one from php.ini
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue