Compare commits

..

No commits in common. "78b1d41cf86c7409d3a48a74d7ec8a3ec6708b5f" and "30ece644232d828f88254fb19529908bdab7551d" have entirely different histories.

13 changed files with 746 additions and 759 deletions

View file

@ -8,9 +8,6 @@ on:
branches: branches:
- '*' - '*'
- "!l10n_*" # Dont test localization branches - "!l10n_*" # Dont test localization branches
tags:
- 'v*.*.*'
- 'v*.*.*-**'
pull_request: pull_request:
branches: branches:
- '*' - '*'
@ -20,8 +17,6 @@ jobs:
assets_artifact_build: assets_artifact_build:
name: Build assets artifact name: Build assets artifact
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
permissions:
contents: write
env: env:
APP_ENV: prod APP_ENV: prod
@ -95,10 +90,3 @@ jobs:
with: with:
name: Full Part-DB including dependencies and built assets name: Full Part-DB including dependencies and built assets
path: /tmp/partdb_with_assets.zip path: /tmp/partdb_with_assets.zip
- name: Upload assets as release attachment
if: startsWith(github.ref, 'refs/tags/')
run: |
gh release upload "${{ github.ref_name }}" /tmp/partdb_assets.zip /tmp/partdb_with_assets.zip --clobber
env:
GH_TOKEN: ${{ github.token }}

View file

@ -1 +1 @@
2.8.1 2.8.0

44
composer.lock generated
View file

