Merge branch 'master' into turbo
3
.env
|
@ -9,6 +9,7 @@
|
||||||
# Real environment variables win over .env files.
|
# Real environment variables win over .env files.
|
||||||
#
|
#
|
||||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||||
|
# https://symfony.com/doc/current/configuration/secrets.html
|
||||||
#
|
#
|
||||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||||
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
|
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
|
||||||
|
@ -82,5 +83,5 @@ HISTORY_SAVE_REMOVED_DATA=0
|
||||||
|
|
||||||
|
|
||||||
###> symfony/mailer ###
|
###> symfony/mailer ###
|
||||||
# MAILER_DSN=smtp://localhost
|
# MAILER_DSN=null://null
|
||||||
###< symfony/mailer ###
|
###< symfony/mailer ###
|
||||||
|
|
18
.github/workflows/docker_build.yml
vendored
|
@ -18,32 +18,38 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Docker meta
|
name: Docker meta
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
uses: crazy-max/ghaction-docker-meta@v1
|
uses: docker/metadata-action@v4
|
||||||
with:
|
with:
|
||||||
# list of Docker images to use as base name for tags
|
# list of Docker images to use as base name for tags
|
||||||
images: |
|
images: |
|
||||||
jbtronics/part-db1
|
jbtronics/part-db1
|
||||||
|
# Mark the image build from master as latest (as we dont have really releases yet)
|
||||||
|
tags: |
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
type=ref,event=branch,
|
||||||
|
type=ref,event=tag,
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v2
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v2
|
||||||
-
|
-
|
||||||
name: Login to DockerHub
|
name: Login to DockerHub
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
|
4
.github/workflows/static_analysis.yml
vendored
|
@ -12,14 +12,14 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Get Composer Cache Directory
|
- name: Get Composer Cache Directory
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
|
49
.github/workflows/tests.yml
vendored
|
@ -12,23 +12,34 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
phpunit:
|
phpunit:
|
||||||
name: PHPUnit and coverage Test (${{ matrix.php-versions }})
|
name: PHPUnit and coverage Test (PHP ${{ matrix.php-versions }}, ${{ matrix.db-type }})
|
||||||
# Ubuntu 20.04 ships MySQL 8.0 which causes problems with login, so we just use ubuntu 18.04 for now...
|
# Ubuntu 20.04 ships MySQL 8.0 which causes problems with login, so we just use ubuntu 18.04 for now...
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
|
|
||||||
env:
|
|
||||||
APP_ENV: test
|
|
||||||
SYMFONY_DEPRECATIONS_HELPER: disabled
|
|
||||||
DATABASE_URL: 'mysql://root:root@127.0.0.1:3306/test'
|
|
||||||
PHP_VERSION: ${{ matrix.php-versions }}
|
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php-versions: ['7.3', '7.4', '8.0', '8.1']
|
php-versions: [ '7.3', '7.4', '8.0', '8.1' ]
|
||||||
|
db-type: [ 'mysql', 'sqlite' ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Note that we set DATABASE URL later based on our db-type matrix value
|
||||||
|
APP_ENV: test
|
||||||
|
SYMFONY_DEPRECATIONS_HELPER: disabled
|
||||||
|
PHP_VERSION: ${{ matrix.php-versions }}
|
||||||
|
DB_TYPE: ${{ matrix.db-type }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Set Database env for MySQL
|
||||||
|
run: echo "DATABASE_URL=mysql://root:root@127.0.0.1:3306/test" >> $GITHUB_ENV
|
||||||
|
if: matrix.db-type == 'mysql'
|
||||||
|
|
||||||
|
- name: Set Database env for SQLite
|
||||||
|
run: echo "DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"" >> $GITHUB_ENV
|
||||||
|
if: matrix.db-type == 'sqlite'
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
|
@ -63,7 +74,7 @@ jobs:
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||||
|
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v3
|
||||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
|
@ -75,9 +86,9 @@ jobs:
|
||||||
run: composer install --prefer-dist --no-progress
|
run: composer install --prefer-dist --no-progress
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: '12'
|
node-version: '16'
|
||||||
|
|
||||||
- name: Install yarn dependencies
|
- name: Install yarn dependencies
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
@ -87,6 +98,12 @@ jobs:
|
||||||
|
|
||||||
- name: Create DB
|
- name: Create DB
|
||||||
run: php bin/console --env test doctrine:database:create --if-not-exists -n
|
run: php bin/console --env test doctrine:database:create --if-not-exists -n
|
||||||
|
if: matrix.db-type == 'mysql'
|
||||||
|
|
||||||
|
# Checkinf for existance is not supported for sqlite, so do it without it
|
||||||
|
- name: Create DB
|
||||||
|
run: php bin/console --env test doctrine:database:create -n
|
||||||
|
if: matrix.db-type == 'sqlite'
|
||||||
|
|
||||||
- name: Do migrations
|
- name: Do migrations
|
||||||
run: php bin/console --env test doctrine:migrations:migrate -n
|
run: php bin/console --env test doctrine:migrations:migrate -n
|
||||||
|
@ -98,9 +115,9 @@ jobs:
|
||||||
run: ./bin/phpunit --coverage-clover=coverage.xml
|
run: ./bin/phpunit --coverage-clover=coverage.xml
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
env_vars: PHP_VERSION
|
env_vars: PHP_VERSION,DB_TYPE
|
||||||
|
|
||||||
- name: Test app:clean-attachments
|
- name: Test app:clean-attachments
|
||||||
run: php bin/console app:clean-attachments -n
|
run: php bin/console app:clean-attachments -n
|
||||||
|
|
26
Dockerfile
|
@ -1,14 +1,30 @@
|
||||||
FROM php:7-apache
|
FROM php:8.1-apache
|
||||||
|
|
||||||
# Install needed dependencies for PHP build
|
# Install needed dependencies for PHP build
|
||||||
RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \
|
RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \
|
||||||
libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libonig-dev libxslt-dev vim \
|
libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \
|
||||||
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
|
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install GD (we have to configure GD first before installing it, see issue #115)
|
# Install GD with support for multiple formats
|
||||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install gd
|
RUN docker-php-ext-configure gd \
|
||||||
|
--with-webp \
|
||||||
|
--with-jpeg \
|
||||||
|
--with-freetype \
|
||||||
|
&& docker-php-ext-install gd
|
||||||
|
|
||||||
# Install other needed PHP extensions
|
# Install other needed PHP extensions
|
||||||
RUN docker-php-ext-install pdo_mysql curl intl mbstring bcmath gd zip xml xsl
|
RUN docker-php-ext-install pdo_mysql curl intl mbstring bcmath zip xml xsl
|
||||||
|
|
||||||
|
# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html)
|
||||||
|
RUN docker-php-ext-enable opcache; \
|
||||||
|
{ \
|
||||||
|
echo 'opcache.memory_consumption=256'; \
|
||||||
|
echo 'opcache.max_accelerated_files=20000'; \
|
||||||
|
echo 'opcache.validate_timestamp=0'; \
|
||||||
|
# Configure Realpath cache for performance
|
||||||
|
echo 'realpath_cache_size=4096K'; \
|
||||||
|
echo 'realpath_cache_ttl=600'; \
|
||||||
|
} > /usr/local/etc/php/conf.d/symfony-recommended.ini
|
||||||
|
|
||||||
# Install yarn
|
# Install yarn
|
||||||
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
[](https://part-db.crowdin.com/part-db)
|
||||||
|
|
||||||
# Part-DB
|
# Part-DB
|
||||||
Part-DB is an Open-Source inventory managment system for your electronic components.
|
Part-DB is an Open-Source inventory managment system for your electronic components.
|
||||||
|
@ -67,6 +68,8 @@ See [UPGRADE](UPGRADE.md) for more infos.
|
||||||
|
|
||||||
*Hint:* A docker image is available under [jbtronics/part-db1](https://hub.docker.com/r/jbtronics/part-db1). How to setup Part-DB via docker is described [here](https://github.com/Part-DB/Part-DB-symfony/blob/master/docs/docker/docker-install.md).
|
*Hint:* A docker image is available under [jbtronics/part-db1](https://hub.docker.com/r/jbtronics/part-db1). How to setup Part-DB via docker is described [here](https://github.com/Part-DB/Part-DB-symfony/blob/master/docs/docker/docker-install.md).
|
||||||
|
|
||||||
|
**Below you find some general hints for installtion, see [here](docs/installation/installation_guide-debian.md) for a detailed guide how to install Part-DB on Debian/Ubuntu.**
|
||||||
|
|
||||||
1. Copy or clone this repository into a folder on your server.
|
1. Copy or clone this repository into a folder on your server.
|
||||||
2. Configure your webserver to serve from the `public/` folder. See [here](https://symfony.com/doc/current/setup/web_server_configuration.html)
|
2. Configure your webserver to serve from the `public/` folder. See [here](https://symfony.com/doc/current/setup/web_server_configuration.html)
|
||||||
for additional informations.
|
for additional informations.
|
||||||
|
@ -74,7 +77,7 @@ for additional informations.
|
||||||
* Change the line `APP_ENV=dev` to `APP_ENV=prod`
|
* Change the line `APP_ENV=dev` to `APP_ENV=prod`
|
||||||
* If you do not want to use SQLite, change the value of `DATABASE_URL=` to your needs (see [here](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url)) for the format.
|
* If you do not want to use SQLite, change the value of `DATABASE_URL=` to your needs (see [here](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url)) for the format.
|
||||||
In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so choose wisely.
|
In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so choose wisely.
|
||||||
4. Install composer dependencies and generate autoload files: `composer install --no-dev`
|
4. Install composer dependencies and generate autoload files: `composer install -o --no-dev`
|
||||||
5. If you have put Part-DB into a sub-directory on your server (like `part-db/`), you have to edit the file
|
5. If you have put Part-DB into a sub-directory on your server (like `part-db/`), you have to edit the file
|
||||||
`webpack.config.js` and uncomment the lines (remove the `//` before the lines) `.setPublicPath('/part-db/build')` (line 43) and
|
`webpack.config.js` and uncomment the lines (remove the `//` before the lines) `.setPublicPath('/part-db/build')` (line 43) and
|
||||||
`.setManifestKeyPrefix('build/')` (line 44). You have to replace `/part-db` with your own path on line 44.
|
`.setManifestKeyPrefix('build/')` (line 44). You have to replace `/part-db` with your own path on line 44.
|
||||||
|
@ -89,6 +92,10 @@ for additional informations.
|
||||||
When you want to upgrade to a newer version, then just copy the new files into the folder
|
When you want to upgrade to a newer version, then just copy the new files into the folder
|
||||||
and repeat the steps 4. to 7.
|
and repeat the steps 4. to 7.
|
||||||
|
|
||||||
|
### Reverse proxy
|
||||||
|
If you are using a reverse proxy, you have to ensure that the proxies sets the `X-Forwarded-*` headers correctly, or you will get HTTP/HTTPS mixup and wrong hostnames.
|
||||||
|
If the reverse proxy is on a different server (or it cannot access Part-DB via localhost) you have to set the `TRUSTED_PROXIES` env variable to match your reverse proxies IP-address (or IP block). You can do this in your `.env.local` or (when using docker) in your `docker-compose.yml` file.
|
||||||
|
|
||||||
## Useful console commands
|
## Useful console commands
|
||||||
Part-DB provides some command consoles which can be invoked by `php bin/console [command]`. You can get help for every command with the parameter `--help`.
|
Part-DB provides some command consoles which can be invoked by `php bin/console [command]`. You can get help for every command with the parameter `--help`.
|
||||||
Useful commands are:
|
Useful commands are:
|
||||||
|
|
|
@ -300,7 +300,7 @@ $(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
var clipboard = new ClipboardJS('.btn');
|
var clipboard = new ClipboardJS('.btn[data-clipboard-target], .btn[data-clipboard-text], .btn[data-clipboard-action]');
|
||||||
clipboard.on('success', function(e) {
|
clipboard.on('success', function(e) {
|
||||||
setTooltip(e.trigger, 'Copied!');
|
setTooltip(e.trigger, 'Copied!');
|
||||||
hideTooltip(e.trigger);
|
hideTooltip(e.trigger);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.3",
|
"php": "^7.3 || ^8.0",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
"doctrine/doctrine-bundle": "^2.0",
|
"doctrine/doctrine-bundle": "^2.0",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.0",
|
"doctrine/doctrine-migrations-bundle": "^3.0",
|
||||||
"doctrine/orm": "^2.9",
|
"doctrine/orm": "^2.9",
|
||||||
"dompdf/dompdf": "^1.0.1",
|
"dompdf/dompdf": "^2.0.0",
|
||||||
"erusev/parsedown": "^1.7",
|
"erusev/parsedown": "^1.7",
|
||||||
"florianv/swap": "^4.0",
|
"florianv/swap": "^4.0",
|
||||||
"florianv/swap-bundle": "dev-master",
|
"florianv/swap-bundle": "dev-master",
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
"webmozart/assert": "^1.4"
|
"webmozart/assert": "^1.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"dama/doctrine-test-bundle": "^6.0",
|
"dama/doctrine-test-bundle": "^7.0",
|
||||||
"doctrine/doctrine-fixtures-bundle": "^3.2",
|
"doctrine/doctrine-fixtures-bundle": "^3.2",
|
||||||
"ekino/phpstan-banned-code": "^v1.0.0",
|
"ekino/phpstan-banned-code": "^v1.0.0",
|
||||||
"phpstan/extension-installer": "^1.0",
|
"phpstan/extension-installer": "^1.0",
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
"symfony/phpunit-bridge": "5.4.*",
|
"symfony/phpunit-bridge": "5.4.*",
|
||||||
"symfony/stopwatch": "^5.2",
|
"symfony/stopwatch": "^5.2",
|
||||||
"symfony/web-profiler-bundle": "^5.2",
|
"symfony/web-profiler-bundle": "^5.2",
|
||||||
"symplify/easy-coding-standard": "^10.1.1",
|
"symplify/easy-coding-standard": "^11.0",
|
||||||
"vimeo/psalm": "^4.3.2"
|
"vimeo/psalm": "^4.3.2"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
|
1903
composer.lock
generated
|
@ -2,7 +2,19 @@
|
||||||
framework:
|
framework:
|
||||||
secret: '%env(APP_SECRET)%'
|
secret: '%env(APP_SECRET)%'
|
||||||
csrf_protection: true
|
csrf_protection: true
|
||||||
http_method_override: false
|
|
||||||
|
# Must be set to true, to enable the change of HTTP methhod via _method parameter, otherwise our delete routines does not work anymore
|
||||||
|
# TODO: Rework delete routines to work without _method parameter as it is not recommended anymore (see https://github.com/symfony/symfony/issues/45278)
|
||||||
|
http_method_override: true
|
||||||
|
|
||||||
|
# Allow users to configure trusted hosts via .env variables
|
||||||
|
# see https://symfony.com/doc/current/reference/configuration/framework.html#trusted-hosts
|
||||||
|
trusted_hosts: '%env(TRUSTED_HOSTS)%'
|
||||||
|
|
||||||
|
# Allow users to configure reverse proxies via .env variables. Default values are defined in parameters.yaml.
|
||||||
|
trusted_proxies: '%env(TRUSTED_PROXIES)%'
|
||||||
|
# Trust all headers by default. X-Forwared-Host can be a security risk if your reverse proxy doesn't set it.
|
||||||
|
trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix']
|
||||||
|
|
||||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||||
# Remove or comment this section to explicitly disable session support.
|
# Remove or comment this section to explicitly disable session support.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
framework:
|
framework:
|
||||||
default_locale: '%partdb.locale%'
|
default_locale: '%partdb.locale%'
|
||||||
|
# Just enable the locales we need for performance reasons.
|
||||||
|
enabled_locale: '%partdb.locale_menu%'
|
||||||
translator:
|
translator:
|
||||||
default_path: '%kernel.project_dir%/translations'
|
default_path: '%kernel.project_dir%/translations'
|
||||||
fallbacks:
|
fallbacks:
|
||||||
|
|
|
@ -50,4 +50,5 @@ parameters:
|
||||||
env(DEMO_MODE): 0
|
env(DEMO_MODE): 0
|
||||||
env(ALLOW_ATTACHMENT_DOWNLOADS): 0
|
env(ALLOW_ATTACHMENT_DOWNLOADS): 0
|
||||||
|
|
||||||
|
env(TRUSTED_PROXIES): '127.0.0.1' #By default trust only our own server
|
||||||
|
env(TRUSTED_HOSTS): '' # Trust all host names by default
|
||||||
|
|
3
docs/docker/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
db/
|
||||||
|
public_media/
|
||||||
|
uploads/
|
|
@ -9,5 +9,11 @@ services:
|
||||||
# By default
|
# By default
|
||||||
- ./uploads:/var/www/html/uploads
|
- ./uploads:/var/www/html/uploads
|
||||||
- ./public_media:/var/www/html/public/media
|
- ./public_media:/var/www/html/public/media
|
||||||
|
- ./db:/var/www/html/var/db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
image: jbtronics/part-db1:master
|
image: jbtronics/part-db1:latest
|
||||||
|
environment:
|
||||||
|
# Put SQLite database in our mapped folder. You can configure some other kind of database here too.
|
||||||
|
- DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db
|
||||||
|
# In demo env logs will be redirected to stderr
|
||||||
|
- APP_ENV=demo
|
|
@ -19,6 +19,9 @@ The docker image uses a SQLite database and all data (database, uploads and othe
|
||||||
## Direct use of docker image
|
## Direct use of docker image
|
||||||
You can use the `jbtronics/part-db1:master` image directly. You have to expose the port 80 to a host port and configure volumes for `/var/www/html/uploads` and `/var/www/html/public/media`.
|
You can use the `jbtronics/part-db1:master` image directly. You have to expose the port 80 to a host port and configure volumes for `/var/www/html/uploads` and `/var/www/html/public/media`.
|
||||||
|
|
||||||
|
If you want to use SQLite database (which is default), you have to configure Part-DB to put the database file in a mapped volume via the `DATABASE_URL` environment variable.
|
||||||
|
For example if you set `DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db` then you will have to map the `/var/www/html/var/db/` folder to the docker container (see docker-compose.yaml for example).
|
||||||
|
|
||||||
You also have to create the database like described above in step 4.
|
You also have to create the database like described above in step 4.
|
||||||
|
|
||||||
## Running console commands
|
## Running console commands
|
||||||
|
|
178
docs/installation/installation_guide-debian.md
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
# Part-DB installation guide for Debian 11 (Bullseye)
|
||||||
|
This guide shows you how to install Part-DB directly on Debian 11 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 dont need to install this much dependencies. See **TODO** for more information of the docker installation.
|
||||||
|
|
||||||
|
**Caution: This guide shows you how to install Part-DB for use in a trusted local network. If you want to use Part-DB on the internet, you HAVE TO setup a SSL certificate for your connection!**
|
||||||
|
|
||||||
|
## Install prerequisites
|
||||||
|
For the installation of Part-DB, we need some prerequisites. They can be installed by running the following command:
|
||||||
|
```bash
|
||||||
|
sudo apt install git curl zip ca-certificates software-properties-common apt-transport-https lsb-release nano wget
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install PHP and apache2
|
||||||
|
Part-DB is written in [PHP](https://php.net) and therefore needs an PHP interpreter to run. Part-DB needs PHP 7.3 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 it's 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.
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
Now you can install PHP 8.1 and 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 versions shipped in the repositories is pretty old we install it manually:
|
||||||
|
```bash
|
||||||
|
# Download composer installer script
|
||||||
|
wget -O /tmp/composer-setup.php https://getcomposer.org/installer
|
||||||
|
# Install composer globally
|
||||||
|
php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||||
|
# Make composer executable
|
||||||
|
chmod +x /usr/local/bin/composer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install yarn and nodejs
|
||||||
|
To build the frontend (the user interface) Part-DB uses [yarn](https://yarnpkg.com/). As it dependens on nodejs and the shipped versions are pretty old, we install new versions from offical nodejs 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
|
||||||
|
```
|
||||||
|
|
||||||
|
We can install yarn with the following commands:
|
||||||
|
```bash
|
||||||
|
# Add yarn repository
|
||||||
|
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
||||||
|
# Install yarn
|
||||||
|
sudo apt update && sudo apt install yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a folder for Part-DB and download it
|
||||||
|
We now have all prerequisites installed and can start to install Part-DB. We will create a folder for Part-DB in a webfolder of apache2 and download it to this folder. The downloading is done via git, which allows you to update easily later.
|
||||||
|
```bash
|
||||||
|
# Download Part-DB into the new folder /var/www/partdb
|
||||||
|
git clone https://github.com/Part-DB/Part-DB-symfony.git /var/www/partdb
|
||||||
|
```
|
||||||
|
|
||||||
|
Change ownership of the files to the apache user:
|
||||||
|
```bash
|
||||||
|
chown -R www-data:www-data /var/www/partdb
|
||||||
|
```
|
||||||
|
|
||||||
|
For the next steps we should be in the Part-DB folder, so move into it:
|
||||||
|
```bash
|
||||||
|
cd /var/www/partdb
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create configuration for Part-DB
|
||||||
|
The basic configuration of Part-DB is done by a `.env.local` file in the main directory. Create on by from the default configuration:
|
||||||
|
```bash
|
||||||
|
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 **TODO**.
|
||||||
|
Other configuration options like the default language or default currency can be found in `config/parameters.yaml`.
|
||||||
|
|
||||||
|
Please check that the `partdb.default_currency` value in `config/parameters.yaml` matches your mainly used currency, as this can not be changed after creating price informations.
|
||||||
|
|
||||||
|
## Install dependencies for Part-DB and build frontend
|
||||||
|
Part-DB depends on several other libraries and components. Install them by running the following commands:
|
||||||
|
```bash
|
||||||
|
# Install composer dependencies (please note the sudo command, to run it under the web server user)
|
||||||
|
sudo -u www-data composer install --no-dev -o
|
||||||
|
|
||||||
|
# Install yarn dependencies
|
||||||
|
sudo yarn install
|
||||||
|
# Build frontend
|
||||||
|
sudo yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a database for Part-DB
|
||||||
|
Part-DB by default uses a file based sqlite database to store the data. Use the following command to create the database. The database will normally created at `/var/www/partdb/var/app.db`.
|
||||||
|
```bash
|
||||||
|
sudo -u www-data php bin/console doctrine:migrations:migrate
|
||||||
|
```
|
||||||
|
The command will warn you about schema changes and potential data loss. Continue with typing `yes`.
|
||||||
|
|
||||||
|
The command will output several lines of informations. Somewhere should be a a yellow background message like `The initial password for the "admin" user is: f502481134`. Write down this password as you will need it later for inital login.
|
||||||
|
|
||||||
|
## Configure apache2 to show Part-DB
|
||||||
|
Part-DB is now configured, but we have to say apache2 to serve Part-DB as web application. This is done by creating a new apache site:
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/apache2/sites-available/partdb.conf
|
||||||
|
```
|
||||||
|
and add the following content (change ServerName and ServerAlias to your needs):
|
||||||
|
```
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName partdb.lan
|
||||||
|
ServerAlias www.partdb.lan
|
||||||
|
|
||||||
|
DocumentRoot /var/www/partdb/public
|
||||||
|
<Directory /var/www/partdb/public>
|
||||||
|
AllowOverride All
|
||||||
|
Order Allow,Deny
|
||||||
|
Allow from All
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
ErrorLog /var/log/apache2/partdb_error.log
|
||||||
|
CustomLog /var/log/apache2/partdb_access.log combined
|
||||||
|
</VirtualHost>
|
||||||
|
```
|
||||||
|
Activate the new site by:
|
||||||
|
```bash
|
||||||
|
sudo ln -s /etc/apache2/sites-available/partdb.conf /etc/apache2/sites-enabled/partdb.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure apache to show pretty URL pathes for Part-DB (`/label/dialog` instead of `/index.php/label/dialog`):
|
||||||
|
```bash
|
||||||
|
sudo a2enmod rewrite
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to access Part-DB via the IP-Address of the server, instead of the domain name, you have to remove the apache2 default configuration with:
|
||||||
|
```bash
|
||||||
|
sudo rm /etc/apache2/sites-enabled/000-default.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart the apache2 webserver with:
|
||||||
|
```bash
|
||||||
|
sudo service apache2 restart
|
||||||
|
```
|
||||||
|
|
||||||
|
and Part-DB should now be available under `http://YourServerIP` (or `http://partdb.lan` if you configured DNS in your network to point on the server).
|
||||||
|
|
||||||
|
## Login to Part-DB
|
||||||
|
Navigate to the Part-DB web interface and login via the user icon in the top right corner. You can login using the username `admin` and the password you have written down earlier.
|
||||||
|
|
||||||
|
## Update Part-DB
|
||||||
|
If you want to update your existing Part-DB installation, you just have to run the following commands:
|
||||||
|
```bash
|
||||||
|
# Move into Part-DB folder
|
||||||
|
cd /var/www/partdb
|
||||||
|
# Pull latest Part-DB version from GitHub
|
||||||
|
git pull
|
||||||
|
# Apply correct permission
|
||||||
|
chown -R www-data:www-data .
|
||||||
|
# Install new composer dependencies
|
||||||
|
sudo -u www-data composer install --no-dev -o
|
||||||
|
# Install yarn dependencies and build new frontend
|
||||||
|
sudo yarn install
|
||||||
|
sudo yarn build
|
||||||
|
|
||||||
|
# Check if all your configurations in .env.local and /var/www/partdb/config/parameters.yaml are correct.
|
||||||
|
sudo nano config/parameters.yaml
|
||||||
|
|
||||||
|
# Apply new database schemas (you should do a backup of your database file /var/www/partdb/var/app.db before)
|
||||||
|
sudo -u www-data php bin/console doctrine:migrations:migrate
|
||||||
|
|
||||||
|
# Clear Part-DB cache
|
||||||
|
sudo u www-data php bin/console cache:clear
|
||||||
|
```
|
|
@ -1,39 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="tests/bootstrap.php">
|
||||||
xsi:noNamespaceSchemaLocation="bin/.phpunit/phpunit.xsd"
|
<coverage processUncoveredFiles="true">
|
||||||
backupGlobals="false"
|
<include>
|
||||||
colors="true"
|
<directory suffix=".php">src</directory>
|
||||||
bootstrap="tests/bootstrap.php"
|
</include>
|
||||||
>
|
</coverage>
|
||||||
<php>
|
<php>
|
||||||
<ini name="error_reporting" value="-1" />
|
<ini name="error_reporting" value="-1"/>
|
||||||
<server name="APP_ENV" value="test" force="true" />
|
<server name="APP_ENV" value="test" force="true"/>
|
||||||
<server name="SHELL_VERBOSITY" value="-1" />
|
<server name="SHELL_VERBOSITY" value="-1"/>
|
||||||
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
|
<server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
|
||||||
<server name="SYMFONY_PHPUNIT_VERSION" value="8.5" />
|
<server name="SYMFONY_PHPUNIT_VERSION" value="9"/>
|
||||||
<ini name="memory_limit" value="512M" />
|
<ini name="memory_limit" value="512M"/>
|
||||||
<ini name="display_errors" value="1" />
|
<ini name="display_errors" value="1"/>
|
||||||
</php>
|
</php>
|
||||||
|
<testsuites>
|
||||||
<testsuites>
|
<testsuite name="Project Test Suite">
|
||||||
<testsuite name="Project Test Suite">
|
<directory>tests</directory>
|
||||||
<directory>tests</directory>
|
</testsuite>
|
||||||
</testsuite>
|
</testsuites>
|
||||||
</testsuites>
|
<extensions>
|
||||||
|
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
|
||||||
<filter>
|
</extensions>
|
||||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
<listeners>
|
||||||
<directory suffix=".php">src</directory>
|
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
|
||||||
</whitelist>
|
</listeners>
|
||||||
</filter>
|
|
||||||
|
|
||||||
<extensions>
|
|
||||||
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
|
|
||||||
</extensions>
|
|
||||||
|
|
||||||
<listeners>
|
|
||||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
|
||||||
</listeners>
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 645 B After Width: | Height: | Size: 645 B |
Before Width: | Height: | Size: 735 B After Width: | Height: | Size: 735 B |
Before Width: | Height: | Size: 713 B After Width: | Height: | Size: 713 B |
Before Width: | Height: | Size: 768 B After Width: | Height: | Size: 768 B |
Before Width: | Height: | Size: 511 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 467 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 768 B After Width: | Height: | Size: 768 B |
|
@ -2,7 +2,7 @@
|
||||||
<browserconfig>
|
<browserconfig>
|
||||||
<msapplication>
|
<msapplication>
|
||||||
<tile>
|
<tile>
|
||||||
<square150x150logo src="/icons/mstile-150x150.png"/>
|
<square150x150logo src="/icon/mstile-150x150.png"/>
|
||||||
<TileColor>#00a300</TileColor>
|
<TileColor>#00a300</TileColor>
|
||||||
</tile>
|
</tile>
|
||||||
</msapplication>
|
</msapplication>
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 420 B After Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 718 B After Width: | Height: | Size: 718 B |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
@ -8,11 +8,11 @@
|
||||||
"theme_color": "#ffffff",
|
"theme_color": "#ffffff",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/icons/android-chrome-192x192.png",
|
"src": "/icon/android-chrome-192x192.png",
|
||||||
"sizes": "192x192"
|
"sizes": "192x192"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/icons/android-chrome-384x384.png",
|
"src": "/icon/android-chrome-384x384.png",
|
||||||
"sizes": "384x384"
|
"sizes": "384x384"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -90,7 +90,7 @@ class ShowEventLogCommand extends Command
|
||||||
$total_count = $this->repo->count([]);
|
$total_count = $this->repo->count([]);
|
||||||
$max_page = (int) ceil($total_count / $limit);
|
$max_page = (int) ceil($total_count / $limit);
|
||||||
|
|
||||||
if ($page > $max_page) {
|
if ($page > $max_page && $max_page > 0) {
|
||||||
$io->error("There is no page ${page}! The maximum page is ${max_page}.");
|
$io->error("There is no page ${page}! The maximum page is ${max_page}.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace App\Entity\Attachments;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Validator\Constraints\Selectable;
|
use App\Validator\Constraints\Selectable;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
@ -105,6 +106,7 @@ abstract class Attachment extends AbstractNamedDBElement
|
||||||
* @ORM\ManyToOne(targetEntity="AttachmentType", inversedBy="attachments_with_type")
|
* @ORM\ManyToOne(targetEntity="AttachmentType", inversedBy="attachments_with_type")
|
||||||
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
|
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
|
||||||
* @Selectable()
|
* @Selectable()
|
||||||
|
* @Assert\NotNull(message="validator.attachment.must_not_be_null")
|
||||||
*/
|
*/
|
||||||
protected $attachment_type;
|
protected $attachment_type;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ abstract class AbstractDBElement implements \JsonSerializable
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
return ['@id' => $this->getID()];
|
return ['@id' => $this->getID()];
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N
|
||||||
* @var Supplier
|
* @var Supplier
|
||||||
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Supplier", inversedBy="orderdetails")
|
* @ORM\ManyToOne(targetEntity="App\Entity\Parts\Supplier", inversedBy="orderdetails")
|
||||||
* @ORM\JoinColumn(name="id_supplier", referencedColumnName="id")
|
* @ORM\JoinColumn(name="id_supplier", referencedColumnName="id")
|
||||||
|
* @Assert\NotNull(message="validator.orderdetail.supplier_must_not_be_null")
|
||||||
*/
|
*/
|
||||||
protected $supplier;
|
protected $supplier;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ final class StructuralDBElementIterator extends ArrayIterator implements Recursi
|
||||||
return !empty($element->getSubelements());
|
return !empty($element->getSubelements());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChildren()
|
public function getChildren(): StructuralDBElementIterator
|
||||||
{
|
{
|
||||||
/** @var AbstractStructuralDBElement $element */
|
/** @var AbstractStructuralDBElement $element */
|
||||||
$element = $this->current();
|
$element = $this->current();
|
||||||
|
|
|
@ -233,7 +233,7 @@ final class TreeViewNode implements JsonSerializable
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
$ret = [
|
$ret = [
|
||||||
'text' => $this->text,
|
'text' => $this->text,
|
||||||
|
|
|
@ -63,7 +63,7 @@ final class TreeViewNodeIterator extends ArrayIterator implements RecursiveItera
|
||||||
return !empty($element->getNodes());
|
return !empty($element->getNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChildren()
|
public function getChildren(): TreeViewNodeIterator
|
||||||
{
|
{
|
||||||
/** @var TreeViewNode $element */
|
/** @var TreeViewNode $element */
|
||||||
$element = $this->current();
|
$element = $this->current();
|
||||||
|
|
|
@ -8,6 +8,9 @@ use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
||||||
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
|
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
|
||||||
use Doctrine\DBAL\Exception;
|
use Doctrine\DBAL\Exception;
|
||||||
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
|
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
|
||||||
|
use Doctrine\DBAL\Platforms\MariaDBPlatform;
|
||||||
|
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||||
|
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
@ -124,11 +127,11 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration
|
||||||
*/
|
*/
|
||||||
public function getDatabaseType(): ?string
|
public function getDatabaseType(): ?string
|
||||||
{
|
{
|
||||||
if ($this->connection->getDriver() instanceof AbstractMySQLDriver) {
|
if ($this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
|
||||||
return 'mysql';
|
return 'mysql';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->connection->getDriver() instanceof AbstractSQLiteDriver) {
|
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
|
||||||
return 'sqlite';
|
return 'sqlite';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace App\Services\Attachments;
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Liip\ImagineBundle\Service\FilterService;
|
use Liip\ImagineBundle\Service\FilterService;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use function strlen;
|
use function strlen;
|
||||||
use Symfony\Component\Asset\Packages;
|
use Symfony\Component\Asset\Packages;
|
||||||
|
@ -59,15 +60,18 @@ class AttachmentURLGenerator
|
||||||
protected $attachmentHelper;
|
protected $attachmentHelper;
|
||||||
protected $filterService;
|
protected $filterService;
|
||||||
|
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
public function __construct(Packages $assets, AttachmentPathResolver $pathResolver,
|
public function __construct(Packages $assets, AttachmentPathResolver $pathResolver,
|
||||||
UrlGeneratorInterface $urlGenerator, AttachmentManager $attachmentHelper,
|
UrlGeneratorInterface $urlGenerator, AttachmentManager $attachmentHelper,
|
||||||
FilterService $filterService)
|
FilterService $filterService, LoggerInterface $logger)
|
||||||
{
|
{
|
||||||
$this->assets = $assets;
|
$this->assets = $assets;
|
||||||
$this->pathResolver = $pathResolver;
|
$this->pathResolver = $pathResolver;
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->attachmentHelper = $attachmentHelper;
|
$this->attachmentHelper = $attachmentHelper;
|
||||||
$this->filterService = $filterService;
|
$this->filterService = $filterService;
|
||||||
|
$this->logger = $logger;
|
||||||
|
|
||||||
//Determine a normalized path to the public folder (assets are relative to this folder)
|
//Determine a normalized path to the public folder (assets are relative to this folder)
|
||||||
$this->public_path = $this->pathResolver->parameterToAbsolutePath('public');
|
$this->public_path = $this->pathResolver->parameterToAbsolutePath('public');
|
||||||
|
@ -168,8 +172,14 @@ class AttachmentURLGenerator
|
||||||
return $this->assets->getUrl($asset_path);
|
return $this->assets->getUrl($asset_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise we can serve the relative path via Asset component
|
try {
|
||||||
return $this->filterService->getUrlOfFilteredImage($asset_path, $filter_name);
|
//Otherwise we can serve the relative path via Asset component
|
||||||
|
return $this->filterService->getUrlOfFilteredImage($asset_path, $filter_name);
|
||||||
|
} catch (\Imagine\Exception\RuntimeException $e) {
|
||||||
|
//If the filter fails, we can not serve the thumbnail and fall back to the original image and log an warning
|
||||||
|
$this->logger->warning('Could not open thumbnail for attachment with ID ' . $attachment->getID() . ': ' . $e->getMessage());
|
||||||
|
return $this->assets->getUrl($asset_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
16
symfony.lock
|
@ -512,15 +512,15 @@
|
||||||
"version": "v4.2.3"
|
"version": "v4.2.3"
|
||||||
},
|
},
|
||||||
"symfony/flex": {
|
"symfony/flex": {
|
||||||
"version": "1.0",
|
"version": "1.19",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"repo": "github.com/symfony/recipes",
|
"repo": "github.com/symfony/recipes",
|
||||||
"branch": "master",
|
"branch": "main",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e"
|
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"./.env"
|
".env"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"symfony/form": {
|
"symfony/form": {
|
||||||
|
@ -561,15 +561,15 @@
|
||||||
"version": "v4.2.3"
|
"version": "v4.2.3"
|
||||||
},
|
},
|
||||||
"symfony/mailer": {
|
"symfony/mailer": {
|
||||||
"version": "4.3",
|
"version": "5.4",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"repo": "github.com/symfony/recipes",
|
"repo": "github.com/symfony/recipes",
|
||||||
"branch": "master",
|
"branch": "main",
|
||||||
"version": "4.3",
|
"version": "4.3",
|
||||||
"ref": "bbfc7e27257d3a3f12a6fb0a42540a42d9623a37"
|
"ref": "97a61eabb351d7f6cb7702039bcfe07fe9d7e03c"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"./config/packages/mailer.yaml"
|
"config/packages/mailer.yaml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"symfony/maker-bundle": {
|
"symfony/maker-bundle": {
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
{# <img src="..." class="rounded mr-2" alt="...">#}
|
{# <img src="..." class="rounded mr-2" alt="...">#}
|
||||||
<i class="fas fa-fw {{ flash_symbol }} mr-2"></i>
|
<i class="fas fa-fw {{ flash_symbol }} mr-2"></i>
|
||||||
<strong class="mr-auto">{{ flash_title|trans }}</strong>
|
<strong class="mr-auto">{{ flash_title|trans }}</strong>
|
||||||
<small class="text-muted">{{ "now" | format_datetime("short", "short") }}</small>
|
<small class="{% if "text-white" in flash_bg %}text-white{% else %}text-muted{% endif %}">{{ "now" | format_datetime("short", "short") }}</small>
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="toast-body {{ flash_bg }}">
|
<div class="toast-body {{ flash_bg }}">
|
||||||
{{ message | trans}}
|
{{ message | trans }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="application-name" content="Part-DB">
|
<meta name="application-name" content="Part-DB">
|
||||||
<meta name="apple-mobile-web-app-title" content="Part-DB">
|
<meta name="apple-mobile-web-app-title" content="Part-DB">
|
||||||
<meta name="msapplication-config" content="{{ asset('icons/browserconfig.xml') }}">
|
<meta name="msapplication-config" content="{{ asset('icon/browserconfig.xml') }}">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
<meta name="msapplication-navbutton-color" content="#ffffff">
|
<meta name="msapplication-navbutton-color" content="#ffffff">
|
||||||
|
@ -18,11 +18,11 @@
|
||||||
<meta name="msapplication-starturl" content="/en/">
|
<meta name="msapplication-starturl" content="/en/">
|
||||||
|
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="{{ asset('icons/favicon.ico') }}">
|
<link rel="shortcut icon" type="image/x-icon" href="{{ asset('icon/favicon.ico') }}">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('icons/apple-touch-icon.png') }}">
|
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('icon/apple-touch-icon.png') }}">
|
||||||
<link rel="icon" type="image/png" href="{{ asset('icons/favicon-32x32.png') }}" sizes="32x32">
|
<link rel="icon" type="image/png" href="{{ asset('icon/favicon-32x32.png') }}" sizes="32x32">
|
||||||
<link rel="icon" type="image/png" href="{{ asset('icons/favicon-16x16.png') }}" sizes="16x16">
|
<link rel="icon" type="image/png" href="{{ asset('icon/favicon-16x16.png') }}" sizes="16x16">
|
||||||
<link rel="mask-icon" href="{{ asset('icons/safari-pinned-tab.svg') }}" color="#5bbad5">
|
<link rel="mask-icon" href="{{ asset('icon/safari-pinned-tab.svg') }}" color="#5bbad5">
|
||||||
|
|
||||||
|
|
||||||
<title>{% apply trim %}{% block title %}{{ partdb_title}}{% endblock %}{% endapply %}</title>
|
<title>{% apply trim %}{% block title %}{{ partdb_title}}{% endblock %}{% endapply %}</title>
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
<li>Run <kbd>yarn install</kbd> and <kbd>yarn build</kbd> in Part-DB folder.</li>
|
<li>Run <kbd>yarn install</kbd> and <kbd>yarn build</kbd> in Part-DB folder.</li>
|
||||||
<li>Run <kbd>php bin/console cache:clear</kbd></li>
|
<li>Run <kbd>php bin/console cache:clear</kbd></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% elseif exception.class == "Doctrine\\DBAL\\Exception\\InvalidFieldNameException" %}
|
{% elseif exception.class == "Doctrine\\DBAL\\Exception\\InvalidFieldNameException" or exception.class == "Doctrine\\DBAL\\Exception\\TableNotFoundException" %}
|
||||||
<i>Invalid database schema.</i> Try following things:
|
<i>Invalid or not existing database schema.</i> Try following things:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Check if the <code>DATABASE_URL</code> in <code>.env.local</code> is correct</li>
|
||||||
<li>Run <kbd>php bin/console doctrine:migrations:migrate</kbd> to upgrade database schema</li>
|
<li>Run <kbd>php bin/console doctrine:migrations:migrate</kbd> to upgrade database schema</li>
|
||||||
<li>Run <kbd>php bin/console cache:clear</kbd></li>
|
<li>Run <kbd>php bin/console cache:clear</kbd></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<h4><i class="fa fa-book fa-fw" aria-hidden="true"></i> {% trans %}homepage.license{% endtrans %}</h4>
|
<h4><i class="fa fa-book fa-fw" aria-hidden="true"></i> {% trans %}homepage.license{% endtrans %}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Part-DB, Copyright © 2019 - 2020 of <strong>
|
<p>Part-DB, Copyright © 2019 - 2022 of <strong>
|
||||||
<a class="link-external" rel="noopener" target="_blank" href="https://github.com/jbtronics/">Jan Böhmer</a>
|
<a class="link-external" rel="noopener" target="_blank" href="https://github.com/jbtronics/">Jan Böhmer</a>
|
||||||
</strong>. <br> Part-DB is published under the <strong>GNU Affero General Public License v3.0 (or later)</strong>, so it comes with <strong>ABSOLUTELY NO WARRANTY</strong>.
|
</strong>. <br> Part-DB is published under the <strong>GNU Affero General Public License v3.0 (or later)</strong>, so it comes with <strong>ABSOLUTELY NO WARRANTY</strong>.
|
||||||
This is free software, and you are welcome to redistribute it under certain conditions.
|
This is free software, and you are welcome to redistribute it under certain conditions.
|
||||||
|
|
|
@ -88,10 +88,12 @@ class UserTest extends TestCase
|
||||||
public function testSetBackupCodes(): void
|
public function testSetBackupCodes(): void
|
||||||
{
|
{
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
$this->assertNull($user->getBackupCodesGenerationDate());
|
||||||
|
|
||||||
$codes = ['test', 'invalid', 'test'];
|
$codes = ['test', 'invalid', 'test'];
|
||||||
$user->setBackupCodes($codes);
|
$user->setBackupCodes($codes);
|
||||||
// Backup Codes generation date must be changed!
|
// Backup Codes generation date must be changed!
|
||||||
$this->assertEqualsWithDelta(new DateTime(), $user->getBackupCodesGenerationDate(), 0.1);
|
$this->assertInstanceOf(\DateTime::class, $user->getBackupCodesGenerationDate());
|
||||||
$this->assertSame($codes, $user->getBackupCodes());
|
$this->assertSame($codes, $user->getBackupCodes());
|
||||||
|
|
||||||
//Test what happens if we delete the backup keys
|
//Test what happens if we delete the backup keys
|
||||||
|
|
|
@ -77,7 +77,7 @@ class BackupCodeGeneratorTest extends TestCase
|
||||||
public function testGenerateSingleCode(int $code_length): void
|
public function testGenerateSingleCode(int $code_length): void
|
||||||
{
|
{
|
||||||
$generator = new BackupCodeGenerator($code_length, 10);
|
$generator = new BackupCodeGenerator($code_length, 10);
|
||||||
$this->assertRegExp("/^([a-f0-9]){{$code_length}}\$/", $generator->generateSingleCode());
|
$this->assertMatchesRegularExpression("/^([a-f0-9]){{$code_length}}\$/", $generator->generateSingleCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function codeCountDataProvider(): array
|
public function codeCountDataProvider(): array
|
||||||
|
|
|
@ -215,5 +215,17 @@
|
||||||
<target>This location can only contain a single part and it is already full!</target>
|
<target>This location can only contain a single part and it is already full!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="4gPskOG" name="validator.attachment.must_not_be_null">
|
||||||
|
<segment>
|
||||||
|
<source>validator.attachment.must_not_be_null</source>
|
||||||
|
<target>You must select an attachment type!</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="cDDVrWT" name="validator.orderdetail.supplier_must_not_be_null">
|
||||||
|
<segment>
|
||||||
|
<source>validator.orderdetail.supplier_must_not_be_null</source>
|
||||||
|
<target>You must select an supplier!</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|