fixes
Some checks failed
Gitea Actions / Run-Tests-On-Arm64 (push) Failing after 16m4s
Gitea Actions / Run-Tests-On-Amd64 (push) Failing after 30m18s

This commit is contained in:
Thomas Peterson 2025-05-18 15:58:50 +02:00
parent 43264fce3b
commit 2913dca789
73 changed files with 2800 additions and 1460 deletions

View File

@ -56,7 +56,7 @@ services:
networks: networks:
- network - network
smtp4dev: smtp4dev:
image: registry.thomas-peterson.de/smtp4dev image: registry.thomas-peterson.de/smtp4dev:manifest-amd64
restart: always restart: always
ports: ports:
# Change the number before : to the port the web interface should be accessible on # Change the number before : to the port the web interface should be accessible on

View File

@ -133,7 +133,7 @@ RUN --mount=type=cache,target=/tmp/.composer \
# on production, we don't want test dependencies # on production, we don't want test dependencies
COMPOSER_HOME=/tmp/.composer composer install --no-scripts --no-plugins --no-progress -o --no-dev; \ COMPOSER_HOME=/tmp/.composer composer install --no-scripts --no-plugins --no-progress -o --no-dev; \
else \ else \
COMPOSER_HOME=/tmp/.composer composer install --no-scripts --no-plugins --no-progress -o; \ COMPOSER_HOME=/tmp/.composer composer update --ignore-platform-reqs --no-scripts --no-plugins --no-progress -o; \
fi fi
# copy the full codebase # copy the full codebase
@ -170,6 +170,6 @@ COPY --from=codebase --chown=$APP_USER_NAME:$APP_GROUP_NAME /codebase $APP_CODE_
RUN echo "root ALL=(ALL) NOPASSWD: ALL " | tee -a "/etc/sudoers.d/users" && \ RUN echo "root ALL=(ALL) NOPASSWD: ALL " | tee -a "/etc/sudoers.d/users" && \
echo "${APP_USER_NAME} ALL=(ALL) NOPASSWD: ALL " | tee -a "/etc/sudoers.d/users" echo "${APP_USER_NAME} ALL=(ALL) NOPASSWD: ALL " | tee -a "/etc/sudoers.d/users"
RUN pecl install xdebug RUN pecl install https://xdebug.org/files/xdebug-3.4.2.tgz
ENV APP_ENV=dev ENV APP_ENV=dev

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
# start-cron.sh # start-cron.sh
touch /var/log/cron.log touch /var/log/cron.log
touch /var/log/cronD.log
touch /var/log/cronH.log
rm -R /data/www/new/var/cache/* rm -R /data/www/new/var/cache/*
rm -R /data/www/new/var/log/* rm -R /data/www/new/var/log/*
chmod -R 0777 /data/www/new/var/cache chmod -R 0777 /data/www/new/var/cache
chmod -R 0777 /data/www/new/var/log chmod -R 0777 /data/www/new/var/log
chmod 0777 /var/log/cron.log chmod 0777 /var/log/cron.log
chmod 0777 /var/log/cronD.log
chmod 0777 /var/log/cronH.log

View File

@ -5,5 +5,7 @@ BASH_ENV=/container.env
* * * * * root chmod -R 0777 /data/www/old/market/steplayouter >> /var/log/cron.log 2>&1 * * * * * root chmod -R 0777 /data/www/old/market/steplayouter >> /var/log/cron.log 2>&1
* * * * * root chmod -R 0777 /data/www/new/web/uploads/media >> /var/log/cron.log 2>&1 * * * * * root chmod -R 0777 /data/www/new/web/uploads/media >> /var/log/cron.log 2>&1
* * * * * root chmod -R 0777 /data/www/new/web/media >> /var/log/cron.log 2>&1 * * * * * root chmod -R 0777 /data/www/new/web/media >> /var/log/cron.log 2>&1
* * * * * www-data cd /data/www/new/web && /usr/local/bin/php /data/www/new/bin/console application:queue:do >> /var/log/cron.log 2>&1 * * * * * www-data cd /data/www/new/web && /usr/local/bin/php /data/www/new/bin/console application:queue:doEveryMinute >> /var/log/cron.log 2>&1
@daily www-data cd /data/www/new/web && /usr/local/bin/php /data/www/new/bin/console application:queue:doEveryDay >> /var/log/cronD.log 2>&1
@hourly www-data cd /data/www/new/web && /usr/local/bin/php /data/www/new/bin/console application:queue:doEveryHour >> /var/log/cronH.log 2>&1
# #

View File

@ -4,7 +4,7 @@ error_log = /proc/self/fd/2
access.log = /proc/self/fd/1 access.log = /proc/self/fd/1
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
catch_workers_output = yes catch_workers_output = yes
rlimit_core = unlimited
user = __APP_USER_NAME user = __APP_USER_NAME
group = __APP_GROUP_NAME group = __APP_GROUP_NAME
listen = 0.0.0.0:9000 listen = 0.0.0.0:9000

View File

@ -26,16 +26,6 @@
} }
} }
}, },
"@symfony/ux-turbo": {
"turbo-core": {
"enabled": true,
"fetch": "eager"
},
"mercure-turbo-stream": {
"enabled": false,
"fetch": "eager"
}
},
"@symfony/ux-vue": { "@symfony/ux-vue": {
"vue": { "vue": {
"enabled": true, "enabled": true,

View File

@ -1,65 +1,50 @@
import { Controller } from '@hotwired/stimulus'; import { Controller } from '@hotwired/stimulus';
export default class extends Controller { export default class extends Controller {
static targets = ['dialog', 'dynamicContent']; static targets = ['dialog'];
observer = null; open(e) {
this.element.getElementsByClassName('iframe')[0].innerHtml = "";
connect() { var htmlId = e.target.dataset.html_id;
if (this.hasDynamicContentTarget) { var iframe = document.createElement('iframe');
// when the content changes, call this.open() iframe.classList.add("w-full");
this.observer = new MutationObserver(() => { iframe.classList.add("h-full");
const shouldOpen = this.dynamicContentTarget.innerHTML.trim().length > 0; iframe.src = e.target.dataset.href;
this.element.getElementsByClassName('iframe')[0].appendChild(iframe);
if (shouldOpen && !this.dialogTarget.open) {
this.open();
} else if (!shouldOpen && this.dialogTarget.open) {
this.close();
}
});
this.observer.observe(this.dynamicContentTarget, {
childList: true,
characterData: true,
subtree: true
});
}
}
disconnect() {
if (this.observer) {
this.observer.disconnect();
}
if (this.dialogTarget.open) {
this.close();
}
}
open() {
this.dialogTarget.showModal(); this.dialogTarget.showModal();
document.body.classList.add('overflow-hidden', 'blur-sm');
var $this = this;
window.addEventListener(htmlId, function(e) {
document.getElementById(htmlId).value = e.detail.id;
document.getElementById(htmlId + "-widget").classList.add('media-chooser--choosen');
document.getElementById(htmlId + "__preview__title").innerHtml = e.detail.title;
if (e.detail.thumbPath === "") {
} else {
document.getElementById(htmlId + "__preview__img").src = e.detail.thumbPath;
}
iframe.remove();
$this.close();
document.getElementById(htmlId).dispatchEvent(new Event('change', { bubbles: true }));
}, {once: true});
} }
trash(e) {
var htmlId = e.target.dataset.html_id;
document.getElementById(htmlId).value = "";
document.getElementById(htmlId + "__preview__title").innerHtml = "";
document.getElementById(htmlId + "__preview__title").innerText = "";
document.getElementById(htmlId + "__preview__img").removeAttribute('src');
document.getElementById(htmlId + "__preview__img").removeAttribute('alt');
document.getElementById(htmlId + "__preview__img").removeAttribute('srcset');
document.getElementById(htmlId).dispatchEvent(new Event('change', { bubbles: true }));
}
close() { close() {
this.dialogTarget.close(); this.dialogTarget.close();
document.body.classList.remove('overflow-hidden', 'blur-sm'); document.body.classList.remove('overflow-hidden', 'blur-sm');
} }
useMedia(e) {
let dataset = e.target.dataset;
document.getElementById(e.target.dataset.htmlId).value = e.target.dataset.id;
// Update preview
document.getElementById(e.target.dataset.htmlId + "-widget").classList.add('media-chooser--choosen');
document.getElementById(e.target.dataset.htmlId + "__preview__title").innerHtml = this.title;
if (e.target.dataset.thumbPath === "") {
} else {
document.getElementById(e.target.dataset.htmlId + "__preview__img").src = e.target.dataset.thumbPath;
}
// Close modal
this.close();
}
clickOutside(event) { clickOutside(event) {
if (event.target === this.dialogTarget) { if (event.target === this.dialogTarget) {
this.dialogTarget.close(); this.dialogTarget.close();

View File

@ -71,7 +71,9 @@
@apply inline-flex items-center justify-center py-1 gap-1 font-medium rounded-sm px-4 text-sm text-white shadow-lg bg-psc-500 hover:bg-psc-600 hover:ring-2 hover:ring-psc-500 hover:ring-offset-2 min-h-[2.25rem]; @apply inline-flex items-center justify-center py-1 gap-1 font-medium rounded-sm px-4 text-sm text-white shadow-lg bg-psc-500 hover:bg-psc-600 hover:ring-2 hover:ring-psc-500 hover:ring-offset-2 min-h-[2.25rem];
} }
.psc-button-secondary {
@apply inline-flex items-center justify-center py-1 gap-1 font-medium rounded-sm px-4 text-xs text-white shadow-lg bg-psc-500 hover:bg-psc-600 hover:ring-2 hover:ring-psc-500 hover:ring-offset-2 min-h-[1.8rem];
}
.form-label { .form-label {
@apply block uppercase text-xs font-bold mb-2; @apply block uppercase text-xs font-bold mb-2;

View File

@ -13,9 +13,10 @@
} }
}, },
"require": { "require": {
"php": "8.1.*", "php": "8.2.*",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-mongodb": "^2",
"azuyalabs/yasumi": "^2.5", "azuyalabs/yasumi": "^2.5",
"behat/transliterator": "^1.2@dev", "behat/transliterator": "^1.2@dev",
"bitandblack/colors": "^2.13", "bitandblack/colors": "^2.13",
@ -24,12 +25,11 @@
"cocur/slugify": "v3.1", "cocur/slugify": "v3.1",
"composer/package-versions-deprecated": "^1.8", "composer/package-versions-deprecated": "^1.8",
"ddeboer/imap": "1.18.*", "ddeboer/imap": "1.18.*",
"doctrine/annotations": "^1.0", "doctrine/annotations": "^2",
"doctrine/cache": "^1.11", "doctrine/cache": "^2",
"doctrine/doctrine-bundle": "2.7.*", "doctrine/doctrine-bundle": "^2",
"doctrine/mongodb-odm-bundle": "^4", "doctrine/mongodb-odm-bundle": "^5",
"doctrine/orm": "^2.7", "doctrine/orm": "^2.7",
"dunglas/doctrine-json-odm": "^1.4",
"gabrielbull/ups-api": "dev-master", "gabrielbull/ups-api": "dev-master",
"gregwar/captcha-bundle": "^2.2", "gregwar/captcha-bundle": "^2.2",
"guzzlehttp/guzzle": "^6", "guzzlehttp/guzzle": "^6",
@ -40,7 +40,7 @@
"knplabs/knp-menu-bundle": "^3", "knplabs/knp-menu-bundle": "^3",
"knplabs/knp-paginator-bundle": "5.9.*", "knplabs/knp-paginator-bundle": "5.9.*",
"lexik/form-filter-bundle": "^7", "lexik/form-filter-bundle": "^7",
"lexik/jwt-authentication-bundle": "2.16.*", "lexik/jwt-authentication-bundle": "^3",
"liip/imagine-bundle": "2.9.*", "liip/imagine-bundle": "2.9.*",
"mobiledetect/mobiledetectlib": "^2.8", "mobiledetect/mobiledetectlib": "^2.8",
"mpdf/mpdf": "dev-qrcode", "mpdf/mpdf": "dev-qrcode",
@ -93,7 +93,6 @@
"symfony/ux-autocomplete": "^2.14", "symfony/ux-autocomplete": "^2.14",
"symfony/ux-chartjs": "^2.19", "symfony/ux-chartjs": "^2.19",
"symfony/ux-live-component": "^2.12", "symfony/ux-live-component": "^2.12",
"symfony/ux-turbo": "^2.24",
"symfony/ux-twig-component": "^2.12", "symfony/ux-twig-component": "^2.12",
"symfony/ux-vue": "^2.23", "symfony/ux-vue": "^2.23",
"symfony/validator": "*", "symfony/validator": "*",
@ -137,7 +136,7 @@
"sort-packages": true, "sort-packages": true,
"optimize-autoloader": true, "optimize-autoloader": true,
"platform": { "platform": {
"php": "8.1.12" "php": "8.2.28"
}, },
"allow-plugins": { "allow-plugins": {
"symfony/flex": true, "symfony/flex": true,

1270
src/new/composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,5 @@ return [
Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true], Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true],
Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true], Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true],
Symfonycasts\SassBundle\SymfonycastsSassBundle::class => ['all' => true], Symfonycasts\SassBundle\SymfonycastsSassBundle::class => ['all' => true],
Dunglas\DoctrineJsonOdm\Bundle\DunglasDoctrineJsonOdmBundle::class => ['all' => true],
Symfony\UX\Vue\VueBundle::class => ['all' => true], Symfony\UX\Vue\VueBundle::class => ['all' => true],
Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
]; ];

View File

@ -5,5 +5,28 @@ declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void { return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('monolog', ['handlers' => ['main' => ['type' => 'stream', 'path' => '%kernel.logs_dir%/%kernel.environment%.log', 'level' => 'debug', 'channels' => ['!event']], 'console' => ['type' => 'console', 'process_psr_3_messages' => false, 'channels' => ['!event', '!doctrine', '!console']]]]); $containerConfigurator->extension(
'monolog', [
'handlers' => [
'main' => [
'type' => 'stream',
'path' => '%kernel.logs_dir%/%kernel.environment%.log',
'level' => 'debug',
'channels' => [
'!event',
'!php'
]
],
'console' => [
'type' => 'console',
'process_psr_3_messages' => false,
'channels' => [
'!event',
'!doctrine',
'!console'
]
]
]
]
);
}; };

View File

@ -5,5 +5,10 @@ declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void { return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('lexik_jwt_authentication', ['secret_key' => '%env(resolve:JWT_SECRET_KEY)%', 'public_key' => '%env(resolve:JWT_PUBLIC_KEY)%', 'pass_phrase' => '%env(JWT_PASSPHRASE)%']); $containerConfigurator->extension('lexik_jwt_authentication', [
'secret_key' => '%env(resolve:JWT_SECRET_KEY)%',
'public_key' => '%env(resolve:JWT_PUBLIC_KEY)%',
'user_id_claim' => 'uid',
'pass_phrase' => '%env(JWT_PASSPHRASE)%'
]);
}; };

View File

@ -15,11 +15,13 @@ use PSC\Shop\UserBundle\Security\ApiKey\ShopProvider;
use PSC\Shop\UserBundle\Security\User\UserProvider; use PSC\Shop\UserBundle\Security\User\UserProvider;
use PSC\Shop\UserBundle\Security\ZendAuthenticator; use PSC\Shop\UserBundle\Security\ZendAuthenticator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
return static function (ContainerConfigurator $containerConfigurator): void { return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension( $containerConfigurator->extension(
'security', 'security',
[ [
'session_fixation_strategy' => SessionAuthenticationStrategy::NONE,
'password_hashers' => 'password_hashers' =>
[ [
Contact::class => Contact::class =>
@ -84,10 +86,14 @@ return static function (ContainerConfigurator $containerConfigurator): void {
['user_provider', 'shop_provider', 'instance_provider'] ['user_provider', 'shop_provider', 'instance_provider']
] ]
] ]
// 'database_token' => ['entity' => ['class' => Shop::class]], // 'database_token' => ['entity' => ['class' => Shop::class]],
// 'database_api_key' => ['entity' => ['class' => Instance::class]], // 'database_api_key' => ['entity' => ['class' => Instance::class]],
], ],
'firewalls' => [ 'firewalls' => [
'dev' => [
'security' => false,
'pattern' => '^/(_(profiler|wdt)|css|images|js)/',
],
'admin_secured_area' => [ 'admin_secured_area' => [
'pattern' => '^/backend', 'pattern' => '^/backend',
'provider' => 'user_provider', 'provider' => 'user_provider',
@ -100,6 +106,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
'password_parameter' => 'password' 'password_parameter' => 'password'
], ],
'logout' => [ 'logout' => [
'invalidate_session' => false,
'path' => 'psc_backend_logout', 'path' => 'psc_backend_logout',
'target' => 'psc_backend_login' 'target' => 'psc_backend_login'
] ]
@ -125,7 +132,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
], ],
'custom_authenticators' => [ 'custom_authenticators' => [
ApiKeyAuthenticator::class, ApiKeyAuthenticator::class,
ZendAuthenticator::class, ZendAuthenticator::class,
] ]
], ],
'storefront' => [ 'storefront' => [

View File

@ -2,6 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
use PSC\Shop\MediaBundle\Service\MediaManager;
use PSC\Shop\OrderBundle\Service\Order; use PSC\Shop\OrderBundle\Service\Order;
use PSC\System\SettingsBundle\Service\Instance; use PSC\System\SettingsBundle\Service\Instance;
use PSC\System\SettingsBundle\Service\Shop; use PSC\System\SettingsBundle\Service\Shop;
@ -19,7 +20,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
'instanceService' => service(Instance::class), 'instanceService' => service(Instance::class),
'shopService' => service(Shop::class), 'shopService' => service(Shop::class),
'orderService' => service(Order::class), 'orderService' => service(Order::class),
'tokenService' => service(Token::class) 'tokenService' => service(Token::class),
'mediaService' => service(MediaManager::class)
] ]
] ]
); );

View File

@ -20,7 +20,7 @@ class Shop
$tmp->id = $shopEntity->getUID(); $tmp->id = $shopEntity->getUID();
$tmp->name = $shopEntity->getTitle(); $tmp->name = $shopEntity->getTitle();
$tmp->uuid = $shopEntity->getUuid(); $tmp->uuid = $shopEntity->getUuid();
$tmp->deleted = (bool)$shopEntity->isDeleted(); $tmp->disabled = (bool)$shopEntity->isDeleted();
$tmp->private = (bool)$shopEntity->isPrivate(); $tmp->private = (bool)$shopEntity->isPrivate();
$tmp->basketField1 = (string)$shopEntity->getBasketfield1(); $tmp->basketField1 = (string)$shopEntity->getBasketfield1();
$tmp->basketField2 = (string)$shopEntity->getBasketfield2(); $tmp->basketField2 = (string)$shopEntity->getBasketfield2();
@ -33,7 +33,9 @@ class Shop
$domains = $this->entityManager $domains = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Domain')->getAllByShopId($shopEntity); ->getRepository('PSC\Shop\EntityBundle\Entity\Domain')->getAllByShopId($shopEntity);
$domainsTemp = []; $domainsTemp = [];
/** @var \PSC\Shop\EntityBundle\Entity\Domain $domain */ /**
* @var \PSC\Shop\EntityBundle\Entity\Domain $domain
*/
foreach ($domains as $domain) { foreach ($domains as $domain) {
$domainsTemp[] = new Domain($domain->getUid(), $domain->getHost(), $domain->isLetsEncrypt()); $domainsTemp[] = new Domain($domain->getUid(), $domain->getHost(), $domain->isLetsEncrypt());
} }