@ -4130,16 +4130,16 @@
}, },
{ {
"name": "dompdf/dompdf", "name": "dompdf/dompdf",
"version": "v3.1.5", "version": "v3.1.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/dompdf/dompdf.git", "url": "https://github.com/dompdf/dompdf.git",
"reference": "f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496" "reference": "db712c90c5b9868df3600e64e68da62e78a34623"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496", "url": "https://api.github.com/repos/dompdf/dompdf/zipball/db712c90c5b9868df3600e64e68da62e78a34623",
"reference": "f11ead23a8a76d0ff9bbc6c7c8fd7e05ca328496", "reference": "db712c90c5b9868df3600e64e68da62e78a34623",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4188,9 +4188,9 @@
"homepage": "https://github.com/dompdf/dompdf", "homepage": "https://github.com/dompdf/dompdf",
"support": { "support": {
"issues": "https://github.com/dompdf/dompdf/issues", "issues": "https://github.com/dompdf/dompdf/issues",
"source": "https://github.com/dompdf/dompdf/tree/v3.1.5" "source": "https://github.com/dompdf/dompdf/tree/v3.1.4"
}, },
"time": "2026-03-03T13:54:37+00:00" "time": "2025-10-29T12:43:30+00:00"
}, },
{ {
"name": "dompdf/php-font-lib", "name": "dompdf/php-font-lib",
@ -9502,16 +9502,16 @@
}, },
{ {
"name": "sabberworm/php-css-parser", "name": "sabberworm/php-css-parser",
"version": "v9.3.0", "version": "v9.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
"reference": "88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949" "reference": "59373045e11ad47b5c18fc615feee0219e42f6d3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949", "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/59373045e11ad47b5c18fc615feee0219e42f6d3",
"reference": "88dbd0f7f91abbfe4402d0a3071e9ff4d81ed949", "reference": "59373045e11ad47b5c18fc615feee0219e42f6d3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9538,7 +9538,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "9.4.x-dev" "dev-main": "9.3.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -9576,9 +9576,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v9.3.0" "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v9.2.0"
}, },
"time": "2026-03-03T17:31:43+00:00" "time": "2026-02-21T17:12:03+00:00"
}, },
{ {
"name": "sabre/uri", "name": "sabre/uri",
@ -19148,12 +19148,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git", "url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "da19d9c4572f2adae57b28b2111d7fa667cd6dcb" "reference": "89525190c449738e468ee27e77f9fdc1bc160e08"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/da19d9c4572f2adae57b28b2111d7fa667cd6dcb", "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/89525190c449738e468ee27e77f9fdc1bc160e08",
"reference": "da19d9c4572f2adae57b28b2111d7fa667cd6dcb", "reference": "89525190c449738e468ee27e77f9fdc1bc160e08",
"shasum": "" "shasum": ""
}, },
"conflict": { "conflict": {
@ -19282,7 +19282,7 @@
"commerceteam/commerce": ">=0.9.6,<0.9.9", "commerceteam/commerce": ">=0.9.6,<0.9.9",
"components/jquery": ">=1.0.3,<3.5", "components/jquery": ">=1.0.3,<3.5",
"composer/composer": "<1.10.27|>=2,<2.2.26|>=2.3,<2.9.3", "composer/composer": "<1.10.27|>=2,<2.2.26|>=2.3,<2.9.3",
"concrete5/concrete5": "<9.4.8", "concrete5/concrete5": "<9.4.3",
"concrete5/core": "<8.5.8|>=9,<9.1", "concrete5/core": "<8.5.8|>=9,<9.1",
"contao-components/mediaelement": ">=2.14.2,<2.21.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1",
"contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
@ -19296,7 +19296,7 @@
"cosenary/instagram": "<=2.3", "cosenary/instagram": "<=2.3",
"couleurcitron/tarteaucitron-wp": "<0.3", "couleurcitron/tarteaucitron-wp": "<0.3",
"cpsit/typo3-mailqueue": "<0.4.3|>=0.5,<0.5.1", "cpsit/typo3-mailqueue": "<0.4.3|>=0.5,<0.5.1",
"craftcms/cms": "<4.17.0.0-beta2|>=5,<5.9.0.0-beta2", "craftcms/cms": "<4.17.0.0-beta1|>=5,<5.9.0.0-beta1",
"craftcms/commerce": ">=4.0.0.0-RC1-dev,<=4.10|>=5,<=5.5.1", "craftcms/commerce": ">=4.0.0.0-RC1-dev,<=4.10|>=5,<=5.5.1",
"craftcms/composer": ">=4.0.0.0-RC1-dev,<=4.10|>=5.0.0.0-RC1-dev,<=5.5.1", "craftcms/composer": ">=4.0.0.0-RC1-dev,<=4.10|>=5.0.0.0-RC1-dev,<=5.5.1",
"craftcms/craft": ">=3.5,<=4.16.17|>=5.0.0.0-RC1-dev,<=5.8.21", "craftcms/craft": ">=3.5,<=4.16.17|>=5.0.0.0-RC1-dev,<=5.8.21",
@ -19454,7 +19454,7 @@
"friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
"froala/wysiwyg-editor": "<=4.3", "froala/wysiwyg-editor": "<=4.3",
"frosh/adminer-platform": "<2.2.1", "frosh/adminer-platform": "<2.2.1",
"froxlor/froxlor": "<=2.3.3", "froxlor/froxlor": "<=2.2.5",
"frozennode/administrator": "<=5.0.12", "frozennode/administrator": "<=5.0.12",
"fuel/core": "<1.8.1", "fuel/core": "<1.8.1",
"funadmin/funadmin": "<=7.1.0.0-RC4", "funadmin/funadmin": "<=7.1.0.0-RC4",
@ -19504,7 +19504,7 @@
"ibexa/solr": ">=4.5,<4.5.4", "ibexa/solr": ">=4.5,<4.5.4",
"ibexa/user": ">=4,<4.4.3|>=5,<5.0.4", "ibexa/user": ">=4,<4.4.3|>=5,<5.0.4",
"icecoder/icecoder": "<=8.1", "icecoder/icecoder": "<=8.1",
"idno/known": "<1.6.4", "idno/known": "<=1.6.2",
"ilicmiljan/secure-props": ">=1.2,<1.2.2", "ilicmiljan/secure-props": ">=1.2,<1.2.2",
"illuminate/auth": "<5.5.10", "illuminate/auth": "<5.5.10",
"illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4", "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4",
@ -19554,7 +19554,7 @@
"kelvinmo/simplexrd": "<3.1.1", "kelvinmo/simplexrd": "<3.1.1",
"kevinpapst/kimai2": "<1.16.7", "kevinpapst/kimai2": "<1.16.7",
"khodakhah/nodcms": "<=3", "khodakhah/nodcms": "<=3",
"kimai/kimai": "<=2.50", "kimai/kimai": "<2.46",
"kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4",
"klaviyo/magento2-extension": ">=1,<3", "klaviyo/magento2-extension": ">=1,<3",
"knplabs/knp-snappy": "<=1.4.2", "knplabs/knp-snappy": "<=1.4.2",
@ -20167,7 +20167,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-03-04T22:09:37+00:00" "time": "2026-03-01T01:36:02+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",

View file

@ -25,5 +25,5 @@ framework:
adapter: cache.app adapter: cache.app
cache.settings: cache.settings:
adapter: cache.system adapter: cache.app
tags: true tags: true

View file

@ -195,8 +195,6 @@ abstract class BaseAdminController extends AbstractController
$this->commentHelper->setMessage($form['log_comment']->getData()); $this->commentHelper->setMessage($form['log_comment']->getData());
//In principle, the form should be disabled, if the edit permission is not granted, but for good measure, we also check it here, before saving changes.
$this->denyAccessUnlessGranted('edit', $entity);
$em->persist($entity); $em->persist($entity);
$em->flush(); $em->flush();
$this->addFlash('success', 'entity.edit_flash'); $this->addFlash('success', 'entity.edit_flash');

View file

@ -71,10 +71,7 @@ class TypeaheadController extends AbstractController
#[Route(path: '/builtInResources/search', name: 'typeahead_builtInRessources')] #[Route(path: '/builtInResources/search', name: 'typeahead_builtInRessources')]
public function builtInResources(Request $request, BuiltinAttachmentsFinder $finder): JsonResponse public function builtInResources(Request $request, BuiltinAttachmentsFinder $finder): JsonResponse
{ {
//Ensure that the user can access Part-DB at all $query = $request->get('query');
$this->denyAccessUnlessGranted('HAS_ACCESS_PERMISSIONS');
$query = $request->query->getString('query');
$array = $finder->find($query); $array = $finder->find($query);
$result = []; $result = [];
@ -208,16 +205,9 @@ class TypeaheadController extends AbstractController
/** @var Category|null $category */ /** @var Category|null $category */
$category = $entityManager->getRepository(Category::class)->find($categoryId); $category = $entityManager->getRepository(Category::class)->find($categoryId);
//Ensure the user has access to both the part and the category
$this->denyAccessUnlessGranted('read', $part);
if ($category !== null) {
$this->denyAccessUnlessGranted('read', $category);
}
$clonedPart = clone $part; $clonedPart = clone $part;
$clonedPart->setCategory($category); $clonedPart->setCategory($category);
$partRepository = $entityManager->getRepository(Part::class); $partRepository = $entityManager->getRepository(Part::class);
$ipnSuggestions = $partRepository->autoCompleteIpn($clonedPart, $description, $this->ipnSuggestSettings->suggestPartDigits); $ipnSuggestions = $partRepository->autoCompleteIpn($clonedPart, $description, $this->ipnSuggestSettings->suggestPartDigits);

View file

@ -121,7 +121,6 @@ class BaseEntityAdminForm extends AbstractType
'label' => 'entity.edit.alternative_names.label', 'label' => 'entity.edit.alternative_names.label',
'help' => 'entity.edit.alternative_names.help', 'help' => 'entity.edit.alternative_names.help',
'empty_data' => null, 'empty_data' => null,
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
'attr' => [ 'attr' => [
'class' => 'tagsinput', 'class' => 'tagsinput',
'data-controller' => 'elements--tagsinput', 'data-controller' => 'elements--tagsinput',

View file

@ -304,11 +304,11 @@ final readonly class BarcodeScanResultHandler
return null; return null;
} }
// Digi-Key: supplierPartNumber directly // Digi-Key: can use customerPartNumber or supplierPartNumber directly
if ($vendor === 'digikey') { if ($vendor === 'digikey') {
return [ return [
'providerKey' => 'digikey', 'providerKey' => 'digikey',
'providerId' => $scanResult->supplierPartNumber ?? throw new \RuntimeException('Digikey barcode does not contain required supplier part number'), 'providerId' => $scanResult->customerPartNumber ?? $scanResult->supplierPartNumber,
]; ];
} }
@ -316,7 +316,7 @@ final readonly class BarcodeScanResultHandler
if ($vendor === 'element14') { if ($vendor === 'element14') {
return [ return [
'providerKey' => 'element14', 'providerKey' => 'element14',
'providerId' => $scanResult->supplierPartNumber ?? throw new \RuntimeException('Element14 barcode does not contain required supplier part number'), 'providerId' => $scanResult->supplierPartNumber,
]; ];
} }

View file

@ -420,7 +420,7 @@ class UpdateExecutor
// Step 11: Clear cache // Step 11: Clear cache
$stepStart = microtime(true); $stepStart = microtime(true);
$this->runCommand([ $this->runCommand([
'php', 'bin/console', 'cache:pool:clear', '--all', 'php', 'bin/console', 'cache:clear',
'--env=prod', '--env=prod',
'--no-interaction', '--no-interaction',
], 'Clear cache', 120); ], 'Clear cache', 120);
@ -489,7 +489,7 @@ class UpdateExecutor
// Clear cache after rollback // Clear cache after rollback
$this->runCommand([ $this->runCommand([
'php', 'bin/console', 'cache:pool:clear', '--all', 'php', 'bin/console', 'cache:clear',
'--env=prod', '--env=prod',
], 'Clear cache after rollback', 120); ], 'Clear cache after rollback', 120);
$log('rollback_cache', 'Cleared cache after rollback', true); $log('rollback_cache', 'Cleared cache after rollback', true);

View file

@ -1,7 +1,8 @@
{% block flashes %} {% block flashes %}
{# Insert flashes #} {# Insert flashes #}
<turbo-stream action="update" action="morph" target="toast-container"> <turbo-stream action="replace" action="morph" target="toast-container">
<template> <template>
<div class="toast-container" id="toast-container">
{% for label, messages in app.flashes() %} {% for label, messages in app.flashes() %}
{% for message in messages %} {% for message in messages %}
{{ include('_toast.html.twig', { {{ include('_toast.html.twig', {
@ -10,10 +11,13 @@
}) }} }) }}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
</div>
</template> </template>
</turbo-stream> </turbo-stream>
{% endblock %} {% endblock %}
{# Insert info about when the sidebar trees were updated last time, so the sidebar_tree_controller can decide if it needs to reload the tree #} {# Insert info about when the sidebar trees were updated last time, so the sidebar_tree_controller can decide if it needs to reload the tree #}
<span id="sidebar-last-time-updated" style="display: none;" data-last-update="{{ sidebar_tree_updater.lastTreeUpdate.format("Y-m-d\\TH:i:sP") }}"></span> <span id="sidebar-last-time-updated" style="display: none;" data-last-update="{{ sidebar_tree_updater.lastTreeUpdate.format("Y-m-d\\TH:i:sP") }}"></span>

View file

@ -195,6 +195,9 @@
{% endif %} {% endif %}
</div> </div>
</fieldset> </fieldset>
{# Include turbo control things, so we can still control page title and reloading #}
{% include "_turbo_control.html.twig" %}
</turbo-frame> </turbo-frame>
</div> </div>
</div> </div>

View file

@ -17,7 +17,7 @@
<b><i>Can not load frontend assets.</i></b><p>Try following things:</p> <b><i>Can not load frontend assets.</i></b><p>Try following things:</p>
<ul> <ul>
<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> and <kbd>php bin/console cache:pool:clear --all</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" or exception.class == "Doctrine\\DBAL\\Exception\\TableNotFoundException"
@ -26,21 +26,21 @@
<ul> <ul>
<li>Check if the <code>DATABASE_URL</code> in <code>.env.local</code> (or docker configure) is correct</li> <li>Check if the <code>DATABASE_URL</code> in <code>.env.local</code> (or docker configure) 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> and <kbd>php bin/console cache:pool:clear --all</kbd></li> <li>Run <kbd>php bin/console cache:clear</kbd></li>
</ul> </ul>
{% elseif exception.class == "Doctrine\\DBAL\\Exception\\DriverException" %} {% elseif exception.class == "Doctrine\\DBAL\\Exception\\DriverException" %}
<b><i>Error while executing database query.</i></b><br>This is maybe caused by an old database schema.<br><p>Try following things:</p> <b><i>Error while executing database query.</i></b><br>This is maybe caused by an old database schema.<br><p>Try following things:</p>
<ul> <ul>
<li>Check if the <code>DATABASE_URL</code> in <code>.env.local</code> (or docker configure) is correct</li> <li>Check if the <code>DATABASE_URL</code> in <code>.env.local</code> (or docker configure) is correct</li>
<li>Run <kbd>php bin/console doctrine:migrations:migrate</kbd> to upgrade database schema (if upgrade is available)</li> <li>Run <kbd>php bin/console doctrine:migrations:migrate</kbd> to upgrade database schema (if upgrade is available)</li>
<li>Run <kbd>php bin/console cache:clear</kbd> and <kbd>php bin/console cache:pool:clear --all</kbd></li> <li>Run <kbd>php bin/console cache:clear</kbd></li>
<li>If this issue persist, create a ticket at <a href="https://github.com/Part-DB/Part-DB-symfony/issues" rel="noopener">GitHub</a>.</li> <li>If this issue persist, create a ticket at <a href="https://github.com/Part-DB/Part-DB-symfony/issues" rel="noopener">GitHub</a>.</li>
</ul> </ul>
{% else %} {% else %}
You could try following things, if this error is unexpected: You could try following things, if this error is unexpected:
<ul> <ul>
<li>Check <code>var/log/prod.log</code> (or <code>docker logs</code> when Part-DB is running inside a docker container) for additional informations</li> <li>Check <code>var/log/prod.log</code> (or <code>docker logs</code> when Part-DB is running inside a docker container) for additional informations</li>
<li>Run <kbd>php bin/console cache:clear</kbd> and <kbd>php bin/console cache:pool:clear --all</kbd> to clear caches</li> <li>Run <kbd>php bin/console cache:clear</kbd> to clear cache</li>
</ul> </ul>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

1385
yarn.lock

File diff suppressed because it is too large Load diff