View File

@ -22,11 +22,11 @@ class Shop
* @OA\Property(type="integer") * @OA\Property(type="integer")
*/ */
public int $id = 0; public int $id = 0;
/** /**
* @OA\Property(type="string", maxLength=255) * @OA\Property(type="string", maxLength=255)
*/ */
public string $uuid = ""; public string $uuid = "";
/** /**
* @OA\Property(type="string", maxLength=255) * @OA\Property(type="string", maxLength=255)
*/ */
public string $name = ""; public string $name = "";
@ -58,15 +58,15 @@ class Shop
* @OA\Property(type="string", maxLength=255) * @OA\Property(type="string", maxLength=255)
*/ */
public string $basketPosField2 = ""; public string $basketPosField2 = "";
/** /**
* @OA\Property(type="array", @OA\Items(ref=@Model(type=\PSC\Component\ApiBundle\Model\Shop\Domain::class))) * @OA\Property(type="array", @OA\Items(ref=@Model(type=\PSC\Component\ApiBundle\Model\Shop\Domain::class)))
*/ */
public array $domains = []; public array $domains = [];
/** /**
* @OA\Property(type="boolean") * @OA\Property(type="boolean")
*/ */
public bool $deleted = false; public bool $disabled = false;
/** /**
* @OA\Property(type="boolean") * @OA\Property(type="boolean")
*/ */
public bool $private = false; public bool $private = false;

View File

@ -34,9 +34,13 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class AccountType extends AbstractType class AccountType extends AbstractType
{ {
/** @var Field */ /**
* @var Field
*/
protected $fields; protected $fields;
/** @var General */ /**
* @var General
*/
protected $general; protected $general;
protected $shop = null; protected $shop = null;
protected $formFactory; protected $formFactory;
@ -57,7 +61,8 @@ class AccountType extends AbstractType
$builder $builder
->add('title', TextType::class, ['label' => 'Name']) ->add('title', TextType::class, ['label' => 'Name'])
->add('payments', EntityType::class, array( ->add(
'payments', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Payment', 'class' => 'PSC\Shop\EntityBundle\Entity\Payment',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
@ -68,8 +73,10 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('shippings', EntityType::class, array( )
->add(
'shippings', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Shipping', 'class' => 'PSC\Shop\EntityBundle\Entity\Shipping',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
@ -80,8 +87,10 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('productGroups', EntityType::class, array( )
->add(
'productGroups', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Productgroup', 'class' => 'PSC\Shop\EntityBundle\Entity\Productgroup',
'choice_label' => function (Productgroup $choice, $key, $value) { 'choice_label' => function (Productgroup $choice, $key, $value) {
@ -99,8 +108,10 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('parent', EntityType::class, array( )
->add(
'parent', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Account', 'class' => 'PSC\Shop\EntityBundle\Entity\Account',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
@ -112,8 +123,10 @@ class AccountType extends AbstractType
->join('u.shops', 's') ->join('u.shops', 's')
->where('s.uid = :shop')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('s.uid = :shop')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('productsOrg', EntityType::class, array( )
->add(
'productsOrg', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'nrTitle', 'choice_label' => 'nrTitle',
'multiple' => true, 'multiple' => true,
@ -123,8 +136,10 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->andWhere('u.private = 1 AND u.originalProduct = 0')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->andWhere('u.private = 1 AND u.originalProduct = 0')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('productsSub', EntityType::class, array( )
->add(
'productsSub', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'nrTitle', 'choice_label' => 'nrTitle',
'required' => false, 'required' => false,
@ -134,8 +149,10 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->andWhere('u.private = 1 AND u.originalProduct != 0')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->andWhere('u.private = 1 AND u.originalProduct != 0')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
->add('cms', EntityType::class, array( )
->add(
'cms', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Cms', 'class' => 'PSC\Shop\EntityBundle\Entity\Cms',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
@ -146,7 +163,8 @@ class AccountType extends AbstractType
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('(u.shop = :shop OR u.uid in (' . implode(",", $tempCms) . '))')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('(u.shop = :shop OR u.uid in (' . implode(",", $tempCms) . '))')->andWhere('u.private = 1')->setParameter('shop', $this->shop->getSelectedShop()->getId());
} }
)) )
)
->add('appendix', TextType::class, ['required' => false, 'label' => 'additive']) ->add('appendix', TextType::class, ['required' => false, 'label' => 'additive'])
->add('locked', CheckboxType::class, ['required' => false, 'label' => 'Locked']) ->add('locked', CheckboxType::class, ['required' => false, 'label' => 'Locked'])
->add('street', TextType::class, ['required' => false, 'label' => 'street']) ->add('street', TextType::class, ['required' => false, 'label' => 'street'])
@ -165,12 +183,14 @@ class AccountType extends AbstractType
->add('phone', TextType::class, ['required' => false, 'label' => 'number']) ->add('phone', TextType::class, ['required' => false, 'label' => 'number'])
->add('phoneAppendix', TextType::class, ['required' => false, 'label' => 'extension']) ->add('phoneAppendix', TextType::class, ['required' => false, 'label' => 'extension'])
->add('priceFactor', NumberType::class, array('required' => false, 'label' => 'factor', 'scale' => 2, 'html5' => true, ->add(
'priceFactor', NumberType::class, array('required' => false, 'label' => 'factor', 'scale' => 2, 'html5' => true,
'attr' => array( 'attr' => array(
'min' => -0.01, 'min' => -0.01,
'max' => 2.00, 'max' => 2.00,
'step' => 0.01, 'step' => 0.01,
))) ))
)
->add('mobileAreaCode', TextType::class, ['required' => false, 'label' => 'Countrycode']) ->add('mobileAreaCode', TextType::class, ['required' => false, 'label' => 'Countrycode'])
->add('mobilePrefix', TextType::class, ['required' => false, 'label' => 'prefix']) ->add('mobilePrefix', TextType::class, ['required' => false, 'label' => 'prefix'])
@ -220,7 +240,9 @@ class AccountType extends AbstractType
->add('lastname2', TextType::class, ['required' => false, 'label' => 'lastname2']) ->add('lastname2', TextType::class, ['required' => false, 'label' => 'lastname2'])
->add('calcValue1', TextType::class, ['required' => false, 'label' => 'value1']) ->add('calcValue1', TextType::class, ['required' => false, 'label' => 'value1'])
->add('calcValue2', TextType::class, ['required' => false, 'label' => 'value2']); ->add('calcValue2', TextType::class, ['required' => false, 'label' => 'value2']);
/** @var \PSC\System\PluginBundle\Form\Interfaces\Field $field */ /**
* @var \PSC\System\PluginBundle\Form\Interfaces\Field $field
*/
foreach ($this->fields->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Account) as $field) { foreach ($this->fields->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Account) as $field) {
$builder->add($field->buildForm($this->formFactory->createNamedBuilder($field->getGroup()), $options)); $builder->add($field->buildForm($this->formFactory->createNamedBuilder($field->getGroup()), $options));
} }
@ -235,10 +257,12 @@ class AccountType extends AbstractType
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(
array(
'data_class' => 'PSC\Shop\EntityBundle\Entity\Account', 'data_class' => 'PSC\Shop\EntityBundle\Entity\Account',
'cms' => [], 'cms' => [],
'translation_domain' => 'core_account_create_and_edit' 'translation_domain' => 'core_account_create_and_edit'
)); )
);
} }
} }

View File

@ -186,7 +186,7 @@ class ContactType extends AbstractType
)) ))
->add('productsSub', EntityType::class, array( ->add('productsSub', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'title', 'choice_label' => 'nrTitle',
'choice_value' => 'uid', 'choice_value' => 'uid',
'required' => false, 'required' => false,
'multiple' => true, 'multiple' => true,

View File

@ -30,6 +30,21 @@ class ContactRepository extends ServiceEntityRepository implements UserLoaderInt
{ {
parent::__construct($registry, Contact::class); parent::__construct($registry, Contact::class);
} }
public function loadUserByUid($uuid)
{
$user = $this->createQueryBuilder('c')
->where('c.uid = :uid AND c.enable = 1')
->setParameter('uid', $uuid)
->getQuery()
->getOneOrNullResult();
if (null === $user) {
$message = sprintf('Unable to find an Contact identified by "%s".', $uuid);
throw new UserNotFoundException($message);
}
return $user;
}
public function loadUserByUsername($username) public function loadUserByUsername($username)
{ {
@ -38,6 +53,10 @@ class ContactRepository extends ServiceEntityRepository implements UserLoaderInt
->setParameter('username', $username) ->setParameter('username', $username)
->getQuery() ->getQuery()
->getOneOrNullResult(); ->getOneOrNullResult();
if(null === $user) {
$user = $this->loadUserByUid($username);
}
if (null === $user) { if (null === $user) {
$message = sprintf('Unable to find an Contact identified by "%s".', $username); $message = sprintf('Unable to find an Contact identified by "%s".', $username);
throw new UserNotFoundException($message); throw new UserNotFoundException($message);

View File

@ -985,6 +985,12 @@ class Product
return $this->title; return $this->title;
} }
public function getTitleSubTitle(): ?string
{
return $this->title . ' ' . $this->subTitle;
}
public function setTitle(?string $title): void public function setTitle(?string $title): void
{ {
$this->title = $title; $this->title = $title;
@ -2871,7 +2877,7 @@ class Product
public function getNrTitle() public function getNrTitle()
{ {
return $this->nrIntern . ' ' . $this->title; return $this->nrIntern . ' ' . $this->title . ' ' . $this->subTitle;
} }
/** /**

View File

@ -4,6 +4,7 @@ namespace PSC\Shop\EntityBundle\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Attribute\Groups;
#[ORM\Table(name: 'shop')] #[ORM\Table(name: 'shop')]
#[ORM\Entity(repositoryClass: 'PSC\Shop\EntityBundle\Repository\ShopRepository')] #[ORM\Entity(repositoryClass: 'PSC\Shop\EntityBundle\Repository\ShopRepository')]

View File

@ -8,6 +8,8 @@ use Doctrine\ORM\EntityManagerInterface;
use PSC\Shop\MediaBundle\Helper\MediaManager; use PSC\Shop\MediaBundle\Helper\MediaManager;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormView;
@ -18,71 +20,19 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/ */
class TWMediaType extends AbstractType class TWMediaType extends AbstractType
{ {
/**
* @var MediaManager
*/
protected $mediaManager; protected $mediaManager;
/**
* @var \Doctrine\ODM\MongoDB\DocumentManager
*/
protected $mongoManager; protected $mongoManager;
/**
* @param MediaManager $mediaManager The media manager
* @param EntityManagerInterface $objectManager The media manager
* @param DocumentManager $mongoManager The media manager
*/
public function __construct(MediaManager $mediaManager, DocumentManager $mongoManager) public function __construct(MediaManager $mediaManager, DocumentManager $mongoManager)
{ {
$this->mediaManager = $mediaManager; $this->mediaManager = $mediaManager;
$this->mongoManager = $mongoManager; $this->mongoManager = $mongoManager;
} }
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting form the
* top most type. Type extensions can further modify the form.
*
* @param FormBuilderInterface $builder The form builder
* @param array $options The options
*
* @see FormTypeExtensionInterface::buildForm()
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addViewTransformer(
new IdToMediaTransformer($this->mongoManager, $options['current_value_container']),
true
);
$builder->setAttribute('chooser', $options['chooser']);
$builder->setAttribute('mediatype', $options['mediatype']);
}
/**
* @return string
*/
public function getParent() public function getParent()
{ {
return FormType::class; return TextType::class;
}
/**
* Sets the default options for this type.
*
* @param OptionsResolver $resolver The resolver for the options.
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'compound' => false,
'chooser' => 'psc_shop_media_backend_folder_tw',
'mediatype' => null,
'current_value_container' => new CurrentValueContainer(),
)
);
} }
/** /**
@ -95,9 +45,6 @@ class TWMediaType extends AbstractType
return 'tw_media'; return 'tw_media';
} }
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options) public function buildView(FormView $view, FormInterface $form, array $options)
{ {
$view->vars['chooser'] = $form->getConfig()->getAttribute('chooser'); $view->vars['chooser'] = $form->getConfig()->getAttribute('chooser');

View File

@ -6,7 +6,7 @@ class MediaItem
{ {
public ?string $name; public ?string $name;
public ?string $description; public ?string $description = null;
public ?string $media; public ?string $media;

View File

@ -1,6 +1,6 @@
{% extends 'modalFrame.html.twig' %} {% extends 'backend_layout.html.twig' %}
{% block body %} {% block appContent %}
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
{{ form_start(folderForm, { 'attr': {'class': ''}}) }} {{ form_start(folderForm, { 'attr': {'class': ''}}) }}
@ -134,14 +134,13 @@
<td class="text-end"> <td class="text-end">
{% if modal %} {% if modal %}
{% if isImage %} {% if isImage %}
<a href="javascript:void(0)" alt="{{ media.originalFilename }}" class="js-url-chooser-media-select btn btn-primary btn-sm" data-thumb-path="{{ imageurl }}" data-path="{{ path }}" data-title="{{ media.title|escape('js') }}" data-id="{{ media.id }}">Einfügen</a> <button href="javascript:void(0)" alt="{{ media.originalFilename }}" class="js-url-chooser-media-select btn btn-primary btn-sm" type="button" data-action="modal#useMedia" data-thumb-path="{{ imageurl }}" data-path="{{ path }}" data-title="{{ media.title|escape('js') }}" data-id="{{ media.id }}" data-html-id="{{ htmlId }}">Einfügen</button>
{% else %} {% else %}
<a href="javascript:void(0)" alt="{{ media.originalFilename }}" class="js-url-chooser-media-select btn btn-primary btn-sm" data-path="{{ path }}" data-title="{{ media.title|escape('js') }}" data-id="{{ media.id }}">Einfügen</a> <a href="javascript:void(0)" alt="{{ media.originalFilename }}" class="js-url-chooser-media-select btn btn-primary btn-sm" data-path="{{ path }}" data-title="{{ media.title|escape('js') }}" data-id="{{ media.id }}">Einfügen</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
<a href="{{ path('psc_shop_media_backend_upload_swap', {folder: selectedFolder.id, media: media.id, modal: modal, htmlId: htmlId}) }}" class="btn btn-sm btn-warning">Tauschen</a> <a href="{{ path('psc_shop_media_backend_upload_swap', {folder: selectedFolder.id, media: media.id, modal: modal, htmlId: htmlId}) }}" class="btn btn-sm btn-warning">Tauschen</a>
<a href="{{ path('psc_shop_media_backend_media_detail', {folder: selectedFolder.id, uuid: media.id, modal: modal, htmlId: htmlId}) }}" class="btn btn-sm btn-info">Bearbeiten</a> <a href="{{ path('psc_shop_media_backend_media_detail', {folder: selectedFolder.id, uuid: media.id, modal: modal, htmlId: htmlId}) }}" class="btn btn-sm btn-info">Bearbeiten</a>
<button type="button" data-action="modal#useMedia" data-thumb-path="{{ imageurl }}" data-path="{{ path }}" data-title="{{ media.title|escape('js') }}" data-id="{{ media.id }}" data-html-id="{{ htmlId }}">Close</button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -155,3 +154,16 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %}
<script type="module">
import $ from 'jquery'
$(document).ready(function() {
$("button[data-action='modal#useMedia']").click(function() {
const event = new CustomEvent("{{ htmlId }}", {detail: {thumbPath: $(this).attr('data-thumb-path'), path: $(this).attr('data-path'), title: $(this).attr('data-title'), id: $(this).attr('data-id')}});
window.parent.dispatchEvent(event);
});
});
</script>
{% endblock %}

View File

@ -2,13 +2,12 @@
{% apply spaceless %} {% apply spaceless %}
<div id="{{ id }}-widget" class="media-chooser {% if(value.ent is defined) %}media-chooser--choosen{% endif %}"> <div id="{{ id }}-widget" class="media-chooser {% if(value.ent is defined) %}media-chooser--choosen{% endif %}">
<!-- Hidden input --> <!-- Hidden input -->
<input id="{{ id }}" type="hidden" name="{{ full_name }}" value="{% if(value.id is defined) %}{{ value.id }}{% endif %}"> <input id="{{ id }}" type="hidden" name="{{ full_name }}" value="{{value}}">
<!-- Preview --> <!-- Preview -->
<div class="media-chooser__preview"> <div class="media-chooser__preview">
<figure class="thumbnail"> <figure class="thumbnail">
{% if(value.ent is defined) %} {% if(value is defined and value != "") %}
{% set media = value.ent %} {% set media = mediaService.getMedia(value) %}
{% set handler = mediamanager.getHandler(media) %} {% set handler = mediamanager.getHandler(media) %}
{% set imageurl = handler.getImageUrl(media, app.request.basePath) %} {% set imageurl = handler.getImageUrl(media, app.request.basePath) %}
{% if imageurl is not empty and media.location == 'local' %} {% if imageurl is not empty and media.location == 'local' %}
@ -37,18 +36,33 @@
</figure> </figure>
</div> </div>
<a <div data-controller="modal">
data-turbo-frame="modal" <button
data-action="modal#mediaSelect" data-action="modal#open"
href="{{ path(chooser, {'uuid': 0, 'modal': 1, 'htmlId' : id}) }}" data-html_id="{{id}}"
class="flex items-center space-x-1 bg-psc-500 hover:bg-blue-700 text-white text-sm font-bold px-4 rounded" data-href="{{ path('psc_shop_media_backend_folder_tw', {'uuid': 0, 'modal': 1, 'htmlId' : id}) }}"
>Auswählen</a> class="flex items-center space-x-1 bg-psc-500 hover:bg-blue-700 text-white text-sm font-bold px-4 rounded"
type="button"
>Auswählen</button>
<button type="button"
data-action="modal#trash"
data-html_id="{{id}}">
<i data-html_id="{{id}}" class="fa fa-trash"></i>
</button>
<button type="button" id="{{ id }}__preview__del-btn" class="js-media-chooser-del-preview-btn btn btn-danger media-chooser__preview__del-btn" data-linked-id="{{ id }}"> <dialog
<i class="fa fa-trash"></i> class="open:flex bg-gray-800 rounded-lg shadow-xl inset-0 w-full md:w-fit md:max-w-[50%] md:min-w-[50%] h-full"
</button> data-action="close->modal#close click->modal#clickOutside"
data-modal-target="dialog"
>
<div class="flex grow p-5 h-full iframe">
</div>
</dialog>
</div>
<!-- Select Button --> <!-- Select Button -->
</div>
</div>
{% endapply %} {% endapply %}
{% endblock %} {% endblock %}

View File

@ -0,0 +1,65 @@
{% block tw_media_widget %}
{% apply spaceless %}
<div id="{{ id }}-widget" class="media-chooser {% if(value.ent is defined) %}media-chooser--choosen{% endif %}">
<!-- Hidden input -->
<input id="{{ id }}" type="hidden" name="{{ full_name }}" value="{% if(value.id is defined) %}{{ value.id }}{% endif %}">
<!-- Preview -->
<div class="media-chooser__preview">
<figure class="thumbnail">
{% if(value.ent is defined) %}
{% set media = value.ent %}
{% set handler = mediamanager.getHandler(media) %}
{% set imageurl = handler.getImageUrl(media, app.request.basePath) %}
{% if imageurl is not empty and media.location == 'local' %}
{% if imageurl|lower|split('.')|last == 'svg' or 'image/svg' in media.contentType %}
{% set imageurlretina = imageurl %}
{% else %}
{% set imageurlretina = asset(imageurl | imagine_filter('media_list_thumbnail_retina')) %}
{% set imageurl = asset(imageurl | imagine_filter('media_list_thumbnail')) %}
{% endif %}
{% endif %}
{% if imageurl %}
<img src="{{ imageurl }}" srcset="{{ imageurl }} 1x, {{ imageurlretina is defined ? ', ' ~ imageurlretina ~ " 2x" }}" alt="{{ media.title }}" id="{{ id }}__preview__img" class="thumbnail-img media-chooser__preview__img">
<figcaption id="{{ id }}__preview__title" class="media-chooser__preview__title">
{{ media.title }}
</figcaption>
{% else %}
<i class="fas fa-file-o media-thumbnail__icon"></i>
<figcaption id="{{ id }}__preview__title" class="media-chooser__preview__title">
{{ media.title }}
</figcaption>
{% endif %}
{% else %}
<img id="{{ id }}__preview__img" class="thumbnail-img media-chooser__preview__img">
<figcaption id="{{ id }}__preview__title" class="media-chooser__preview__title"></figcaption>
{% endif %}
</figure>
</div>
<div data-controller="modal">
<button
data-action="modal#open"
data-html_id="{{id}}"
data-href="{{ path(chooser, {'uuid': 0, 'modal': 1, 'htmlId' : id}) }}"
class="flex items-center space-x-1 bg-psc-500 hover:bg-blue-700 text-white text-sm font-bold px-4 rounded"
type="button"
>Auswählen</button>
<dialog
class="open:flex bg-gray-800 rounded-lg shadow-xl inset-0 w-full md:w-fit md:max-w-[50%] md:min-w-[50%] h-full"
data-action="close->modal#close click->modal#clickOutside"
data-modal-target="dialog"
>
<div class="flex grow p-5 h-full iframe">
</div>
</dialog>
</div>
<button type="button" id="{{ id }}__preview__del-btn" class="js-media-chooser-del-preview-btn btn btn-danger media-chooser__preview__del-btn" data-linked-id="{{ id }}">
<i class="fa fa-trash"></i>
</button>
<!-- Select Button -->
</div>
{% endapply %}
{% endblock %}

View File

@ -57,12 +57,11 @@ class EditController extends AbstractController
/** /**
* Create * Create
* *
* * @param Request $request
* @param Request $request * @param SessionInterface $session
* @param SessionInterface $session * @param Field $field
* @param Field $field * @param EntityManagerInterface $entityManager
* @param EntityManagerInterface $entityManager * @param \PSC\System\SettingsBundle\Service\Shop $shopService
* @param \PSC\System\SettingsBundle\Service\Shop $shopService
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\ORMException
*/ */
@ -72,7 +71,9 @@ class EditController extends AbstractController
{ {
$customFields = $field->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::News); $customFields = $field->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::News);
$customGroups = $field->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::News); $customGroups = $field->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::News);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /**
* @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop
*/
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
$news = new News(); $news = new News();
$news->setShop($selectedShop); $news->setShop($selectedShop);
@ -97,13 +98,12 @@ class EditController extends AbstractController
/** /**
* edit * edit
* *
* * @param Request $request
* @param Request $request * @param Field $field
* @param Field $field * @param SessionInterface $session
* @param SessionInterface $session * @param EntityManagerInterface $entityManager
* @param EntityManagerInterface $entityManager * @param \PSC\System\SettingsBundle\Service\Shop $shopService
* @param \PSC\System\SettingsBundle\Service\Shop $shopService * @param $uid
* @param $uid
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\ORMException
*/ */
@ -113,9 +113,13 @@ class EditController extends AbstractController
{ {
$customFields = $field->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::News); $customFields = $field->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::News);
$customGroups = $field->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::News); $customGroups = $field->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::News);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /**
* @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop
*/
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
/** @var News $news */ /**
* @var News $news
*/
$news = $entityManager $news = $entityManager
->getRepository('PSC\Shop\NewsBundle\Entity\News')->findOneBy(array('uid' => $uid, 'shop' => $selectedShop)); ->getRepository('PSC\Shop\NewsBundle\Entity\News')->findOneBy(array('uid' => $uid, 'shop' => $selectedShop));
$form = $this->createForm(NewsType::class, $news); $form = $this->createForm(NewsType::class, $news);
@ -126,8 +130,11 @@ class EditController extends AbstractController
$entityManager->flush(); $entityManager->flush();
$session->getFlashBag()->add('success', 'News Entry \'' . $news->getTitle() . '\' has been updated!'); $session->getFlashBag()->add('success', 'News Entry \'' . $news->getTitle() . '\' has been updated!');
$this->logService->createLogEntry($selectedShop, $this->getUser(), LogEntry::INFO, PSCShopNewsBundle::class, $news->getTitle(), "News Entry saved"); $this->logService->createLogEntry($selectedShop, $this->getUser(), LogEntry::INFO, PSCShopNewsBundle::class, $news->getTitle(), "News Entry saved");
return $this->redirectToRoute('psc_shop_news_backend_list'); // return $this->redirectToRoute('psc_shop_news_backend_list');
} }
$customGroups = [];
$customFields = [];
return array( return array(
'news' => $news, 'news' => $news,
'form' => $form->createView(), 'form' => $form->createView(),
@ -140,11 +147,10 @@ class EditController extends AbstractController
/** /**
* remove * remove
* *
* * @param Request $request
* @param Request $request * @param SessionInterface $session
* @param SessionInterface $session * @param EntityManagerInterface $entityManager
* @param EntityManagerInterface $entityManager * @param $uid
* @param $uid
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/ */
#[Route(path: '/edit/delete/{uid}', name: 'psc_shop_news_backend_delete')] #[Route(path: '/edit/delete/{uid}', name: 'psc_shop_news_backend_delete')]
@ -152,7 +158,9 @@ class EditController extends AbstractController
public function deleteAction(Request $request, SessionInterface $session, EntityManagerInterface $entityManager, \PSC\System\SettingsBundle\Service\Shop $shopService, $uid) public function deleteAction(Request $request, SessionInterface $session, EntityManagerInterface $entityManager, \PSC\System\SettingsBundle\Service\Shop $shopService, $uid)
{ {
$news = $entityManager->getRepository('PSC\Shop\NewsBundle\Entity\News')->findOneBy(['uid' => $uid]); $news = $entityManager->getRepository('PSC\Shop\NewsBundle\Entity\News')->findOneBy(['uid' => $uid]);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /**
* @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop
*/
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
$form = $this->createForm(DeleteType::class); $form = $this->createForm(DeleteType::class);
$form->handleRequest($request); $form->handleRequest($request);

View File

@ -15,12 +15,18 @@ namespace PSC\Shop\NewsBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use PSC\Shop\MediaBundle\Model\MediaItem;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Symfony\Component\Serializer\Attribute\Ignore;
use Symfony\Component\Serializer\Attribute\MaxDepth;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
/** /**
* Cms * Cms
* *
*
* @package PSC\Shop\News * @package PSC\Shop\News
* @subpackage Entitys * @subpackage Entitys
*/ */
@ -54,8 +60,8 @@ class News
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'einleitung', type: 'string', length: 255)] #[ORM\Column(name: 'einleitung', type: 'string', length: 255, nullable: true)]
protected $introduction; protected ?string $introduction;
/** /**
* Language * Language
* *
@ -68,27 +74,28 @@ class News
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'text', type: 'string')] #[ORM\Column(name: 'text', type: 'string', nullable: true)]
protected $text; protected ?string $text;
/** /**
* Shop zu welcher die News gehört * Shop zu welcher die News gehört
* *
* @var int * @var int
*/ */
#[ORM\ManyToOne(targetEntity: 'PSC\Shop\EntityBundle\Entity\Shop')] #[ORM\ManyToOne(targetEntity: 'PSC\Shop\EntityBundle\Entity\Shop')]
#[Ignore]
#[ORM\JoinColumn(name: 'shop_id', referencedColumnName: 'id')] #[ORM\JoinColumn(name: 'shop_id', referencedColumnName: 'id')]
protected $shop; protected $shop;
#[ORM\Column(name: 'sort_date', type: 'date')] #[ORM\Column(name: 'sort_date', type: 'date', nullable: true)]
protected $sortDate; protected $sortDate;
#[ORM\Column(name: 'from_date', type: 'datetime')] #[ORM\Column(name: 'from_date', type: 'datetime', nullable: true)]
protected ?\DateTime $fromDate; protected ?\DateTime $fromDate;
#[ORM\Column(name: 'to_date', type: 'datetime')] #[ORM\Column(name: 'to_date', type: 'datetime', nullable: true)]
protected ?\DateTime $toDate; protected ?\DateTime $toDate;
#[ORM\Column(name: 'media', type: 'json_document', options: ['jsonb' => true])] #[ORM\Column(type: 'json')]
public $media = []; protected ?string $media = null;
/** /**
* enable * enable
* *
@ -99,8 +106,8 @@ class News
public function __construct() public function __construct()
{ {
$this->media = new ArrayCollection();
} }
public function getUid() public function getUid()
{ {
return $this->uid; return $this->uid;
@ -261,4 +268,29 @@ class News
{ {
$this->toDate = $toDate; $this->toDate = $toDate;
} }
public function setMedia(array $media): void
{
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer(), new ArrayDenormalizer()];
$serializer = new Serializer($normalizers, $encoders);
$this->media = $serializer->serialize($media, 'json');
}
public function getMedia(): array
{
if($this->media === null) {
return [];
}
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer(), new ArrayDenormalizer()];
$serializer = new Serializer($normalizers, $encoders);
return $serializer->deserialize($this->media, MediaItem::class. '[]', 'json');
}
} }

View File

@ -1,130 +1,30 @@
{% extends 'backend_base.html.twig' %} {% extends 'backend_tailwind_base.html.twig' %}
{% form_theme form 'tailwind_formtheme.html.twig' %}
{% trans_default_domain 'core_news_edit' %}
{% block header %}
<div>
<h1 class="text-psc text-2xl font-medium flex flex-row gap-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-8">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z" />
</svg>
{{ 'News'|trans }} {{ 'create'|trans }}</h1>
</div>
<div class="flex flex-wrap items-center gap-4 justify-start shrink-0">
<a href="{{ path('psc_shop_news_backend_list') }}" class="inline-flex items-center justify-center py-1 gap-1 font-medium rounded-sm px-4 text-sm text-white shadow-lg bg-psc-500 hover:bg-psc-600 hover:ring-2 hover:ring-psc-500 hover:ring-offset-2 min-h-[2.25rem]">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="button-icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</svg>
{{ 'back'|trans }}</a>
</div>
{% endblock %}
{% block body %} {% block body %}
<div class="w-full">
{{ component('NewsForm', {
form: form,
initialFormData: news,
customGroups: customGroups
}) }}
</div>
{% endblock %}
<div class="header">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<h3>
<i class="fa-fw fa fa-newspaper"></i>
News <span>>
erstellen </span>
</h3>
</div>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 text-end">
<a href="{{ path("psc_shop_news_backend_list") }}" class="btn btn-default btn-sm"><i class="fa fa-lg fa-fw fa-arrow-left"></i> Zurück</a>
</div>
</div>
</div>
<div class="body">
{{ form_start(form, { 'attr': {'class': ''}}) }}
<div class="panel">
<div class="header">
<h4>{{ news.title }}</h4>
</div>
<div class="body">
<div class="row">
<div class="col-md-2">
<ul class="nav nav-pills flex-column" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="tab" href="#all" role="tab">Allgemein</a>
</li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#text" role="tab">Text</a>
</li>
{% for customGroup in customGroups %}
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#{{ customGroup.id }}" role="tab">{{ customGroup.title }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="col-md-10">
<div class="tab-content">
<div class="tab-pane active" id="all" role="tabpanel">
<div class="row">
<div class="col-md-4">
<div class="row mb-3">
<label class="col-md-3 form-control-label">{{ form_label(form.title) }}</label>
<div class="col-md-9">
{{ form_widget(form.title) }}
</div>
</div>
</div>
<div class="col-md-4">
<div class="row mb-3">
<label class="col-md-3 form-control-label">{{ form_label(form.url) }}</label>
<div class="col-md-9">
{{ form_widget(form.url) }}
</div>
</div>
</div>
<div class="col-md-4">
<div class="row">
<div class="col-md-6">{{ form_widget(form.enable) }}</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="row mb-3">
<label class="col-md-3 form-control-label">{{ form_label(form.sortDate) }}</label>
<div class="col-md-9">
{{ form_widget(form.sortDate) }}
</div>
</div>
</div>
<div class="col-md-4">
<div class="row mb-3">
<label class="col-md-3 form-control-label">{{ form_label(form.language) }}</label>
<div class="col-md-9">
{{ form_widget(form.language) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="row mb-3">
<label class="col-md-1 form-control-label">{{ form_label(form.introduction) }}</label>
<div class="col-md-11">
{{ form_widget(form.introduction) }}
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="text" role="tabpanel">
{{ form_widget(form.text, {attr: {'class': 'form-control summernote'}}) }}
</div>
{% for customGroup in customGroups %}
<div class="tab-pane" id="{{ customGroup.id }}" role="tabpanel">
{% for customField in customFields %}
{% if customField.group == customGroup.id and customField.getTemplate %}
{{ include(customField.getTemplate, { 'form': form }) }}
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<div class="panel">
<div class="body">
<div class="row mb-3">
<div class="col-md-offset-1 col-md-11">
{{ form_widget(form.save, {attr: {class: 'btn btn-primary btn-sm'}}) }}
</div>
</div>
</div>
</div>
{{ form_end(form) }}
</div>
{{ summernote_mediabundle_init('default') }}
{% endblock %}

View File

@ -21,10 +21,10 @@
{% block body %} {% block body %}
<div class="w-full"> <div class="w-full">
{{ component('NewsForm', { {{ component('NewsForm', {
form: form, form: form,
news: news, initialFormData: news,
customGroups: customGroups customGroups: customGroups
}) }} }) }}
</div> </div>
<h4 class="text-psc text-xl font-medium flex flex-row gap-1 mb-2"> <h4 class="text-psc text-xl font-medium flex flex-row gap-1 mb-2">
@ -32,36 +32,37 @@
<path stroke-linecap="round" stroke-linejoin="round" d="M6.429 9.75 2.25 12l4.179 2.25m0-4.5 5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L21.75 12l-4.179 2.25m0 0 4.179 2.25L12 21.75 2.25 16.5l4.179-2.25m11.142 0-5.571 3-5.571-3" /> <path stroke-linecap="round" stroke-linejoin="round" d="M6.429 9.75 2.25 12l4.179 2.25m0-4.5 5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L21.75 12l-4.179 2.25m0 0 4.179 2.25L12 21.75 2.25 16.5l4.179-2.25m11.142 0-5.571 3-5.571-3" />
</svg> </svg>
{{ 'Changes'|trans }}</h4> {{ 'Changes'|trans }}</h4>
<div class="rounded-sm border bg-white px-7.5 py-6 shadow-lg dark:border-strokedark dark:bg-boxdark"> <div class="rounded-sm border bg-white px-6 py-6 shadow-lg dark:border-strokedark dark:bg-boxdark">
<div class="w-full grid grid-cols-4 border-t border-stroke px-4 bg-slate-100 py-4.5 dark:border-strokedark sm:grid-cols-8 md:px-6 2xl:px-7.5"> <div class="w-full rounded-lg border border-stone-200">
<div class="hidden sm:flex col-span-1 px-6 py-3"> <div class="grid grid-cols-4 border-b border-stone-200 bg-stone-100 text-sm font-medium text-stone-600 dark:bg-surface-dark">
{{ 'Date'|trans }} <div class="hidden sm:flex col-span-1 px-6 py-3 font-bold">
{{ 'Date'|trans }}
</div>
<div class="col-span-1 px-6 py-3 font-bold">
{{ 'Username'|trans }}
</div>
<div class="col-span-2 px-6 py-3 font-bold">
{{ 'Changes'|trans }}
</div>
</div> </div>
<div class="col-span-1 px-6 py-3"> {% for change in changes %}
{{ 'Username'|trans }} <div class="grid grid-cols-4 group text-sm text-stone-800 dark:text-white">
<div class="hidden sm:flex col-span-1 px-6 py-3">
{{ change.created|date('H:i:s d.m.Y') }}
</div>
<div class="col-span-1 px-6 py-3">
{{ change.username }}
</div>
<div class="col-span-2 px-6 py-3">
{% for key, set in change.changeset %}
{% if set[1] is not iterable %}
<strong>{{ key }}</strong> <span class="badge bg-danger"><del>{{ set[0] }}</del></span><span class="badge bg-success">{% if set[1] is null %}0{% else %}{{ set[1] }}{% endif %}</span></br>
{% endif %}
{% endfor %}
</div>
</div> </div>
<div class="col-span-2 px-6 py-3"> {% endfor %}
{{ 'Changes'|trans }} </div>
</div>
</div>
{% for change in changes %}
<div class="w-full grid grid-cols-4 border-t border-stroke px-4 bg-slate-100 py-4.5 dark:border-strokedark sm:grid-cols-8 md:px-6 2xl:px-7.5">
<div class="hidden sm:flex col-span-1 px-6 py-3">
{{ change.created|date('H:i:s d.m.Y') }}
</div>
<div class="col-span-1 px-6 py-3">
{{ change.username }}
</div>
<div class="col-span-2 px-6 py-3">
{% for key, set in change.changeset %}
{% if set[1] is not iterable %}
<strong>{{ key }}</strong> <span class="badge bg-danger"><del>{{ set[0] }}</del></span><span class="badge bg-success">{% if set[1] is null %}0{% else %}{{ set[1] }}{% endif %}</span></br>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -2,7 +2,7 @@
{{ form_start(form, {attr: {class: ''}}) }} {{ form_start(form, {attr: {class: ''}}) }}
<div class="tab-group flex-none md:flex w-full" data-dui-orientation="vertical"> <div class="tab-group flex-none md:flex w-full" data-dui-orientation="vertical">
<div role="tablist" class="relative mr-5 rounded-sm flex flex-col p-1 w-full md:w-2/12"> <div role="tablist" class="relative mr-5 rounded-sm flex flex-col p-1 w-full md:w-2/12">
<div class="absolute top-0 left-0 right-0 mx-1 text-white w-auto bg-psc-500 rounded-sm shadow-sm transition-all duration-300 transform scale-x-0 translate-x-0 tab-indicator z-0"></div> <div class="tab-indicator absolute left-0 w-1 bg-psc-500 transition-transform duration-300"></div>
<a href="#" class="tab-link flex items-center text-sm active px-4 py-2 relative" data-dui-tab-target="all"> <a href="#" class="tab-link flex items-center text-sm active px-4 py-2 relative" data-dui-tab-target="all">
<svg width="1.5em" height="1.5em" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="currentColor" class="button-icon"> <svg width="1.5em" height="1.5em" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="currentColor" class="button-icon">
<path d="M21 7.35304L21 16.647C21 16.8649 20.8819 17.0656 20.6914 17.1715L12.2914 21.8381C12.1102 21.9388 11.8898 21.9388 11.7086 21.8381L3.30861 17.1715C3.11814 17.0656 3 16.8649 3 16.647L2.99998 7.35304C2.99998 7.13514 3.11812 6.93437 3.3086 6.82855L11.7086 2.16188C11.8898 2.06121 12.1102 2.06121 12.2914 2.16188L20.6914 6.82855C20.8818 6.93437 21 7.13514 21 7.35304Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path> <path d="M21 7.35304L21 16.647C21 16.8649 20.8819 17.0656 20.6914 17.1715L12.2914 21.8381C12.1102 21.9388 11.8898 21.9388 11.7086 21.8381L3.30861 17.1715C3.11814 17.0656 3 16.8649 3 16.647L2.99998 7.35304C2.99998 7.13514 3.11812 6.93437 3.3086 6.82855L11.7086 2.16188C11.8898 2.06121 12.1102 2.06121 12.2914 2.16188L20.6914 6.82855C20.8818 6.93437 21 7.13514 21 7.35304Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
@ -72,36 +72,37 @@
{{ form_widget(form.text) }} {{ form_widget(form.text) }}
</div> </div>
<div id="media" class="tab-content w-full text-stone-500 text-sm hidden p-4"> <div id="media" class="tab-content w-full text-stone-500 text-sm hidden p-4">
<div class="w-full overflow-hidden rounded-lg border border-stone-200">
<table class="table table-borderless form-no-mb"> <table class="w-full">
<thead> <thead class="border-b border-stone-200 bg-stone-100 text-sm font-medium text-stone-600 dark:bg-surface-dark"">
<tr>
<td>Name</td>
<td>Description</td>
<td>Media</td>
<td></td>
</tr>
</thead>
<tbody>
{% for media_form in form.media %}
<tr> <tr>
<td> <td class="px-2.5 py-2 text-start font-medium">Name</td>
{{ form_row(media_form.name) }} <td class="px-2.5 py-2 text-start font-medium">Description</td>
</td> <td class="px-2.5 py-2 text-start font-medium">Media</td>
<td> <td></td>
{{ form_row(media_form.description) }}
</td>
<td>
{{ form_row(media_form.media) }}
</td>
<td>
{{ form_row(media_form.vars.button_delete, {label: 'X', attr: {class: 'btn btn-outline-danger'}}) }}
</td>
</tr> </tr>
{% endfor %} </thead>
</tbody> <tbody class="group text-sm text-stone-800 dark:text-white">
</table> {% for media_form in form.media %}
{{ form_widget(form.media.vars.button_add, {label: '+ Add Media', attr: {class: 'btn btn-outline-primary'}}) }} <tr class="border-b border-stone-200 last:border-0">
<td class="p-3">
{{ form_row(media_form.name) }}
</td>
<td class="p-3">
{{ form_row(media_form.description) }}
</td>
<td class="p-3">
{{ form_row(media_form.media) }}
</td>
<td class="p-3">
{{ form_row(media_form.vars.button_delete, {label: 'X', attr: {class: 'btn btn-outline-danger'}}) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{{ form_widget(form.media.vars.button_add, {label: '+ Add Media', attr: {class: 'psc-button-secondary mt-1'}}) }}
</div> </div>
{% if customGroups is defined %} {% if customGroups is defined %}
{% for customGroup in customGroups %} {% for customGroup in customGroups %}

View File

@ -17,8 +17,8 @@ class NewsForm extends AbstractController
use DefaultActionTrait; use DefaultActionTrait;
use LiveCollectionTrait; use LiveCollectionTrait;
#[LiveProp(fieldName: 'formData')] #[LiveProp]
public ?News $news; public ?News $initialFormData;
public ?Array $customGroups; public ?Array $customGroups;
@ -26,7 +26,7 @@ class NewsForm extends AbstractController
{ {
return $this->createForm( return $this->createForm(
NewsType::class, NewsType::class,
$this->news $this->initialFormData
); );
} }
} }

View File

@ -113,7 +113,7 @@ class Order
return false; return false;
} }
protected function updateOrder(\PSC\Shop\OrderBundle\Model\Base $order) public function updateOrder(\PSC\Shop\OrderBundle\Model\Base $order)
{ {
if ($this->load_only_order) { if ($this->load_only_order) {
die("Do Not Update"); die("Do Not Update");
@ -286,10 +286,12 @@ class Order
public function getLastOrders(int $limit = 10): array public function getLastOrders(int $limit = 10): array
{ {
$query = $this->entityManager $query = $this->entityManager
->createQuery(' ->createQuery(
'
SELECT c FROM PSCEntityBundle:Order c SELECT c FROM PSCEntityBundle:Order c
JOIN c.shop s JOIN c.shop s
WHERE s.uid = :id ORDER BY c.created DESC') WHERE s.uid = :id ORDER BY c.created DESC'
)
->setParameter('id', $this->shopService->getSelectedShop()->getUid()) ->setParameter('id', $this->shopService->getSelectedShop()->getUid())
->setMaxResults($limit); ->setMaxResults($limit);
try { try {

View File

@ -0,0 +1,122 @@
<?php
namespace PSC\Shop\QueueBundle\Command;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManagerInterface;
use PSC\Shop\EntityBundle\Document\Job;
use PSC\Shop\EntityBundle\Document\JobLog;
use PSC\Shop\EntityBundle\Document\Queue;
use PSC\Shop\EntityBundle\Entity\Shop;
use PSC\Shop\QueueBundle\Event\InternalEvent;
use PSC\Shop\QueueBundle\Service\Event\Manager;
use PSC\Shop\QueueBundle\Service\Event\Registry;
use PSC\System\PluginBundle\Document\Plugin;
use PSC\System\PluginBundle\Event\ClearCache;
use PSC\System\PluginBundle\Event\DeInstallPlugin;
use PSC\System\PluginBundle\Event\EveryRun;
use PSC\System\PluginBundle\Event\InstallPlugin;
use PSC\System\SettingsBundle\Document\LogEntry;
use PSC\System\SettingsBundle\Service\Log;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\FlockStore;
#[AsCommand(name: 'application:queue:doEveryDay')]
class DoEveryDayCommand extends Command
{
/**
* @var Manager
*/
private Manager $eventManager;
/**
* @var Registry
*/
private Registry $eventRegistry;
private \PSC\Shop\QueueBundle\Service\Queue\Registry $queueRegistry;
/**
* @var DocumentManager
*/
private DocumentManager $mongoDb;
/**
* @var KernelInterface
*/
private KernelInterface $kernel;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $entityManager;
/**
* @var Log
*/
private Log $logService;
private iterable $internalQueues;
public function __construct(#[TaggedIterator('psc.queues.internal')] iterable $internalQueues, EntityManagerInterface $entityManager, Manager $eventManager, Registry $eventRegistry, \PSC\Shop\QueueBundle\Service\Queue\Registry $queueRegistry, DocumentManager $documentManager, KernelInterface $kernel, Log $logService, private readonly \Symfony\Component\DependencyInjection\ContainerInterface $containerService)
{
$this->eventManager = $eventManager;
$this->eventRegistry = $eventRegistry;
$this->queueRegistry = $queueRegistry;
$this->mongoDb = $documentManager;
$this->kernel = $kernel;
$this->entityManager = $entityManager;
$this->logService = $logService;
$this->internalQueues = $internalQueues;
// you *must* call the parent constructor
parent::__construct();
}
protected function configure()
{
$this
->setDescription('Run the Jobs');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$store = new FlockStore();
$factory = new LockFactory($store);
$lock = $factory->createLock('doEveryDayQueue');
if ($lock->acquire()) {
foreach ($this->internalQueues as $queue) {
$queue->execute();
}
$queues = $this->mongoDb
->getRepository('PSC\Shop\EntityBundle\Document\Queue')
->findBy(
array('eventType' => 'system_plugin_every_day', 'active' => true),
[
'pos' => 'ASC'
]
);
/**
* @var Queue $queue
*/
foreach ($queues as $queue) {
$queueObj = $this->queueRegistry->get($queue->getQueueType());
try {
$success = $queueObj->execute(new EveryRun(), $queue);
} catch (\Exception $exception) {
$this->logService->createLogEntry(new Shop(), LogEntry::ERROR, "Cron", "", $exception->getMessage(), []);
}
}
$this->eventManager->clearManager();
}
date_default_timezone_set('Europe/Berlin');
$output->writeln("Successfully ".date('Y-m-d H:i:s'));
return 0;
}
}

View File

@ -0,0 +1,248 @@
<?php
namespace PSC\Shop\QueueBundle\Command;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManagerInterface;
use PSC\Shop\EntityBundle\Document\Job;
use PSC\Shop\EntityBundle\Document\JobLog;
use PSC\Shop\EntityBundle\Document\Queue;
use PSC\Shop\EntityBundle\Entity\Shop;
use PSC\Shop\QueueBundle\Event\InternalEvent;
use PSC\Shop\QueueBundle\Service\Event\Manager;
use PSC\Shop\QueueBundle\Service\Event\Registry;
use PSC\System\PluginBundle\Document\Plugin;
use PSC\System\PluginBundle\Event\ClearCache;
use PSC\System\PluginBundle\Event\DeInstallPlugin;
use PSC\System\PluginBundle\Event\EveryRun;
use PSC\System\PluginBundle\Event\InstallPlugin;
use PSC\System\SettingsBundle\Document\LogEntry;
use PSC\System\SettingsBundle\Service\Log;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\FlockStore;
#[AsCommand(name: 'application:queue:doEveryHour')]
class DoEveryHourCommand extends Command
{
/**
* @var Manager
*/
private Manager $eventManager;
/**
* @var Registry
*/
private Registry $eventRegistry;
private \PSC\Shop\QueueBundle\Service\Queue\Registry $queueRegistry;
/**
* @var DocumentManager
*/
private DocumentManager $mongoDb;
/**
* @var KernelInterface
*/
private KernelInterface $kernel;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $entityManager;
/**
* @var Log
*/
private Log $logService;
private iterable $internalQueues;
public function __construct(#[TaggedIterator('psc.queues.internal')] iterable $internalQueues, EntityManagerInterface $entityManager, Manager $eventManager, Registry $eventRegistry, \PSC\Shop\QueueBundle\Service\Queue\Registry $queueRegistry, DocumentManager $documentManager, KernelInterface $kernel, Log $logService, private readonly \Symfony\Component\DependencyInjection\ContainerInterface $containerService)
{
$this->eventManager = $eventManager;
$this->eventRegistry = $eventRegistry;
$this->queueRegistry = $queueRegistry;
$this->mongoDb = $documentManager;
$this->kernel = $kernel;
$this->entityManager = $entityManager;
$this->logService = $logService;
$this->internalQueues = $internalQueues;
// you *must* call the parent constructor
parent::__construct();
}
protected function configure()
{
$this
->setDescription('Run the Jobs');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$store = new FlockStore();
$factory = new LockFactory($store);
$lock = $factory->createLock('doEveryHourQueue');
if ($lock->acquire()) {
foreach ($this->internalQueues as $queue) {
$queue->execute();
}
$queues = $this->mongoDb
->getRepository('PSC\Shop\EntityBundle\Document\Queue')
->findBy(
array('eventType' => 'system_plugin_every_hour', 'active' => true),
[
'pos' => 'ASC'
]
);
/**
* @var Queue $queue
*/
foreach ($queues as $queue) {
$queueObj = $this->queueRegistry->get($queue->getQueueType());
try {
$success = $queueObj->execute(new EveryRun(), $queue);
} catch (\Exception $exception) {
$this->logService->createLogEntry(new Shop(), LogEntry::ERROR, "Cron", "", $exception->getMessage(), []);
}
}
$this->eventManager->clearManager();
/**
* @var Job $job
*/
foreach ($this->eventManager->getAll() as $job) {
$canBeRemoved = true;
$event = $this->eventRegistry->get($job->getEvent());
if ($event instanceof ClearCache) {
$fs = new Filesystem();
//$fs->remove($this->kernel->getCacheDir());
} elseif ($event instanceof InstallPlugin) {
$event->setData($job->getData());
$event->setShop($job->getShop());
$install = $this->containerService->get($event->getInstallClass());
$install->execute();
$plugin = $this->mongoDb
->getRepository(Plugin::class)
->findOneBy(array('id' => (string)$event->getPlugin()));
$plugin->setShouldBeInstalled(false);
$this->mongoDb->persist($plugin);
} elseif ($event instanceof DeInstallPlugin) {
$event->setData($job->getData());
$event->setShop($job->getShop());
$deinstall = $this->containerService->get($event->getDeInstallClass());
$deinstall->execute();
$plugin = $this->mongoDb
->getRepository(Plugin::class)
->findOneBy(array('id' => (string)$event->getPlugin()));
$plugin->setInstalled(false);
$plugin->setShouldBeDeInstalled(false);
$this->mongoDb->persist($plugin);
} elseif ($event instanceof InternalEvent) {
$event->setData($job->getData());
$event->setShop($job->getShop());
} else {
$event->setData($job->getData());
$event->setShop($job->getShop());
$queues = $this->mongoDb
->getRepository(Queue::class)
->findBy(
array(
'shop' => $job->getShop(),
'active' => true,
'eventType' => $job->getEvent()
),
[
'pos' => 'ASC'
]
);
/**
* @var Queue $queue
*/
foreach ($queues as $queue) {
if (!$event->doProcess($queue)) {
continue;
}
$queueObj = $this->queueRegistry->get($queue->getQueueType());
/**
* @var JobLog $jobLog
*/
$jobLog = $this->mongoDb->getRepository(JobLog::class)->findOneBy(
[
'job' => $job->getId(),
'queue' => $queue->getId()
]
);
if ($jobLog) {
if ($jobLog->getError() == "") {
continue;
}
$jobLog->incCount();
if ($jobLog->getCount() > 2 && $jobLog->getError() != "") {
$canBeRemoved = false;
continue;
}
} else {
$jobLog = new JobLog();
$jobLog->setJob($job->getId());
$jobLog->setQueue($queue->getId());
}
$jobLog->setUpdated(new \DateTime());
try {
$success = $queueObj->execute($event, $queue);
if (!$success) {
$canBeRemoved = false;
$jobLog->setError($queueObj->getError());
} else {
$jobLog->setError("");
}
$this->mongoDb->persist($jobLog);
$this->mongoDb->flush();
} catch (\Exception $e) {
$response = $e->getResponse();
$message = $response->getContent(false);
$jobLog->setError($e->getMessage());
$this->mongoDb->persist($jobLog);
$this->mongoDb->flush();
$canBeRemoved = false;
}
}
}
if ($canBeRemoved) {
$this->eventManager->removeJob($job);
}
}
if (count($this->eventManager->getAll()) == 0) {
$this->mongoDb->createQueryBuilder(JobLog::class)->remove()->getQuery()->execute();
}
}
date_default_timezone_set('Europe/Berlin');
$output->writeln("Successfully ".date('Y-m-d H:i:s'));
return 0;
}
}

View File

@ -28,8 +28,8 @@ use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\FlockStore; use Symfony\Component\Lock\Store\FlockStore;
#[AsCommand(name: 'application:queue:do')] #[AsCommand(name: 'application:queue:doEveryMinute')]
class DoCommand extends Command class DoEveryMinuteCommand extends Command
{ {
/** /**
* @var Manager * @var Manager
@ -81,13 +81,10 @@ class DoCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$store = new FlockStore(); $store = new FlockStore();
$factory = new LockFactory($store); $factory = new LockFactory($store);
$lock = $factory->createLock('doQueue'); $lock = $factory->createLock('doEveryMinuteQueue');
if ($lock->acquire()) { if ($lock->acquire()) {
foreach ($this->internalQueues as $queue) { foreach ($this->internalQueues as $queue) {

View File

@ -13,117 +13,122 @@ class Mail
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $text; protected $text;
/** /**
* @var string $textHtml * @var string $textHtml
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $textHtml; protected $textHtml;
/** /**
* @var string $from * @var string $from
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $from; protected $from;
/** /**
* @var string $fromName * @var string $fromName
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $fromName; protected $fromName;
/** /**
* @var string $to * @var string $to
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $to; protected $to;
/** /**
* @var string $toName * @var string $toName
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $toName; protected $toName;
/** /**
* @var string $subject * @var string $subject
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $subject; protected $subject;
/** /**
* @var string $bcc * @var string $bcc
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $bcc; protected $bcc;
/** /**
* @var boolean $sendInvoice * @var boolean $sendInvoice
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendInvoice; protected $sendInvoice;
/** /**
* @var boolean $sendDelivery * @var boolean $sendInvoice
*/ */
#[Field(type: 'bool')]
protected $sendXInvoice;
/**
* @var boolean $sendDelivery
*/
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendDelivery; protected $sendDelivery;
/** /**
* @var boolean $sendLabel * @var boolean $sendLabel
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendLabel; protected $sendLabel;
/** /**
* @var boolean $sendOrder * @var boolean $sendOrder
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendOrder; protected $sendOrder;
/** /**
* @var boolean $sendOffer * @var boolean $sendOffer
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendOffer; protected $sendOffer;
/** /**
* @var boolean $sendJobticket * @var boolean $sendJobticket
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendJobticket; protected $sendJobticket;
/** /**
* @var boolean $sendStorno * @var boolean $sendStorno
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendStorno; protected $sendStorno;
/** /**
* @var boolean $sendPosInvoice * @var boolean $sendPosInvoice
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosInvoice; protected $sendPosInvoice;
/** /**
* @var boolean $sendPosDelivery * @var boolean $sendPosDelivery
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosDelivery; protected $sendPosDelivery;
/** /**
* @var boolean $sendPosLabel * @var boolean $sendPosLabel
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosLabel; protected $sendPosLabel;
/** /**
* @var boolean $sendPosOrder * @var boolean $sendPosOrder
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosOrder; protected $sendPosOrder;
/** /**
* @var boolean $sendPosOffer * @var boolean $sendPosOffer
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosOffer; protected $sendPosOffer;
/** /**
* @var boolean $sendPosJobticket * @var boolean $sendPosJobticket
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosJobticket; protected $sendPosJobticket;
/** /**
* @var boolean $sendPosStorno * @var boolean $sendPosStorno
*/ */
#[Field(type: 'bool')] #[Field(type: 'bool')]
protected $sendPosStorno; protected $sendPosStorno;
/** /**
* @var array $files * @var array $files
*/ */
#[Field(type: 'collection')] #[Field(type: 'collection')]
protected $files; protected $files;
/** /**
* @return string * @return string
*/ */
public function getText() public function getText()
@ -267,6 +272,23 @@ class Mail
$this->sendInvoice = $sendInvoice; $this->sendInvoice = $sendInvoice;
} }
/**
* @return bool
*/
public function isSendXInvoice()
{
return $this->sendXInvoice;
}
/**
* @param bool $sendXInvoice
*/
public function setSendXInvoice($sendXInvoice)
{
$this->sendXInvoice = $sendXInvoice;
}
/** /**
* @return bool * @return bool
*/ */
@ -490,4 +512,5 @@ class Mail
{ {
$this->sendPosJobticket = $sendPosJobticket; $this->sendPosJobticket = $sendPosJobticket;
} }
} }

View File

@ -93,6 +93,14 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-1">
<div class="row mb-3">
{{ form_label(form.sendXInvoice) }}
<div class="col-md-12">
{{ form_widget(form.sendXInvoice) }}
</div>
</div>
</div>
<div class="col-md-1"> <div class="col-md-1">
<div class="row mb-3"> <div class="row mb-3">
{{ form_label(form.sendDelivery) }} {{ form_label(form.sendDelivery) }}
@ -337,4 +345,4 @@
$newLinkLi.before($newFormLi); $newLinkLi.before($newFormLi);
} }
</script> </script>
{% endverbatim %} {% endverbatim %}

View File

@ -2,7 +2,7 @@
namespace PSC\Shop\QueueBundle\Type; namespace PSC\Shop\QueueBundle\Type;
require_once(__DIR__ . '/../../../Shop/EntityBundle/Lagacy/TP_Basket_Item.php'); require_once __DIR__ . '/../../../Shop/EntityBundle/Lagacy/TP_Basket_Item.php';
use Doctrine\Bundle\MongoDBBundle\ManagerRegistry; use Doctrine\Bundle\MongoDBBundle\ManagerRegistry;
use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
@ -56,7 +56,9 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class Mail implements QueueInterface, ConfigurableElementInterface class Mail implements QueueInterface, ConfigurableElementInterface
{ {
/** @var Form */ /**
* @var Form
*/
protected $_formFactory = null; protected $_formFactory = null;
protected $_entityManager = null; protected $_entityManager = null;
protected $_doctrine_mongodb = null; protected $_doctrine_mongodb = null;
@ -66,8 +68,8 @@ class Mail implements QueueInterface, ConfigurableElementInterface
protected $_template = null; protected $_template = null;
protected $_error = null; protected $_error = null;
/** /**
* @var Log * @var Log
*/ */
protected Log $_logService; protected Log $_logService;
public function __construct(TemplateVars $templateVars, Printing $printing, FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, DocumentManager $doctrine_mongodb, MailerInterface $mailer, \Twig\Environment $template, Log $logService) public function __construct(TemplateVars $templateVars, Printing $printing, FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, DocumentManager $doctrine_mongodb, MailerInterface $mailer, \Twig\Environment $template, Log $logService)
{ {
@ -125,6 +127,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$builder->add("toName", TextType::class, array('label' => 'An Name', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("toName", TextType::class, array('label' => 'An Name', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("subject", TextType::class, array('label' => 'Betreff*', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("subject", TextType::class, array('label' => 'Betreff*', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("bcc", TextType::class, array('label' => 'BCC (info@..,prod@...)', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("bcc", TextType::class, array('label' => 'BCC (info@..,prod@...)', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendXInvoice", CheckboxType::class, array('label' => 'XRechnung anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendInvoice", CheckboxType::class, array('label' => 'Rechnung anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendInvoice", CheckboxType::class, array('label' => 'Rechnung anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendDelivery", CheckboxType::class, array('label' => 'Lieferschein anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendDelivery", CheckboxType::class, array('label' => 'Lieferschein anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendOrder", CheckboxType::class, array('label' => 'Auftrag anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendOrder", CheckboxType::class, array('label' => 'Auftrag anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
@ -139,13 +142,15 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$builder->add("sendPosJobticket", CheckboxType::class, array('label' => 'Jobticket anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendPosJobticket", CheckboxType::class, array('label' => 'Jobticket anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendPosLabel", CheckboxType::class, array('label' => 'Label anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendPosLabel", CheckboxType::class, array('label' => 'Label anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add("sendPosStorno", CheckboxType::class, array('label' => 'Storno anfügen?', 'required' => false, 'attr' => array('class' => 'form-element'))); $builder->add("sendPosStorno", CheckboxType::class, array('label' => 'Storno anfügen?', 'required' => false, 'attr' => array('class' => 'form-element')));
$builder->add('files', CollectionType::class, array( $builder->add(
'files', CollectionType::class, array(
'entry_type' => FileType::class, 'entry_type' => FileType::class,
'entry_options' => array('label' => false), 'entry_options' => array('label' => false),
'allow_add' => true, 'allow_add' => true,
'allow_delete' => true, 'allow_delete' => true,
'label' => false 'label' => false
)); )
);
} }
} }
@ -164,6 +169,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$mail->setSubject($form->get('subject')->getData()); $mail->setSubject($form->get('subject')->getData());
$mail->setBcc($form->get('bcc')->getData()); $mail->setBcc($form->get('bcc')->getData());
$mail->setSendInvoice($form->get('sendInvoice')->getData()); $mail->setSendInvoice($form->get('sendInvoice')->getData());
$mail->setSendXInvoice($form->get('sendXInvoice')->getData());
$mail->setSendDelivery($form->get('sendDelivery')->getData()); $mail->setSendDelivery($form->get('sendDelivery')->getData());
$mail->setSendOrder($form->get('sendOrder')->getData()); $mail->setSendOrder($form->get('sendOrder')->getData());
$mail->setSendOffer($form->get('sendOffer')->getData()); $mail->setSendOffer($form->get('sendOffer')->getData());
@ -196,6 +202,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$form->get('subject')->setData($queueObj->getQueueDocument()->getSubject()); $form->get('subject')->setData($queueObj->getQueueDocument()->getSubject());
$form->get('bcc')->setData($queueObj->getQueueDocument()->getBcc()); $form->get('bcc')->setData($queueObj->getQueueDocument()->getBcc());
$form->get('sendInvoice')->setData($queueObj->getQueueDocument()->isSendInvoice()); $form->get('sendInvoice')->setData($queueObj->getQueueDocument()->isSendInvoice());
$form->get('sendXInvoice')->setData($queueObj->getQueueDocument()->isSendXInvoice());
$form->get('sendDelivery')->setData($queueObj->getQueueDocument()->isSendDelivery()); $form->get('sendDelivery')->setData($queueObj->getQueueDocument()->isSendDelivery());
$form->get('sendOrder')->setData($queueObj->getQueueDocument()->isSendOrder()); $form->get('sendOrder')->setData($queueObj->getQueueDocument()->isSendOrder());
$form->get('sendOffer')->setData($queueObj->getQueueDocument()->isSendOffer()); $form->get('sendOffer')->setData($queueObj->getQueueDocument()->isSendOffer());
@ -219,8 +226,8 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
/** /**
* @param EventInterface $event * @param EventInterface $event
* @param Queue $queue * @param Queue $queue
* @return bool * @return bool
* @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\OptimisticLockException
* @throws \MongoException * @throws \MongoException
@ -229,12 +236,18 @@ class Mail implements QueueInterface, ConfigurableElementInterface
public function execute(EventInterface $event, Queue $queue) public function execute(EventInterface $event, Queue $queue)
{ {
/** @var \PSC\Shop\QueueBundle\Document\Queue\Mail $mailDoc */ /**
* @var \PSC\Shop\QueueBundle\Document\Queue\Mail $mailDoc
*/
$mailDoc = $queue->getQueueDocument(); $mailDoc = $queue->getQueueDocument();
$eventDoc = $queue->getEventDocument(); $eventDoc = $queue->getEventDocument();
/** @var TemplateVars $templateVars */ /**
* @var TemplateVars $templateVars
*/
$templateVars = $this->_templateVars; $templateVars = $this->_templateVars;
/** @var Printing $printing */ /**
* @var Printing $printing
*/
$printing = $this->_printing; $printing = $this->_printing;
if ($event->isOverwriteQueueHandling()) { if ($event->isOverwriteQueueHandling()) {
try { try {
@ -265,10 +278,14 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($event instanceof Lock) { if ($event instanceof Lock) {
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
$shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop'); $shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop');
/** @var Shop $shop */ /**
* @var Shop $shop
*/
$shop = $shopRepo->findOneBy(array('uid' => $event->getShop())); $shop = $shopRepo->findOneBy(array('uid' => $event->getShop()));
$params = array( $params = array(
'contact' => $contact, 'contact' => $contact,
@ -295,17 +312,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($html) { if ($html) {
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Lock Mail send", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Lock Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($params), 'from' => $from->render($params),
'to' => $to->render($params), 'to' => $to->render($params),
'subject' => $subject->render($params) 'subject' => $subject->render($params)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Lock Mail error", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Lock Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -314,14 +335,20 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof UnLock || $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Create || $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Login) { if ($event instanceof UnLock || $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Create || $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Login) {
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
/** @var \PSC\Shop\EntityBundle\Document\Contact $contactObj */ /**
* @var \PSC\Shop\EntityBundle\Document\Contact $contactObj
*/
$contactObj = $this->_doctrine_mongodb $contactObj = $this->_doctrine_mongodb
->getRepository('PSC\Shop\EntityBundle\Document\Contact') ->getRepository('PSC\Shop\EntityBundle\Document\Contact')
->findOneBy(array('uid' => (string) $contact->getId())); ->findOneBy(array('uid' => (string) $contact->getId()));
$shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop'); $shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop');
/** @var Shop $shop */ /**
* @var Shop $shop
*/
$shop = $shopRepo->findOneBy(array('uid' => $event->getShop())); $shop = $shopRepo->findOneBy(array('uid' => $event->getShop()));
$params = array( $params = array(
'contact' => $contact, 'contact' => $contact,
@ -349,17 +376,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($html) { if ($html) {
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Login Mail send", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Login Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($params), 'from' => $from->render($params),
'to' => $to->render($params), 'to' => $to->render($params),
'subject' => $subject->render($params) 'subject' => $subject->render($params)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Login Mail error", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Login Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -368,10 +399,14 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof Start) { if ($event instanceof Start) {
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
$shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop'); $shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop');
/** @var Shop $shop */ /**
* @var Shop $shop
*/
$shop = $shopRepo->findOneBy(array('uid' => $event->getShop())); $shop = $shopRepo->findOneBy(array('uid' => $event->getShop()));
$contact->setPasswordResetUuid(Uuid::uuid4()); $contact->setPasswordResetUuid(Uuid::uuid4());
$contact->setPasswordResetDate(time()); $contact->setPasswordResetDate(time());
@ -402,18 +437,22 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($html) { if ($html) {
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($params), 'from' => $from->render($params),
'to' => $to->render($params), 'to' => $to->render($params),
'subject' => $subject->render($params) 'subject' => $subject->render($params)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -422,10 +461,14 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof Finish) { if ($event instanceof Finish) {
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
$shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop'); $shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop');
/** @var Shop $shop */ /**
* @var Shop $shop
*/
$shop = $shopRepo->findOneBy(array('uid' => $event->getShop())); $shop = $shopRepo->findOneBy(array('uid' => $event->getShop()));
$password = $this->generatePassword(10); $password = $this->generatePassword(10);
$contact->setPassword(password_hash($password, PASSWORD_DEFAULT)); $contact->setPassword(password_hash($password, PASSWORD_DEFAULT));
@ -458,17 +501,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [
'message' => "Nicht verfügbar da Passwort enhalten", 'message' => "Nicht verfügbar da Passwort enhalten",
'from' => $from->render($params), 'from' => $from->render($params),
'to' => $to->render($params), 'to' => $to->render($params),
'subject' => $subject->render($params) 'subject' => $subject->render($params)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -477,11 +524,15 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof Notify) { if ($event instanceof Notify) {
$positionRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos'); $positionRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos');
/** @var Orderpos $position */ /**
* @var Orderpos $position
*/
$position = $positionRepo->findOneBy(array('uuid' => $event->getPosition())); $position = $positionRepo->findOneBy(array('uuid' => $event->getPosition()));
$templateVars->loadOrder($position->getOrder()->getUuid()); $templateVars->loadOrder($position->getOrder()->getUuid());
$params = $templateVars->getPosTwigVars($event->getPosition()); $params = $templateVars->getPosTwigVars($event->getPosition());
/** @var Position $objDoc */ /**
* @var Position $objDoc
*/
$objDoc = $this->_doctrine_mongodb $objDoc = $this->_doctrine_mongodb
->getRepository(Position::class) ->getRepository(Position::class)
->findOneBy(['uid' => (string)$position->getId()]); ->findOneBy(['uid' => (string)$position->getId()]);
@ -525,7 +576,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof Change) { if ($event instanceof Change) {
$positionRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos'); $positionRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos');
/** @var Orderpos $position */ /**
* @var Orderpos $position
*/
$position = $positionRepo->findOneBy(array('uuid' => $event->getPosition())); $position = $positionRepo->findOneBy(array('uuid' => $event->getPosition()));
$templateVars->loadOrder($position->getOrder()->getUuid()); $templateVars->loadOrder($position->getOrder()->getUuid());
try { try {
@ -653,17 +706,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$message->attach($fileContent->render($templateVars->getTwigVars()), $fileName->render($templateVars->getTwigVars())); $message->attach($fileContent->render($templateVars->getTwigVars()), $fileName->render($templateVars->getTwigVars()));
} }
} }
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($templateVars->getPosTwigVars($position->getUuid())), 'from' => $from->render($templateVars->getPosTwigVars($position->getUuid())),
'to' => $to->render($templateVars->getPosTwigVars($position->getUuid())), 'to' => $to->render($templateVars->getPosTwigVars($position->getUuid())),
'subject' => $subject->render($templateVars->getPosTwigVars($position->getUuid())) 'subject' => $subject->render($templateVars->getPosTwigVars($position->getUuid()))
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -696,9 +753,14 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($mailDoc->isSendInvoice()) { if ($mailDoc->isSendInvoice()) {
$content = $printing->generateOrder($templateVars->getOrder(), Printing::INVOICE); $content = $printing->generateOrder($templateVars->getOrder(), Printing::INVOICE);
$contentXRechnung = $printing->generateXRechnung($templateVars->getOrder());
if ($content) { if ($content) {
$message->attach($content, $printing->getFileName(), 'application/pdf'); $message->attach($content, $printing->getFileName(), 'application/pdf');
}
}
if ($mailDoc->isSendXInvoice()) {
$contentXRechnung = $printing->generateXRechnung($templateVars->getOrder());
if ($contentXRechnung) {
$message->attach($contentXRechnung, "xrechnung.xml", 'application/pdf'); $message->attach($contentXRechnung, "xrechnung.xml", 'application/pdf');
} }
} }
@ -753,16 +815,20 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$message->attach($fileContent->render($templateVars->getTwigVars()), $fileName->render($templateVars->getTwigVars())); $message->attach($fileContent->render($templateVars->getTwigVars()), $fileName->render($templateVars->getTwigVars()));
} }
} }
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($templateVars->getTwigVars()), 'from' => $from->render($templateVars->getTwigVars()),
'to' => trim($to->render($templateVars->getTwigVars())) 'to' => trim($to->render($templateVars->getTwigVars()))
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "error", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -770,7 +836,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
return true; return true;
} }
if ($event instanceof \Plugin\System\PSC\Upload\Event\Create) { if ($event instanceof \Plugin\System\PSC\Upload\Event\Create) {
/** @var Upload $upload */ /**
* @var Upload $upload
*/
$upload = $this->_doctrine_mongodb $upload = $this->_doctrine_mongodb
->getRepository(Upload::class) ->getRepository(Upload::class)
->findOneBy(['id' => new ObjectId($event->getUpload())]); ->findOneBy(['id' => new ObjectId($event->getUpload())]);
@ -798,16 +866,20 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($html) { if ($html) {
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry(new Shop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "\Plugin\System\PSC\Upload\Event\Create Mail send", [ $this->_logService->createLogEntry(
new Shop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "\Plugin\System\PSC\Upload\Event\Create Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $message->getFrom(), 'from' => $message->getFrom(),
'to' => $message->getTo() 'to' => $message->getTo()
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry(new Shop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "\Plugin\System\PSC\Upload\Event\Create Mail error", [ $this->_logService->createLogEntry(
new Shop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "\Plugin\System\PSC\Upload\Event\Create Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -816,10 +888,14 @@ class Mail implements QueueInterface, ConfigurableElementInterface
} }
if ($event instanceof StockMin || $event instanceof BuyMax) { if ($event instanceof StockMin || $event instanceof BuyMax) {
$productRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product'); $productRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product');
/** @var Product $product */ /**
* @var Product $product
*/
$product = $productRepo->findOneBy(array('uuid' => $event->getProduct())); $product = $productRepo->findOneBy(array('uuid' => $event->getProduct()));
$shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop'); $shopRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shop');
/** @var Shop $shop */ /**
* @var Shop $shop
*/
$shop = $shopRepo->findOneBy(array('uid' => $event->getShop())); $shop = $shopRepo->findOneBy(array('uid' => $event->getShop()));
$params = array( $params = array(
'product' => $product, 'product' => $product,
@ -846,17 +922,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
if ($html) { if ($html) {
$message->html($html->render($params)); $message->html($html->render($params));
} }
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "StockMin BuyMax Mail send", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "StockMin BuyMax Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($params), 'from' => $from->render($params),
'to' => $to->render($params), 'to' => $to->render($params),
'subject' => $subject->render($params) 'subject' => $subject->render($params)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "StockMin BuyMax Mail error", [ $this->_logService->createLogEntry(
$shop, new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "StockMin BuyMax Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -867,7 +947,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$templateVars->loadOrder($event->getOrder()); $templateVars->loadOrder($event->getOrder());
$vars = $templateVars->getPosTwigVars($event->getPosition()); $vars = $templateVars->getPosTwigVars($event->getPosition());
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
$vars['approvalContact'] = $contact; $vars['approvalContact'] = $contact;
try { try {
@ -947,17 +1029,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$message->attach($fileContent->render($vars), $fileName->render($vars)); $message->attach($fileContent->render($vars), $fileName->render($vars));
} }
} }
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Request Mail send", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Request Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($vars), 'from' => $from->render($vars),
'to' => $to->render($vars), 'to' => $to->render($vars),
'subject' => $subject->render($vars) 'subject' => $subject->render($vars)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Request Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }
@ -968,7 +1054,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$templateVars->loadOrder($event->getOrder()); $templateVars->loadOrder($event->getOrder());
$vars = $templateVars->getPosTwigVars($event->getPosition()); $vars = $templateVars->getPosTwigVars($event->getPosition());
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact'); $contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
/** @var Contact $contact */ /**
* @var Contact $contact
*/
$contact = $contactRepo->findOneBy(array('uuid' => $event->getContact())); $contact = $contactRepo->findOneBy(array('uuid' => $event->getContact()));
$vars['approvalContact'] = $contact; $vars['approvalContact'] = $contact;
$vars['message'] = $event->getMessage(); $vars['message'] = $event->getMessage();
@ -1049,17 +1137,21 @@ class Mail implements QueueInterface, ConfigurableElementInterface
$message->attach($fileContent->render($vars), $fileName->render($vars)); $message->attach($fileContent->render($vars), $fileName->render($vars));
} }
} }
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Accept Declined Mail send", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::INFO, PSCShopQueueBundle::class, $queue->getName(), "Accept Declined Mail send", [
'message' => $message->getTextBody(), 'message' => $message->getTextBody(),
'from' => $from->render($vars), 'from' => $from->render($vars),
'to' => $to->render($vars), 'to' => $to->render($vars),
'subject' => $subject->render($vars) 'subject' => $subject->render($vars)
]); ]
);
$this->_mailer->send($message); $this->_mailer->send($message);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_logService->createLogEntry($templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Accept Declined Mail error", [ $this->_logService->createLogEntry(
$templateVars->getOrder()->getShop(), new Contact(), LogEntry::ERROR, PSCShopQueueBundle::class, $queue->getName(), "Accept Declined Mail error", [
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]
);
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;
} }

View File

@ -4,6 +4,7 @@ namespace PSC\Shop\UserBundle\Security\ApiKey;
use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\DocumentManager;
use PSC\Shop\EntityBundle\Document\Instance; use PSC\Shop\EntityBundle\Document\Instance;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
@ -40,7 +41,7 @@ class InstanceProvider implements UserProviderInterface
if (null === $instance) { if (null === $instance) {
throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException(sprintf('Instance "%s" not found.', $identifier)); throw new UserNotFoundException(sprintf('Instance "%s" not found.', $identifier));
} }
return $instance; return $instance;

View File

@ -4,9 +4,9 @@ namespace PSC\Shop\UserBundle\Security\ApiKey;
use PSC\Shop\EntityBundle\Entity\Shop; use PSC\Shop\EntityBundle\Entity\Shop;
use PSC\Shop\EntityBundle\Repository\ShopRepository; use PSC\Shop\EntityBundle\Repository\ShopRepository;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class ShopProvider implements UserProviderInterface class ShopProvider implements UserProviderInterface
@ -42,7 +42,7 @@ class ShopProvider implements UserProviderInterface
if (null === $user) { if (null === $user) {
throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException(sprintf('Shop "%s" not found.', $identifier)); throw new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
} }
return $user; return $user;

View File

@ -4,9 +4,9 @@ namespace PSC\Shop\UserBundle\Security\User;
use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\ContactBundle\Repository\ContactRepository;
use PSC\Shop\EntityBundle\Entity\Contact; use PSC\Shop\EntityBundle\Entity\Contact;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class UserProvider implements UserProviderInterface class UserProvider implements UserProviderInterface
@ -42,12 +42,9 @@ class UserProvider implements UserProviderInterface
public function loadUserByIdentifier(string $identifier): UserInterface public function loadUserByIdentifier(string $identifier): UserInterface
{ {
$user = $this->repository->loadUserByUsername($identifier); $user = $this->repository->loadUserByUsername($identifier);
if (null === $user) { if (null === $user) {
throw new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException(sprintf('User "%s" not found.', $identifier));
} }
return $user; return $user;

View File

@ -59,9 +59,11 @@ class ZendAuthenticator extends AbstractAuthenticator
if ($contact) { if ($contact) {
return new SelfValidatingPassport( return new SelfValidatingPassport(
new UserBadge($contactUuid, function () use ($contact) { new UserBadge(
return $contact; $contactUuid, function () use ($contact) {
}) return $contact;
}
)
); );
} }

View File

@ -20,9 +20,11 @@ class PluginCompiler implements CompilerPassInterface
try { try {
$collection = (new \MongoDB\Client('mongodb://mongodb/'))->psc->Plugin; $collection = (new \MongoDB\Client('mongodb://mongodb/'))->psc->Plugin;
$plugins = $collection->find(array('installed' => true)); $plugins = $collection->find(array('installed' => true));
/** @var Plugin $plugin */ /**
* @var Plugin $plugin
*/
foreach ($plugins as $plugin) { foreach ($plugins as $plugin) {
$container->get('doctrine_mongodb.odm.metadata.chain')->addDriver(new AnnotationDriver(new AnnotationReader(), $container->getParameter('kernel.project_dir') . '/var/plugins/' . $plugin['path'] . '/Document'), $plugin['path']); $container->get('doctrine_mongodb.odm.default_metadata_driver')->addDriver(new AnnotationDriver(new AnnotationReader(), $container->getParameter('kernel.project_dir') . '/var/plugins/' . $plugin['path'] . '/Document'), $plugin['path']);
} }
} catch (\Exception $e) { } catch (\Exception $e) {
var_dump($e->getMessage()); var_dump($e->getMessage());

View File

@ -0,0 +1,26 @@
<?php
namespace PSC\System\PluginBundle\Event;
use PSC\Shop\QueueBundle\Event\Event;
class EveryDay extends Event
{
public function getType(): string
{
return 'system_plugin_every_day';
}
public function getDescription(): string
{
return 'einmal am Tag';
}
public function getData(): void
{
}
public function setData($data): void
{
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PSC\System\PluginBundle\Event;
use PSC\Shop\QueueBundle\Event\Event;
class EveryHour extends Event
{
public function getType(): string
{
return 'system_plugin_every_hour';
}
public function getDescription(): string
{
return 'jede Stunde';
}
public function getData(): void
{
}
public function setData($data): void
{
}
}

View File

@ -13,7 +13,7 @@ class EveryRun extends Event
public function getDescription() public function getDescription()
{ {
return 'Bei jeder Ausführung'; return 'jede Minute';
} }
public function getData() public function getData()

View File

@ -41,6 +41,17 @@ services:
tags: tags:
- { name: events } - { name: events }
psc.system.plugin.event.every.day:
class: PSC\System\PluginBundle\Event\EveryDay
tags:
- { name: events }
psc.system.plugin.event.every.hour:
class: PSC\System\PluginBundle\Event\EveryHour
tags:
- { name: events }
psc.system.plugin.manager: psc.system.plugin.manager:
class: PSC\System\PluginBundle\Service\Manager class: PSC\System\PluginBundle\Service\Manager
public: true public: true
@ -51,4 +62,4 @@ services:
public: false public: false
arguments: ['%kernel.project_dir%'] arguments: ['%kernel.project_dir%']
tags: tags:
- { name: routing.loader } - { name: routing.loader }

View File

@ -97,15 +97,6 @@
"doctrine/sql-formatter": { "doctrine/sql-formatter": {
"version": "1.2.x-dev" "version": "1.2.x-dev"
}, },
"dunglas/doctrine-json-odm": {
"version": "1.4",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "0.1",
"ref": "c2ab78f625df0c89af5908d50a28602ff8c4919f"
}
},
"egulias/email-validator": { "egulias/email-validator": {
"version": "2.1.18" "version": "2.1.18"
}, },
@ -248,9 +239,6 @@
"myclabs/deep-copy": { "myclabs/deep-copy": {
"version": "1.9.5" "version": "1.9.5"
}, },
"namshi/jose": {
"version": "7.2.3"
},
"nelmio/alice": { "nelmio/alice": {
"version": "3.12", "version": "3.12",
"recipe": { "recipe": {
@ -937,15 +925,6 @@
"config/routes/ux_live_component.yaml" "config/routes/ux_live_component.yaml"
] ]
}, },
"symfony/ux-turbo": {
"version": "2.24",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.19",
"ref": "9dd2778a116b6e5e01e5e1582d03d5a9e82630de"
}
},
"symfony/ux-twig-component": { "symfony/ux-twig-component": {
"version": "v2.12.0" "version": "v2.12.0"
}, },

View File

@ -20,22 +20,6 @@
</head> </head>
<body class="min-h-screen bg-slate-100 text-gray-900 overflow-y-auto dark:text-gray-100 dark:bg-gray-900 antialiased"> <body class="min-h-screen bg-slate-100 text-gray-900 overflow-y-auto dark:text-gray-100 dark:bg-gray-900 antialiased">
<div
data-controller="modal"
data-action="turbo:before-cache@window->modal#close"
>
<dialog
class="open:flex bg-gray-800 rounded-lg shadow-xl inset-0 w-full md:w-fit md:max-w-[50%] md:min-w-[50%] animate-fade-in backdrop:bg-slate-600 backdrop:opacity-80"
data-modal-target="dialog"
data-action="close->modal#close click->modal#clickOutside"
>
<div class="flex grow p-5">
<div class="grow overflow-auto p-1">
<turbo-frame id="modal" data-modal-target="dynamicContent"></turbo-frame>
</div>
</div>
</dialog>
</div>
<div class="flex h-full w-full overflow-x-clip"> <div class="flex h-full w-full overflow-x-clip">
<div x-data x-show="$store.sideBar.isOpen" x-transition.opacity.500ms="" @click="$store.sideBar.close()" class="fixed inset-0 z-20 w-full h-full bg-gray-900/50 lg:hidden"></div> <div x-data x-show="$store.sideBar.isOpen" x-transition.opacity.500ms="" @click="$store.sideBar.close()" class="fixed inset-0 z-20 w-full h-full bg-gray-900/50 lg:hidden"></div>
<aside x-data :class="$store.sideBar.isOpen ? 'translate-x-0 max-w-[20em] shadow-2xl lg:max-w-[var(--sidebar-width)]' : '-translate-x-full lg:translate-x-0 lg:max-w-[var(--collapsed-sidebar-width)] lg:shadow-2xl rtl:lg:-translate-x-0 rtl:translate-x-full'" class="fixed inset-y-0 left-0 z-20 flex h-screen flex-col overflow-hidden w-[var(--sidebar-width)] bg-white transition-all rtl:left-auto rtl:right-0 lg:z-0 lg:border-r rtl:lg:border-l rtl:lg:border-r-0 dark:bg-gray-800 dark:border-gray-700 -translate-x-full lg:translate-x-0 lg:shadow-2xl rtl:lg:-translate-x-0 rtl:translate-x-full"> <aside x-data :class="$store.sideBar.isOpen ? 'translate-x-0 max-w-[20em] shadow-2xl lg:max-w-[var(--sidebar-width)]' : '-translate-x-full lg:translate-x-0 lg:max-w-[var(--collapsed-sidebar-width)] lg:shadow-2xl rtl:lg:-translate-x-0 rtl:translate-x-full'" class="fixed inset-y-0 left-0 z-20 flex h-screen flex-col overflow-hidden w-[var(--sidebar-width)] bg-white transition-all rtl:left-auto rtl:right-0 lg:z-0 lg:border-r rtl:lg:border-l rtl:lg:border-r-0 dark:bg-gray-800 dark:border-gray-700 -translate-x-full lg:translate-x-0 lg:shadow-2xl rtl:lg:-translate-x-0 rtl:translate-x-full">

View File

@ -1,3 +1,28 @@
<turbo-frame id="modal"> <!DOCTYPE html>
{% block body %}{% endblock %} <html lang="de-DE">
</turbo-frame> <head>
<meta charset="utf-8">
<title>PSC Admin</title>
<meta name="description" content="">
<meta name="author" content="">
<base href="{{ app.request.getBaseURL() }}/"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script>
var jwt_token = '{{tokenService.generateToken()}}';
</script>
{% block stylesheets %}
{% endblock %}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="apple-touch-icon" sizes="57x57" href="/apps/icons/apple-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="/apps/icons/apple-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="/apps/icons/apple-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="/apps/icons/apple-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="/apps/icons/apple-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="/apps/icons/apple-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="/apps/icons/apps/icons/apple-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="/apps/icons/apple-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="/apps/icons/apple-icon-180x180.png"><link rel="icon" type="image/png" sizes="192x192" href="/apps/icons/android-icon-192x192.png"><link rel="icon" type="image/png" sizes="32x32" href="/apps/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="96x96" href="/apps/icons/favicon-96x96.png"><link rel="icon" type="image/png" sizes="16x16" href="/apps/icons/favicon-16x16.png"><link rel="manifest" href="/apps/icons/manifest.json"><meta name="msapplication-TileColor" content="#ffffff"><meta name="msapplication-TileImage" content="/apps/icons/ms-icon-144x144.png"><meta name="theme-color" content="#ffffff">
</head>
<body class="min-h-screen bg-slate-100 text-gray-900 overflow-y-auto dark:text-gray-100 dark:bg-gray-900 antialiased">
{% block body %}{% endblock %}
{% block javascripts %}
{% endblock %}
{% block importmap %}{{ importmap('backend/tailwind') }}{% endblock %}
</body>
</html>

View File

@ -3,7 +3,8 @@ namespace Plugin\Custom\PSC\Printess\Transformer;
use PSC\Shop\ContactBundle\Model\Contact; use PSC\Shop\ContactBundle\Model\Contact;
class ContactArray { class ContactArray
{
public function transformContactToArray(Contact $contact): array public function transformContactToArray(Contact $contact): array
{ {
@ -73,6 +74,9 @@ class ContactArray {
], [ ], [
'name' => 'contact0abteilung', 'name' => 'contact0abteilung',
'value' => $contact->getLayouterData()->getAbteilung() 'value' => $contact->getLayouterData()->getAbteilung()
], [
'name' => 'contact0district',
'value' => $contact->getLayouterData()->getDistrict()
], [ ], [
'name' => 'contact0function', 'name' => 'contact0function',
'value' => $contact->getLayouterData()->getFunction() 'value' => $contact->getLayouterData()->getFunction()
@ -162,4 +166,4 @@ class ContactArray {
'value' => $contact->getCustom24() 'value' => $contact->getCustom24()
]]; ]];
} }
} }

View File

@ -20,7 +20,7 @@ class OrderController extends AbstractController
GetState $getStateService, GetState $getStateService,
Shop $shopService Shop $shopService
) { ) {
if($order->getUuid() != "") { if($order && $order->getUuid() != "") {
$orderModel = $orderService->getOrderByUuid($order->getUuid()); $orderModel = $orderService->getOrderByUuid($order->getUuid());
$positions = []; $positions = [];

View File

@ -126,7 +126,6 @@ class SaxoprintController extends AbstractController
$putConfig->setConfig($reqConfig); $putConfig->setConfig($reqConfig);
$config = $putConfig->call(); $config = $putConfig->call();
} }
$getPrices->setShop($shop->getMongoShopByUid($product->getShop()->getUid())); $getPrices->setShop($shop->getMongoShopByUid($product->getShop()->getUid()));
$getPrices->setProductId((int)$request->get('saxoprintProductId')); $getPrices->setProductId((int)$request->get('saxoprintProductId'));

View File

@ -6,6 +6,8 @@ use PSC\Library\Calc\Article;
class GetPrices extends Base class GetPrices extends Base
{ {
public array $json = [];
public function getPrices(Article $article): array public function getPrices(Article $article): array
{ {
@ -23,6 +25,12 @@ class GetPrices extends Base
$domain = $this->stagingUrl; $domain = $this->stagingUrl;
} }
$this->json = [
"attributes" => $attributes,
"quantity" => $article->getOptionById('auflage')->getRawValue(),
"productId" => $article->getOptionById('productId')->getValue(),
];
$response = $this->client->request( $response = $this->client->request(
'POST', 'POST',
@ -34,12 +42,7 @@ class GetPrices extends Base
"json" => [ "json" => [
"items" => [ "items" => [
[ [
"product" => [ "product" => $this->json ]
"attributes" => $attributes,
"quantity" => $article->getOptionById('auflage')->getRawValue(),
"productId" => $article->getOptionById('productId')->getValue(),
]
]
] ]
], ],
] ]

View File

@ -17,7 +17,7 @@ class OrderController extends AbstractController
GetState $getStateService, GetState $getStateService,
Shop $shopService Shop $shopService
) { ) {
if($order->getUuid() != "") { if($order && $order->getUuid() != "") {
$orderModel = $orderService->getOrderByUuid($order->getUuid()); $orderModel = $orderService->getOrderByUuid($order->getUuid());
$positions = []; $positions = [];

View File

@ -0,0 +1,48 @@
<?php
namespace Plugin\Custom\PSC\WMD_API\Document\Queue;
use Doctrine\ODM\MongoDB\Mapping\Annotations\EmbeddedDocument;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Field;
#[EmbeddedDocument]
class Check
{
#[Field(type: 'string')]
protected $from;
#[Field(type: 'string')]
protected $bcc;
#[Field(type: 'string')]
protected $to;
public function getFrom(): string
{
return $this->from;
}
public function getTo(): string
{
return $this->to;
}
public function getBcc(): string
{
return (string)$this->bcc;
}
public function setFrom(string $from): void
{
$this->from = $from;
}
public function setTo(string $to): void
{
$this->to = $to;
}
public function setBcc(string $bcc): void
{
$this->bcc = $bcc;
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace Plugin\Custom\PSC\WMD_API\Queue;
use Doctrine\ODM\MongoDB\DocumentManager;
use PSC\Shop\QueueBundle\Type\ConfigurableElementInterface;
use PSC\Library\Calc\Engine;
use PSC\Shop\EntityBundle\Document\Queue;
use PSC\Shop\EntityBundle\Repository\ProductRepository;
use PSC\Shop\QueueBundle\Event\EventInterface;
use PSC\Shop\QueueBundle\Type\QueueInterface;
use PSC\System\SettingsBundle\Service\Shop;
use Plugin\Custom\PSC\WMD_API\Api\GetPrices;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
#[AutoconfigureTag("queues")]
class Check implements QueueInterface, ConfigurableElementInterface
{
public function __construct(private ProductRepository $productRepository,
private Shop $shopService,
private DocumentManager $documentManager,
private GetPrices $pricesApi,
private MailerInterface $mailerService
) {
}
public function getType(): string
{
return 'custom_psc_wmd_check';
}
public function getDescription(): string
{
return 'Exportiert ein Auftrag nach Wir Machen Druck';
}
public function getGroup(): string
{
return 'Allgemeines';
}
public function getName(): string
{
return 'Reseller Products (WMD) Check';
}
public function injectDocument(Form $form, EventInterface $event, Queue $doc)
{
$check = new \Plugin\Custom\PSC\WMD_API\Document\Queue\Check();
$check->setTo($form->get('to')->getData());
$check->setFrom($form->get('from')->getData());
$check->setBcc($form->get('bcc')->getData());
$doc->setQueueDocument($check);
}
public function setFormData(Form $form, EventInterface $event, Queue $doc)
{
if($doc->getQueueDocument() === null) {
return;
}
$form->get('from')->setData($doc->getQueueDocument()->getFrom());
$form->get('bcc')->setData($doc->getQueueDocument()->getBcc());
$form->get('to')->setData($doc->getQueueDocument()->getTo());
}
public function execute(EventInterface $event, Queue $doc)
{
try {
$shop = $this->shopService->getShopByUid($doc->getShop());
$mongoShop = $this->shopService->getMongoShopByUid($shop->getUID());
set_time_limit(0);
$products = $this->productRepository->findBy(['type' => 101, 'enable' => true, 'shop' => $doc->getShop()]);
$engine = new Engine();
$this->pricesApi->setShop($mongoShop);
$doc = $doc->getQueueDocument();
foreach($products as $product) {
$productDoc = $this->documentManager->getRepository(\PSC\Shop\EntityBundle\Document\Product::class)->findOneBy(['uid' => $product->getUid()]);
$engine->loadString($productDoc->getPluginSettingModule('wmd', 'config'));
$engine->calc();
try {
$pricesArray = $this->pricesApi->getPrices($engine->getArticle());
} catch (\Throwable $th) {
$message = (new Email())
->subject('WMD Api Product Fehler')
->from($doc->getFrom())
->to($doc->getTo())
->html(sprintf('%s: %s (%s)<br/>%s<br/>%s', 'Fehler im Product: ', $product->getTitle(), $product->getUid(), $th->getMessage(), json_encode($this->pricesApi->json)));
$bccArray = explode(",", $doc->getBcc());
foreach ($bccArray as $bc) {
if (trim($bc) != "") {
$message->addBcc(trim($bc));
}
}
$this->mailerService->send($message);
continue;
}
}
} catch (\Throwable $th) {
var_dump($th->getMessage());
return false;
}
}
public function getError()
{
}
public function setForm(Form $form)
{
}
public function getForm(FormBuilderInterface $builder, $form_options, EventInterface $event)
{
$builder->add("from", TextType::class, array('label' => 'From', 'attr' => array('class' => 'form-element')));
$builder->add("to", TextType::class, array('label' => 'to', 'attr' => array('class' => 'form-element')));
$builder->add("bcc", TextType::class, array('label' => 'bcc', 'attr' => array('class' => 'form-element')));
}
public function getTemplate()
{
return '@PluginCustomPSCWMD_API/queue/check.html.twig';
}
}

View File

@ -0,0 +1,27 @@
<div class="panel">
<div class="header">
<h4>Check</h4>
</div>
<div class="body">
<div class="row">
<div class="col-md-4">
<div class="form-group row">
<label class="col-md-5 form-control-label">{{ form_label(form.from) }}</label>
<div class="col-md-7">{{ form_widget(form.from, {attr: {'class': 'form-control' }}) }}</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group row">
<label class="col-md-5 form-control-label">{{ form_label(form.to) }}</label>
<div class="col-md-7">{{ form_widget(form.to, {attr: {'class': 'form-control' }}) }}</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group row">
<label class="col-md-5 form-control-label">{{ form_label(form.bcc) }}</label>
<div class="col-md-7">{{ form_widget(form.bcc, {attr: {'class': 'form-control' }}) }}</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -15,7 +15,9 @@ class Startseite implements Field
private $_entityManager; private $_entityManager;
/** @var \PSC\System\SettingsBundle\Service\Shop */ /**
* @var \PSC\System\SettingsBundle\Service\Shop
*/
private $_shopService; private $_shopService;
private $options; private $options;
@ -41,14 +43,16 @@ class Startseite implements Field
{ {
$this->options = $options; $this->options = $options;
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$products = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1)); $products = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1));
$tmp = []; $tmp = [];
foreach ($products as $product) { foreach ($products as $product) {
$tmp[$product->getTitle() . " (" . $product->getUid() . ")"] = $product->getUid(); $tmp[$product->getNrTitle()] = $product->getUid();
} }
$productGroups = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1)); $productGroups = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1));
@ -58,15 +62,18 @@ class Startseite implements Field
$tmpGroups[$productGroup->getTitle() . " (" . $productGroup->getUid() . ")"] = $productGroup->getUid(); $tmpGroups[$productGroup->getTitle() . " (" . $productGroup->getUid() . ")"] = $productGroup->getUid();
} }
$builder->add('mode', ChoiceType::class, [ $builder->add(
'mode', ChoiceType::class, [
'required' => false, 'required' => false,
'label' => 'Startpage', 'label' => 'Startpage',
'choices' => [ 'choices' => [
'Willkommensseite' => "index", 'Willkommensseite' => "index",
'Slider + Produktliste o. Produktgruppen ohne Seitennavi' => "sliderproductsnosidenav", 'Slider + Produktliste o. Produktgruppen ohne Seitennavi' => "sliderproductsnosidenav",
] ]
]) ]
->add('slider_interval', ChoiceType::class, [ )
->add(
'slider_interval', ChoiceType::class, [
'required' => false, 'required' => false,
'label' => 'Sliderspeed', 'label' => 'Sliderspeed',
'choices' => [ 'choices' => [
@ -74,23 +81,30 @@ class Startseite implements Field
'normal' => "4000", 'normal' => "4000",
'fast' => "2000", 'fast' => "2000",
] ]
]) ]
->add('mc_start_products', ChoiceType::class, array( )
->add(
'mc_start_products', ChoiceType::class, array(
'choices' => $tmp, 'choices' => $tmp,
'multiple' => true, 'multiple' => true,
'required' => false, 'required' => false,
'label' => 'Product', 'label' => 'Product',
)) )
->add('mc_start_productgroups', ChoiceType::class, array( )
->add(
'mc_start_productgroups', ChoiceType::class, array(
'choices' => $tmpGroups, 'choices' => $tmpGroups,
'multiple' => true, 'multiple' => true,
'required' => false, 'required' => false,
'label' => 'Productgroups', 'label' => 'Productgroups',
)) )
->add('index_slogan', TextareaType::class, array( )
->add(
'index_slogan', TextareaType::class, array(
'label' => 'Slogen', 'label' => 'Slogen',
'required' => false 'required' => false
)); )
);
return $builder; return $builder;
} }
@ -103,7 +117,9 @@ class Startseite implements Field
public function formPostSetData(FormEvent $event) public function formPostSetData(FormEvent $event)
{ {
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$layoutSettings = json_decode($shopEntity->getLayoutSettings(), true); $layoutSettings = json_decode($shopEntity->getLayoutSettings(), true);
@ -114,7 +130,9 @@ class Startseite implements Field
} }
if (strtolower($shopEntity->getDefaultFunc()) == "index") { if (strtolower($shopEntity->getDefaultFunc()) == "index") {
/** @var Shopsetting $setting */ /**
* @var Shopsetting $setting
*/
$setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout")); $setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout"));
if ($setting) { if ($setting) {
$event->getForm()->get('bootstrap3Startseite')->get('mode')->setData($setting->getValue()); $event->getForm()->get('bootstrap3Startseite')->get('mode')->setData($setting->getValue());
@ -134,12 +152,16 @@ class Startseite implements Field
public function formPostSubmit(FormEvent $event) public function formPostSubmit(FormEvent $event)
{ {
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$layoutSettings = json_decode($shopEntity->getLayoutSettings(), true); $layoutSettings = json_decode($shopEntity->getLayoutSettings(), true);
$layoutSettings[$shopEntity->getLayout()]['slider_interval'] = $event->getForm()->get('bootstrap3Startseite')->get('slider_interval')->getData(); $layoutSettings[$shopEntity->getLayout()]['slider_interval'] = $event->getForm()->get('bootstrap3Startseite')->get('slider_interval')->getData();
/** @var Shopsetting $setting */ /**
* @var Shopsetting $setting
*/
$setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout")); $setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout"));
if ($setting) { if ($setting) {
$setting->setValue($event->getForm()->get('bootstrap3Startseite')->get('mode')->getData()); $setting->setValue($event->getForm()->get('bootstrap3Startseite')->get('mode')->getData());

View File

@ -15,7 +15,9 @@ class Startseite implements Field
private $_entityManager; private $_entityManager;
/** @var \PSC\System\SettingsBundle\Service\Shop */ /**
* @var \PSC\System\SettingsBundle\Service\Shop
*/
private $_shopService; private $_shopService;
private $options; private $options;
@ -41,14 +43,16 @@ class Startseite implements Field
{ {
$this->options = $options; $this->options = $options;
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$products = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1)); $products = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1));
$tmp = []; $tmp = [];
foreach ($products as $product) { foreach ($products as $product) {
$tmp[$product->getTitle() . " (" . $product->getUid() . ")"] = $product->getUid(); $tmp[$product->getNrTitle()] = $product->getUid();
} }
$productGroups = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1)); $productGroups = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "enable" => 1));
@ -58,15 +62,18 @@ class Startseite implements Field
$tmpGroups[$productGroup->getTitle() . " (" . $productGroup->getUid() . ")"] = $productGroup->getUid(); $tmpGroups[$productGroup->getTitle() . " (" . $productGroup->getUid() . ")"] = $productGroup->getUid();
} }
$builder->add('mode', ChoiceType::class, [ $builder->add(
'mode', ChoiceType::class, [
'required' => false, 'required' => false,
'label' => 'Startseite', 'label' => 'Startseite',
'choices' => [ 'choices' => [
'Willkommensseite' => "index", 'Willkommensseite' => "index",
'Slider + Produktliste o. Produktgruppen ohne Seitennavi' => "sliderproductsnosidenav", 'Slider + Produktliste o. Produktgruppen ohne Seitennavi' => "sliderproductsnosidenav",
] ]
]) ]
->add('slider_interval', ChoiceType::class, [ )
->add(
'slider_interval', ChoiceType::class, [
'required' => false, 'required' => false,
'label' => 'Slidergeschwindigkeit', 'label' => 'Slidergeschwindigkeit',
'choices' => [ 'choices' => [
@ -74,23 +81,30 @@ class Startseite implements Field
'Normal' => "4000", 'Normal' => "4000",
'Schnell' => "2000", 'Schnell' => "2000",
] ]
]) ]
->add('mc_start_products', ChoiceType::class, array( )
->add(
'mc_start_products', ChoiceType::class, array(
'choices' => $tmp, 'choices' => $tmp,
'multiple' => true, 'multiple' => true,
'required' => false, 'required' => false,
'label' => 'Produkte', 'label' => 'Produkte',
)) )
->add('mc_start_productgroups', ChoiceType::class, array( )
->add(
'mc_start_productgroups', ChoiceType::class, array(
'choices' => $tmpGroups, 'choices' => $tmpGroups,
'multiple' => true, 'multiple' => true,
'required' => false, 'required' => false,
'label' => 'Produktgruppen', 'label' => 'Produktgruppen',
)) )
->add('index_slogan', TextareaType::class, array( )
->add(
'index_slogan', TextareaType::class, array(
'label' => 'Slogen', 'label' => 'Slogen',
'required' => false 'required' => false
)); )
);
return $builder; return $builder;
} }
@ -103,7 +117,9 @@ class Startseite implements Field
public function formPostSetData(FormEvent $event) public function formPostSetData(FormEvent $event)
{ {
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$layoutSettings = json_decode($shopEntity->getLayoutSettings(), true); $layoutSettings = json_decode($shopEntity->getLayoutSettings(), true);
@ -112,7 +128,9 @@ class Startseite implements Field
$event->getForm()->get('bootstrap4Startseite')->get('slider_interval')->setData($layoutSettings[$shopEntity->getLayout()]['slider_interval']); $event->getForm()->get('bootstrap4Startseite')->get('slider_interval')->setData($layoutSettings[$shopEntity->getLayout()]['slider_interval']);
if (strtolower($shopEntity->getDefaultFunc()) == "index") { if (strtolower($shopEntity->getDefaultFunc()) == "index") {
/** @var Shopsetting $setting */ /**
* @var Shopsetting $setting
*/
$setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout")); $setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout"));
if ($setting) { if ($setting) {
$event->getForm()->get('bootstrap4Startseite')->get('mode')->setData($setting->getValue()); $event->getForm()->get('bootstrap4Startseite')->get('mode')->setData($setting->getValue());
@ -128,12 +146,16 @@ class Startseite implements Field
public function formPostSubmit(FormEvent $event) public function formPostSubmit(FormEvent $event)
{ {
/** @var Shop $shopEntity */ /**
* @var Shop $shopEntity
*/
$shopEntity = $this->options['shopEntity']; $shopEntity = $this->options['shopEntity'];
$layoutSettings = json_decode($shopEntity->getLayoutSettings(), true); $layoutSettings = json_decode($shopEntity->getLayoutSettings(), true);
$layoutSettings[$shopEntity->getLayout()]['slider_interval'] = $event->getForm()->get('bootstrap4Startseite')->get('slider_interval')->getData(); $layoutSettings[$shopEntity->getLayout()]['slider_interval'] = $event->getForm()->get('bootstrap4Startseite')->get('slider_interval')->getData();
/** @var Shopsetting $setting */ /**
* @var Shopsetting $setting
*/
$setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout")); $setting = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $this->_shopService->getSelectedShop()->getUid(), "key" => "index_index_layout"));
if ($setting) { if ($setting) {
$setting->setValue($event->getForm()->get('bootstrap4Startseite')->get('mode')->getData()); $setting->setValue($event->getForm()->get('bootstrap4Startseite')->get('mode')->getData());

View File

@ -104,7 +104,9 @@ class GetPrice extends AbstractController
$output = new \Plugin\System\PSC\XmlCalc\Dto\Output\PriceOutput(); $output = new \Plugin\System\PSC\XmlCalc\Dto\Output\PriceOutput();
$output->product = $data->product; $output->product = $data->product;
/** @var Product $product */ /**
* @var Product $product
*/
$product = $this->entityManager $product = $this->entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findOneBy(['uuid' => $data->product]); ->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findOneBy(['uuid' => $data->product]);
@ -158,7 +160,9 @@ class GetPrice extends AbstractController
$output->xmlProductTypes[] = $article->getName(); $output->xmlProductTypes[] = $article->getName();
} }
/** @var Base $option */ /**
* @var Base $option
*/
foreach ($engine->getArticle()->getOptions() as $option) { foreach ($engine->getArticle()->getOptions() as $option) {
$tmp = new Element(); $tmp = new Element();
$tmp->name = $option->getName(); $tmp->name = $option->getName();
@ -180,7 +184,9 @@ class GetPrice extends AbstractController
$tmp->displayGroup = $option->getDisplayGroup(); $tmp->displayGroup = $option->getDisplayGroup();
if ($option->type == 'select' || $option->type == 'checkbox' || $option->type == 'radio') { if ($option->type == 'select' || $option->type == 'checkbox' || $option->type == 'radio') {
/** @var Opt $option */ /**
* @var Opt $option
*/
if ($option instanceof ColorDBSelect) { if ($option instanceof ColorDBSelect) {
$tmp->colorSystem = $option->getColorSystem(); $tmp->colorSystem = $option->getColorSystem();
if (!isset($output->colorDb[$option->getColorSystem()])) { if (!isset($output->colorDb[$option->getColorSystem()])) {
@ -243,6 +249,8 @@ class GetPrice extends AbstractController
foreach ($group->getVariants() as $variant) { foreach ($group->getVariants() as $variant) {
$variantObj = new Variant(); $variantObj = new Variant();
$variantObj->name = $variant->getName(); $variantObj->name = $variant->getName();
$variantObj->text = $variant->getText();
$variantObj->data = $variant->getData();
foreach ($variant->getValues() as $value) { foreach ($variant->getValues() as $value) {
$valueObj = new Value(); $valueObj = new Value();
$valueObj->key = $value->getKey(); $valueObj->key = $value->getKey();

View File

@ -15,6 +15,21 @@ class Variant
*/ */
public string $name; public string $name;
/**
* @var string
*
* @OA\Property(type="string")
*/
public string $text;
/**
* @var string
*
* @OA\Property(type="string")
*/
public string $data;
/** /**
* @var Variant[] options * @var Variant[] options
* *

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,8 @@ abstract class BaseNews extends Doctrine_Record
'length' => '25', 'length' => '25',
)); ));
$this->hasColumn('sort_date', 'date', 25); $this->hasColumn('sort_date', 'date', 25);
$this->hasColumn('from_date', 'datetime', 25);
$this->hasColumn('to_date', 'datetime', 25);
$this->hasColumn('updated', 'timestamp', 25, array( $this->hasColumn('updated', 'timestamp', 25, array(
'type' => 'timestamp', 'type' => 'timestamp',
'length' => '25', 'length' => '25',
@ -84,4 +86,4 @@ abstract class BaseNews extends Doctrine_Record
$sluggable0 = new Doctrine_Template_Sluggable (array('unique' => true, 'fields' => array(0 => 'title'), 'name' => 'url', 'canUpdate' => true)); $sluggable0 = new Doctrine_Template_Sluggable (array('unique' => true, 'fields' => array(0 => 'title'), 'name' => 'url', 'canUpdate' => true));
$this->actAs($sluggable0); $this->actAs($sluggable0);
} }
} }

View File

@ -25,13 +25,13 @@ $filesOptions = $this->article['basketarticle']->getFiles();
<strong><?php echo $this->layouter()->getTitle($this->article['basketarticle']->getLayouterId()); ?></strong><br /> <strong><?php echo $this->layouter()->getTitle($this->article['basketarticle']->getLayouterId()); ?></strong><br />
<?php endif; ?> <?php endif; ?>
<?php if(($this->article['options'])): ?> <?php if(($this->article['options'])): ?>
<ul id="options_<?= $basketArticle['uuid'] ?>"> <ul id="options_<?= $this->article['uuid'] ?>">
<li>Lade Optionen</li> <li>Lade Optionen</li>
</ul> </ul>
<script> <script>
$(function () { $(function () {
loadDetails($("#options_<?= $basketArticle['uuid'] ?>"), '<?= json_encode(['test' => false, 'product' => $basketArticle['uuid'], 'values' => $this->article['basketarticle']->getOptions()]) ?>'); loadDetails($("#options_<?= $this->article['uuid'] ?>"), '<?= json_encode(['test' => false, 'product' => $basketArticle['uuid'], 'values' => $this->article['basketarticle']->getOptions()]) ?>');
}) })

View File

@ -396,9 +396,9 @@ if($linkend == "") { ?>
if(count($cms) > 0) /* wenn wir CMS einträge haben... */ if(count($cms) > 0) /* wenn wir CMS einträge haben... */
{ {
/* Text ausgeben */ /* Text ausgeben */
if(!$cms->getFirst()->notinmenu) if(!$cms[0]->notinmenu)
{ {
echo $cms->getFirst()->getText(); echo $cms[0]->getText();
} }
echo '<hr>'; echo '<hr>';

View File

@ -2670,6 +2670,10 @@ class ArticleController extends TP_Controller_Action
$this->_redirect('/basket/simple'); $this->_redirect('/basket/simple');
return; return;
} }
if (file_exists($this->_templatePath . '/basket/custom.phtml')) {
$this->_redirect('/basket/custom');
return;
}
$this->_redirect('/basket/index'); $this->_redirect('/basket/index');

View File

@ -209,7 +209,10 @@ class BasketController extends TP_Controller_Action
$this->redirectSpeak("/basket/simple"); $this->redirectSpeak("/basket/simple");
} }
public function customAction()
{
}
public function simpleAction() public function simpleAction()
{ {
@ -2239,7 +2242,6 @@ class BasketController extends TP_Controller_Action
$stockErrorCount = $article->stock_count; $stockErrorCount = $article->stock_count;
$this->view->stockError = true; $this->view->stockError = true;
} }
array_push( array_push(
$temp, array( $temp, array(
'uuid' => $uuid, 'uuid' => $uuid,
@ -3241,14 +3243,7 @@ class BasketController extends TP_Controller_Action
$this->view->delivery_address = Doctrine_Query::create()->select()->from('ContactAddress s')->where('s.contact_id = ? AND display = 1 AND s.uuid = ?', array($this->user->id, $basket->getDelivery()))->fetchOne(); $this->view->delivery_address = Doctrine_Query::create()->select()->from('ContactAddress s')->where('s.contact_id = ? AND display = 1 AND s.uuid = ?', array($this->user->id, $basket->getDelivery()))->fetchOne();
if ($basket->getSender() == 0 || $this->view->sender_address == null) { if ($basket->getSender() == 0 || $this->view->sender_address == null) {
$this->view->sender_address = $this->shop->getOrderSenderSavedAsObject();
$this->view->sender_address = Doctrine_Query::create()->select()->from('ContactAddress s')->where('s.contact_id = ? AND display = 1 AND s.type = ?', array($this->user->id, 3))->fetchOne();
if ($this->view->sender_address == null) {
$this->view->sender_address = $this->shop->getOrderSenderSavedAsObject();
} else {
$basket->setSender($this->view->sender_address->uuid);
$this->view->sender = $basket->getSender();
}
} }
$this->view->sender_address_shop = $this->shop->getOrderSenderSavedAsObject(); $this->view->sender_address_shop = $this->shop->getOrderSenderSavedAsObject();
if ($this->_getParam('basketfield1')) { if ($this->_getParam('basketfield1')) {

View File

@ -45,12 +45,11 @@ class NewsController extends TP_Controller_Action
$news = Doctrine_Query::create() $news = Doctrine_Query::create()
->from('News c') ->from('News c')
->where('c.shop_id = ? AND c.active = 1 AND (c.language = ? ->where('c.shop_id = ? AND c.active = 1 AND (c.from_date IS NULL OR c.from_date < ?) AND (c.to_date IS NULL or c.to_date > ?) AND (c.language = ?
OR c.language = \'all\')', OR c.language = \'all\')',
array($this->shop->id, Zend_Registry::get('locale'))) array($this->shop->id, date('Y-m-d H:i:s'), date('Y-m-d H:i:s'), Zend_Registry::get('locale')))
->orderBy('c.sort_date DESC') ->orderBy('c.sort_date DESC');
->execute(); $news = $news->execute();
$this->view->news = $news; $this->view->news = $news;
$this->_helper->layout->setLayout('default'); $this->_helper->layout->setLayout('default');
@ -60,7 +59,7 @@ class NewsController extends TP_Controller_Action
$news = Doctrine_Query::create() $news = Doctrine_Query::create()
->from('News c') ->from('News c')
->where('c.shop_id = ? AND c.active = 1 AND c.url = ?', ->where('c.shop_id = ? AND c.active = 1 AND (c.from_date IS NULL OR c.from_date < ?) AND (c.to_date IS NULL or c.to_date > ?) AND c.url = ?',
array($this->shop->id, $this->_getParam('url'))) array($this->shop->id, $this->_getParam('url')))
->fetchOne(); ->fetchOne();
@ -68,4 +67,4 @@ class NewsController extends TP_Controller_Action
$this->_helper->layout->setLayout('default'); $this->_helper->layout->setLayout('default');
} }
} }

View File

@ -89,13 +89,16 @@ class TP_Controller_Action extends Zend_Controller_Action
$this->view->shop = Doctrine_Query::create()->from('Shop s')->where('s.id = ?')->fetchOne(array( $this->view->shop = Doctrine_Query::create()->from('Shop s')->where('s.id = ?')->fetchOne(array(
$conf['id'])); $conf['id']));
if ($this->view->shop->template_switch && Zend_Auth::getInstance()->hasIdentity()) { if (Zend_Auth::getInstance()->hasIdentity()) {
$user = Zend_Auth::getInstance()->getIdentity(); $user = Zend_Auth::getInstance()->getIdentity();
$accountPath = $this->getAccountTemplatePath($user['account_id']); $accountPath = $this->getAccountTemplatePath($user['account_id']);
if ($accountPath != "") { if ($accountPath != "") {
$conf['layout'] = $accountPath; $conf['layout'] = $accountPath;
if(file_exists(APPLICATION_PATH . '/design/clients/' . $this->view->shop->uid . '/' . $accountPath)) {
Zend_Registry::set('layout_path', APPLICATION_PATH . '/design/clients/' . $this->view->shop->uid . '/' . $accountPath . ''); Zend_Registry::set('layout_path', APPLICATION_PATH . '/design/clients/' . $this->view->shop->uid . '/' . $accountPath . '');
}else{
Zend_Registry::set('layout_path', APPLICATION_PATH . '/design/vorlagen/' . $accountPath . '');
}
} }
} }

View File

@ -19,7 +19,6 @@ require_once('/data/www/new/vendor/mongodb/mongodb/src/Database.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/Collection.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/Collection.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/UpdateResult.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/UpdateResult.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/InsertOneResult.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/InsertOneResult.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/Executable.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/Explainable.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/Explainable.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/FindOne.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/FindOne.php');
require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/Find.php'); require_once('/data/www/new/vendor/mongodb/mongodb/src/Operation/Find.php');