This commit is contained in:
Thomas 2025-02-07 22:04:13 +01:00
parent 5eebc2647f
commit da58a4e824
672 changed files with 67933 additions and 33621 deletions

View File

@ -76,6 +76,16 @@ services:
- ServerOptions__HostName=smtp4dev - ServerOptions__HostName=smtp4dev
networks: networks:
- network - network
webhook:
image: ghcr.io/tarampampam/webhook-tester:2
restart: always
environment:
- AUTO_CREATE_SESSIONS=true
ports:
# Change the number before : to the port the IMAP server should be accessible on
- '5002:8080'
networks:
- network
application: application:
image: ${DOCKER_REGISTRY?}/${DOCKER_NAMESPACE?}/application-${ENV?}:${TAG?} image: ${DOCKER_REGISTRY?}/${DOCKER_NAMESPACE?}/application-${ENV?}:${TAG?}
build: build:

View File

@ -57,6 +57,7 @@ server {
rewrite ^(.*) /index.php last; rewrite ^(.*) /index.php last;
} }
location /apps/ { # Static files location /apps/ { # Static files
client_max_body_size 1024M; client_max_body_size 1024M;
root $frontRoot; root $frontRoot;

View File

@ -0,0 +1 @@
{"php_version":"8.3.6","fixer_version":"0ab7a8154f7b3a6a42cbe3a467074a47bc32dcf5","rules":{"TwigCsFixer\\Rules\\Delimiter\\DelimiterSpacingRule":{"skipIfNewLine":true},"TwigCsFixer\\Rules\\Function\\NamedArgumentSeparatorRule":null,"TwigCsFixer\\Rules\\Function\\NamedArgumentSpacingRule":null,"TwigCsFixer\\Rules\\Operator\\OperatorNameSpacingRule":null,"TwigCsFixer\\Rules\\Operator\\OperatorSpacingRule":null,"TwigCsFixer\\Rules\\Punctuation\\PunctuationSpacingRule":{"before":{")":0,"]":0,"}":0,":":0,".":0,",":0,"|":0,"?:":0},"after":{"(":0,"[":0,"{":0,".":0,"|":0,":":1,",":1,"?:":1}},"TwigCsFixer\\Rules\\Whitespace\\BlankEOFRule":null,"TwigCsFixer\\Rules\\Delimiter\\BlockNameSpacingRule":null,"TwigCsFixer\\Rules\\Whitespace\\EmptyLinesRule":null,"TwigCsFixer\\Rules\\String\\HashQuoteRule":{"useQuote":false},"TwigCsFixer\\Rules\\Function\\IncludeFunctionRule":null,"TwigCsFixer\\Rules\\Whitespace\\IndentRule":{"spaceRatio":4,"useTab":false},"TwigCsFixer\\Rules\\String\\SingleQuoteRule":{"skipStringContainingSingleQuote":true},"TwigCsFixer\\Rules\\Punctuation\\TrailingCommaMultiLineRule":{"comma":true},"TwigCsFixer\\Rules\\Punctuation\\TrailingCommaSingleLineRule":null,"TwigCsFixer\\Rules\\Whitespace\\TrailingSpaceRule":null},"hashes":{"src\/PSC\/Shop\/NewsBundle\/Resources\/views\/backend\/edit\/edit.html.twig":"5882ade1b4ccd43b9484902acd74352f"}}

View File

@ -34,7 +34,7 @@ window.psc = {};
window.psc.ajaxModal = new ajaxModal; window.psc.ajaxModal = new ajaxModal;
window.psc.mediaChooser = new mediaChooser; window.psc.mediaChooser = new mediaChooser;
window.psc.init = init; window.psc.init = init;
//window.psc.order = new order; window.psc.order = new order;
window.psc.product = new product; window.psc.product = new product;
window.psc.init(); window.psc.init();
@ -43,8 +43,22 @@ window.psc.init();
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import './less/base.scss'; import './less/base.scss';
import 'summernote/dist/summernote-lite.min.css'; import 'summernote/dist/summernote-lite.min.css';
import TomSelect from 'tom-select';
import '../../vendor/tom-select/dist/css/tom-select.bootstrap5.css';
$(function() { window.addEventListener('load', (event) => {
document.querySelectorAll('select[multiple]').forEach((el)=>{
let settings = {
plugins: {
dropdown_input: {},
remove_button:{
title:'Remove this item',
}
}
};
new TomSelect(el,settings);
});
$('[data-bs-toggle="tooltip"]').click(function(el) { $('[data-bs-toggle="tooltip"]').click(function(el) {
bs5Utils.Toast.show({ bs5Utils.Toast.show({

View File

@ -1,7 +1,7 @@
export function init() { export function init() {
window.psc.ajaxModal.init(); window.psc.ajaxModal.init();
psc.mediaChooser.init(); psc.mediaChooser.init();
// psc.order.init(); psc.order.init();
psc.product.init(); psc.product.init();
if (typeof bootstrapApp === 'function') { if (typeof bootstrapApp === 'function') {
bootstrapApp(); bootstrapApp();

View File

@ -55,7 +55,6 @@ const Order_List_Pos_Calc_Option = (elm) => `
export class order { export class order {
init() { init() {
this.load_status(); this.load_status();
this.bind_buttons(); this.bind_buttons();
} }

View File

@ -276,4 +276,4 @@ body > header > .header {
color:white !important; color:white !important;
} }
@import "toogle/toogle.less"; @import "toogle/toogle.scss";

View File

@ -5,9 +5,9 @@
"enabled": true, "enabled": true,
"fetch": "eager", "fetch": "eager",
"autoimport": { "autoimport": {
"tom-select/dist/css/tom-select.default.css": true, "tom-select/dist/css/tom-select.default.css": false,
"tom-select/dist/css/tom-select.bootstrap4.css": false, "tom-select/dist/css/tom-select.bootstrap4.css": false,
"tom-select/dist/css/tom-select.bootstrap5.css": true "tom-select/dist/css/tom-select.bootstrap5.css": false
} }
} }
}, },

View File

@ -0,0 +1,15 @@
import { Controller } from '@hotwired/stimulus';
import EnhancedEditor from '../lib/ckeditor.js';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
connect() {
this.editor = EnhancedEditor.create(this.element)
.then(editor => (this.editor = editor))
.catch(error => console.error(error));
}
disconnect() {
this.editor.destroy().catch(error => console.error(error));
}
}

107
src/new/assets/lib/ckeditor.js vendored Normal file
View File

@ -0,0 +1,107 @@
import {
Autoformat,
BlockQuote,
Bold,
Essentials,
Heading,
Image,
ImageCaption,
ImageStyle,
ImageToolbar,
ImageUpload,
ImageInsertUI,
Indent,
Italic,
Link,
List,
MediaEmbed,
Paragraph,
PasteFromOffice,
PictureEditing,
Table,
TableToolbar,
TextTransformation,
ClassicEditor
} from 'ckeditor5';
// If you need to import translations, here French translations
import coreTranslations from 'ckeditor5/translations/de.js';
import 'ckeditor5/dist/ckeditor5.min.css';
import Flmngr from "./flmngr/src/flmngr.js";
export default class EnhancedEditor extends ClassicEditor {}
EnhancedEditor.builtinPlugins = [Autoformat, Bold, Essentials, Italic, Link, Paragraph];
EnhancedEditor.defaultConfig = {
licenseKey: 'GPL',
plugins: [
Essentials,
Autoformat,
Bold,
Italic,
BlockQuote,
Heading,
Image,
ImageCaption,
ImageStyle,
ImageToolbar,
ImageUpload,
ImageInsertUI,
Indent,
Link,
List,
MediaEmbed,
Paragraph,
PasteFromOffice,
PictureEditing,
Table,
TableToolbar,
TextTransformation,
Flmngr,
],
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'link',
'bulletedList',
'numberedList',
'|',
'outdent',
'indent',
'|',
'uploadImage',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'|',
'upload',
'flmngr',
]
},
image: {
toolbar: [
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side',
'|',
'toggleImageCaption',
'imageTextAlternative',
'|',
'upload',
'flmngr',
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
},
translations: [coreTranslations],
};

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="20"
height="20"
viewBox="0 0 20 20"
>
<g
transform="translate(0,2)">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="m 3.7210133,2 h 5 l 1.9999997,3 h 8 L 16.609922,15 H 1.2099223 Z"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 816 B

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="20"
height="20"
viewBox="0 0 20 20"
>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1,16 H 16 V 1"
/>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 19,4 H 4 v 15"
/>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 15,16 7,8 4,11"
/>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
d="m 12,8 h 1 V 7 h -1 z"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="20"
height="20"
viewBox="0 0 20 20">
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.130856,2.2749367 7.546402,7.5464016"
/>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 10.849606,1.5561867 2.5844542,9.8213386"
/>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 10,2 V 19"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,158 @@
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModuleLoader = true;
}
if (typeof exports === 'object') {
module.exports = factory();
registeredInModuleLoader = true;
}
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
}(function () {
function extend () {
var i = 0;
var result = {};
for (; i < arguments.length; i++) {
var attributes = arguments[ i ];
for (var key in attributes) {
result[key] = attributes[key];
}
}
return result;
}
function init (converter) {
function api (key, value, attributes) {
var result;
if (typeof document === 'undefined') {
return;
}
// Write
if (arguments.length > 1) {
attributes = extend({
path: '/'
}, api.defaults, attributes);
if (typeof attributes.expires === 'number') {
var expires = new Date();
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
attributes.expires = expires;
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
result = JSON.stringify(value);
if (/^[\{\[]/.test(result)) {
value = result;
}
} catch (e) {}
if (!converter.write) {
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
} else {
value = converter.write(value, key);
}
key = encodeURIComponent(String(key));
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
key = key.replace(/[\(\)]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += '=' + attributes[attributeName];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
// Read
if (!key) {
result = {};
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling "get()"
var cookies = document.cookie ? document.cookie.split('; ') : [];
var rdecode = /(%[0-9A-Z]{2})+/g;
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
if (!this.json && cookie.charAt(0) === '"') {
cookie = cookie.slice(1, -1);
}
try {
var name = parts[0].replace(rdecode, decodeURIComponent);
cookie = converter.read ?
converter.read(cookie, name) : converter(cookie, name) ||
cookie.replace(rdecode, decodeURIComponent);
if (this.json) {
try {
cookie = JSON.parse(cookie);
} catch (e) {}
}
if (key === name) {
result = cookie;
break;
}
if (!key) {
result[name] = cookie;
}
} catch (e) {}
}
return result;
}
api.set = api;
api.get = function (key) {
return api.call(api, key);
};
api.getJSON = function () {
return api.apply({
json: true
}, [].slice.call(arguments));
};
api.defaults = {};
api.remove = function (key, attributes) {
api(key, '', extend(attributes, {
expires: -1
}));
};
api.withConverter = init;
return api;
}
return init(function () {});
}));

View File

@ -0,0 +1,160 @@
import { Plugin, Notification, ButtonView } from 'ckeditor5';
import * as Cookies from "./cookie.js";
//import UploadIcon from "../icons/upload.svg";
import FlmngrCommand from "./flmngrcommand.js";
import UploadCommand from "./uploadcommand.js";
export default class Flmngr extends Plugin {
listenersFlmngrIsReady = [];
static get pluginName() {
return 'Flmngr';
}
static get requires() {
return [
Notification,
//'Image',
// Default Drupal 9 CKEditor 5 will fail to attach Flmngr if these lines are not commented
// due to Link/LinkEditing plugins are not enabled until user adds Link button onto toolbar.
// So these two plugins are optional dependency for Flmngr, it can work without them.
//
// 'Link',
// 'LinkEditing',
];
}
setFlmngr(flmngr) {
const options = this.editor.config.get('flmngr') || this.editor.config.get('Flmngr') || {};
options.integration = options["integration"] || "ckeditor5";
options.integrationType = "flmngr";
let flmngrInstance = flmngr.create(options);
FlmngrCommand.flmngr = flmngrInstance;
let apiLegacy = flmngrInstance; // flmngr
// New API exists only in Flmngr v2
let apiNew = !!apiLegacy.getNewAPI && apiLegacy.getNewAPI(); // Flmngr but without isFlmngrReady & isImgPenReady
this.editor["getFlmngr"] = (onFlmngrIsReady) => {
onFlmngrIsReady(apiNew, apiLegacy); // new way to receive Flmngr
return apiLegacy; // old way to receive Flmngr
};
// Call all previous listeners
for (const l of this.listenersFlmngrIsReady)
l(apiNew, apiLegacy);
window.FlmngrCKEditor5 = flmngrInstance.getNewAPI();
}
init() {
this.editor["getFlmngr"] = (onFlmngrIsReady) => {
!!onFlmngrIsReady && this.listenersFlmngrIsReady.push(onFlmngrIsReady); // a new way to receive Flmngr
return null; // an old way to receive Flmngr, but it is not loaded yet, 'getFlmngr' will be overridden later to return existing values
};
// Include Flmngr JS lib into the document if it was not added by 3rd party code
const apiKey = this.editor.config.get('apiKey') || this.editor.config.get('flmngr.apiKey') || this.editor.config.get('Flmngr.apiKey') || 'FLMNFLMN';
if (window.flmngr) {
// Already loaded by another instance or by using flmngr.js manually
this.setFlmngr(window.flmngr);
} else {
// We will load it and wait
if (!window.onFlmngrAndImgPenLoadedArray)
window.onFlmngrAndImgPenLoadedArray = [];
window.onFlmngrAndImgPenLoadedArray.push(() => {
this.setFlmngr(window.flmngr);
});
let delay = this.editor.config.get('libLoadDelay') || this.editor.config.get('flmngr.libLoadDelay') || this.editor.config.get('Flmngr.libLoadDelay');
if (!delay || parseInt(delay) != delay)
delay = 1;
setTimeout(() => {
// let host = "http" + (Cookies.get("N1ED_HTTPS") === "false" ? "" : "s") + "://" + (!!Cookies.get("N1ED_PREFIX") ? (Cookies.get("N1ED_PREFIX") + ".") : "") + "cloud.n1ed.com";
// Flmngr.includeJS(host + "/v/latest/sdk/flmngr.js?apiKey=" + apiKey);
// Flmngr.includeJS(host + "/v/latest/sdk/imgpen.js?apiKey=" + apiKey);
}, delay);
}
/*if ( !this.editor.plugins.has( 'ImageBlockEditing' ) && !this.editor.plugins.has( 'ImageInlineEditing' ) ) {
throw new CKEditorError( 'flmngr-missing-image-plugin', this.editor );
}*/
// Add the commands
this.editor.commands.add( 'upload', new UploadCommand( this.editor ) );
this.editor.commands.add( 'flmngr', new FlmngrCommand( this.editor ) );
// Add UI button
const componentFactory = this.editor.ui.componentFactory;
const t = this.editor.t;
componentFactory.add( 'upload', locale => {
const command = this.editor.commands.get( 'upload' );
const button = new ButtonView( locale );
button.set( {
label: t( 'Upload image or file' ),
withText: true,
tooltip: true
} );
button.bind( 'isEnabled' ).to( command );
button.on( 'execute', () => {
this.editor.execute( 'upload' );
this.editor.editing.view.focus();
} );
return button;
} );
componentFactory.add( 'flmngr', locale => {
const command = this.editor.commands.get( 'flmngr' );
const button = new ButtonView( locale );
button.set( {
label: t( 'Browse image or file' ),
withText: true,
tooltip: true
} );
button.bind( 'isEnabled' ).to( command );
button.on( 'execute', () => {
this.editor.execute( 'flmngr' );
this.editor.editing.view.focus();
} );
return button;
} );
}
static includeJS(urlJS) {
let scripts = document.getElementsByTagName("script");
let alreadyExists = false;
let existingScript = null;
for (let i = 0; i < scripts.length; i++) {
let src = decodeURI(scripts[i].getAttribute("src"));
if (src != null && src.indexOf(urlJS) !== -1) {
alreadyExists = true;
existingScript = scripts[i];
}
}
if (!alreadyExists) {
let script = document.createElement("script");
script.type = "text/javascript";
script.src = urlJS;
script.setAttribute("data-by-n1ed", "true");
document.getElementsByTagName("head")[0].appendChild(script);
return script;
} else {
return null;
}
}
}

View File

@ -0,0 +1,205 @@
import { Command, findAttributeRange, first } from 'ckeditor5';
import {showWarning} from "./utils.js";
export default class FlmngrCommand extends Command {
static flmngr;
imageExtensions = ['jpeg', 'jpg', 'png', 'bmp', 'svg', 'webp'];
constructor( editor ) {
super( editor );
// Remove default document listener to lower its priority.
this.stopListening( this.editor.model.document, 'change' );
// Lower this command listener priority to be sure that refresh() will be called after link & image refresh.
this.listenTo( this.editor.model.document, 'change', () => this.refresh(), { priority: 'low' } );
}
refresh() {
const imageCommand = this.editor.commands.get( 'insertImage' );
const linkCommand = this.editor.commands.get( 'link' );
this.isEnabled = !imageCommand || // if there is no image command, the button IS always enabled: we will show a message
(imageCommand.isEnabled || (!!linkCommand && linkCommand.isEnabled));
}
isImage(filepath) {
let i = filepath.lastIndexOf(".");
if (i > -1 && i < filepath.length-1) {
let ext = filepath.substr(i + 1).toLowerCase();
return ext === 'jpeg' || ext === 'jpg' || ext === 'png' || ext === 'gif' || ext === "bmp" || ext === "svg" || ext === "webp";
}
return false;
}
// Call a dialog to select local file and upload them ("Upload" action)
executeUpload() {
this.execute2(true);
}
// Call Flmngr ("Browse" action)
execute() {
this.execute2(false);
}
execute2(doUpload) { // false = browse
const imageCommand = this.editor.commands.get( 'insertImage' );
if (!imageCommand) {
let msg = "Please enable CKEditor 5 `Image` plugin in order to use Flmngr file manager";
if (!!window.Drupal)
msg += ":\n\nDrupal users must set `Image Upload` -> `Enable image uploads` checkbox on the page of CKEditor 5 text format";
alert(msg);
return;
}
if (!FlmngrCommand.flmngr) {
// console.log("File manager is not loaded yet");
// return;
}
const selection = this.editor.model.document.selection;
const el = selection.getSelectedElement() || first( selection.getSelectedBlocks() );
let currentUrl = null;
let elA = null;
const position = selection.getFirstPosition();
if ( selection.hasAttribute( 'linkHref' ) ) {
elA = findAttributeRange(position, 'linkHref', selection.getAttribute('linkHref'), this.editor.model).getItems().next().value.textNode;
currentUrl = elA.getAttribute("linkHref");
}
let elImg = null;
if (!!el && (el.name === 'imageBlock' || el.name === 'imageInline')) {
elImg = el;
currentUrl = elImg.getAttribute("src");
elA = null;
}
if (doUpload) {
FlmngrCommand.flmngr.selectFiles({
acceptExtensions: !!elImg ? this.imageExtensions : null,
isMultiple: false,
onFinish: (files) => {
FlmngrCommand.flmngr.upload({
filesOrLinks: files,
onFinish: (urls, paths) => {
this.createOrChange(el, elImg, elA, urls);
},
onFail: (error) => {
showWarning(this.editor, 'Unable to upload files', true, error, false);
}
});
}
})
} else {
mediaBundleBrowser(context.$note.attr('id'));
FlmngrCommand.flmngr.pickFiles({
acceptExtensions: !!elImg ? this.imageExtensions : null,
isMultiple: false,
list: currentUrl ? [currentUrl] : null,
onFinish: (files) => {
this.createOrChange(el, elImg, elA, files.map(f => f.url));
}
});
}
}
createOrChange(el, elImg, elA, urls) {
if (!!elImg) {
this.changeImgSrc(elImg, FlmngrCommand.flmngr.getNoCacheUrl(urls[0]));
} else if (!!elA) {
this.changeAHref(elA, urls[0]);
} else {
// Create new IMG and A elements
let urlsImages = [];
let urlsFiles = [];
for (let url of urls) {
if (this.isImage(url))
urlsImages.push(FlmngrCommand.flmngr.getNoCacheUrl(url));
else
urlsFiles.push(url);
}
for (const url of urlsFiles)
this.createNewA(url);
for (const url of urlsImages)
this.createNewImg(url);
}
}
createNewImg(url) {
this.editor.model.change( writer => {
const imageCommand = this.editor.commands.get( 'insertImage' );
// Check if inserting an image is actually possible - it might be possible to only insert a link.
if ( !imageCommand.isEnabled ) {
showWarning(this.editor, 'Inserting image failed', true, 'Could not insert image at the current position.', true);
return;
}
this.editor.execute( 'insertImage', { source: [url] } );
} );
};
createNewA(url) {
this.editor.model.change( writer => {
const insertPosition = this.editor.model.document.selection.getFirstPosition();
const i = url.lastIndexOf("/");
const filename = url.substr(i + 1);
const title = "Download " + filename;
writer.insertText( title, { linkHref: url }, insertPosition );
} );
};
changeImgSrc(el, url) {
this.editor.model.change( writer => {
writer.setAttribute("src", url, el);
writer.removeAttribute("srcset", el);
writer.removeAttribute("sizes", el);
/*
In Drupal when using existing content with existing image,
CKEditor 5 sets also a custom HTML attribute "src", so
to change an image URL we need not only to set an
attribute "src" of a model of CKEditor 5,
but also and "src" attribute of HTML.
Probably this is a bug or a misconfiguration of
CKEditor 5 in Drupal 9/10.
*/
let attr = el.getAttribute("htmlAttributes");
if (attr) {
delete attr.attributes.src;
delete attr.attributes.srcset;
delete attr.attributes.sizes;
writer.setAttribute("htmlAttributes", attr, el);
}
});
};
changeAHref(el, url) {
this.editor.model.change( writer => {
writer.setAttribute( 'linkHref', url, el );
// TODO: probably change text
});
};
isImage(filepath) {
let i = filepath.lastIndexOf(".");
if (i > -1 && i < filepath.length-1) {
let ext = filepath.substr(i + 1).toLowerCase();
if (this.imageExtensions.indexOf(ext) > -1)
return true;
}
return false;
}
}

View File

@ -0,0 +1,5 @@
import Flmngr from './flmngr.js';
export default {
Flmngr
};

View File

@ -0,0 +1,12 @@
import FlmngrCommand from "./flmngrcommand.js";
export default class UploadCommand extends FlmngrCommand {
execute() {
const flmngrCommand = this.editor.commands.get( 'upload' );
flmngrCommand.executeUpload();
}
}

View File

@ -0,0 +1,25 @@
export function showWarning(
editor,
title,
doLocalizeTitle,
message,
doLocalizeMessage
) {
const notification = editor.plugins.get( 'Notification' );
const t = editor.locale.t;
if (!!notification) {
notification.showWarning(
doLocalizeMessage ? t(message) : message,
{
title: doLocalizeTitle ? t(title) : title,
namespace: 'flmngr'
}
);
} else {
alert(
(doLocalizeTitle ? t(title) : title) + "\n\n" +
doLocalizeMessage ? t(message) : message
);
}
}

View File

@ -5,7 +5,10 @@ import $ from 'jquery'
window.$ = window.jQuery = $; window.$ = window.jQuery = $;
import { startStimulusApp } from '@symfony/stimulus-bundle'; import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp(); const app = startStimulusApp();
import { initTabs } from 'david-ai';
// Initialize tabs functionality
initTabs();
Alpine.plugin(persist) Alpine.plugin(persist)
Alpine.store('theme', { Alpine.store('theme', {

View File

@ -12,6 +12,35 @@
font-variation-settings: normal; font-variation-settings: normal;
line-height: 1.5; line-height: 1.5;
} }
.bg-blueGray-50 {
--tw-bg-opacity: 1;
background-color: rgba(248, 250, 252, var(--tw-bg-opacity));
}
.bg-blueGray-100 {
--tw-bg-opacity: 1;
background-color: rgba(241, 245, 249, var(--tw-bg-opacity));
}
.bg-blueGray-200 {
--tw-bg-opacity: 1;
background-color: rgba(226, 232, 240, var(--tw-bg-opacity));
}
.bg-blueGray-600 {
--tw-bg-opacity: 1;
background-color: rgba(71, 85, 105, var(--tw-bg-opacity));
}
.bg-blueGray-700 {
--tw-bg-opacity: 1;
background-color: rgba(51, 65, 85, var(--tw-bg-opacity));
}
.bg-blueGray-800 {
--tw-bg-opacity: 1;
background-color: rgba(30, 41, 59, var(--tw-bg-opacity));
}
} }
:root { :root {
@ -37,3 +66,15 @@
.table-icon, .button-icon { .table-icon, .button-icon {
@apply w-6; @apply w-6;
} }
.psc-button-save {
@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];
}
.form-label {
@apply block uppercase text-xs font-bold mb-2;
}

View File

@ -18,6 +18,7 @@
"ext-iconv": "*", "ext-iconv": "*",
"azuyalabs/yasumi": "^2.5", "azuyalabs/yasumi": "^2.5",
"behat/transliterator": "^1.2@dev", "behat/transliterator": "^1.2@dev",
"bitandblack/colors": "^2.13",
"brick/money": "^0.7.0", "brick/money": "^0.7.0",
"chillerlan/php-qrcode": "v5.0.x-dev", "chillerlan/php-qrcode": "v5.0.x-dev",
"cocur/slugify": "v3.1", "cocur/slugify": "v3.1",
@ -123,7 +124,8 @@
"symfony/stopwatch": "*", "symfony/stopwatch": "*",
"symfony/web-profiler-bundle": "*", "symfony/web-profiler-bundle": "*",
"symplify/config-transformer": "^11.1", "symplify/config-transformer": "^11.1",
"tomasvotruba/symfony-config-generator": "^0.1.5" "tomasvotruba/symfony-config-generator": "^0.1.5",
"vincentlanglet/twig-cs-fixer": "^3.5"
}, },
"config": { "config": {
"preferred-install": { "preferred-install": {

738
src/new/composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,11 @@ framework:
paths: paths:
- assets/ - assets/
missing_import_mode: strict missing_import_mode: strict
excluded_patterns:
- '*/assets/styles/_*.scss'
- '*/assets/styles/**/_*.scss'
when@prod: when@prod:
framework: framework:
asset_mapper: asset_mapper:
missing_import_mode: warn missing_import_mode: warn

View File

@ -122,6 +122,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
'access_token' => [ 'access_token' => [
'token_handler' => ApiKeyHandler::class, 'token_handler' => ApiKeyHandler::class,
'token_extractors' => ApiKeyExtractor::class 'token_extractors' => ApiKeyExtractor::class
],
'custom_authenticators' => [
ApiKeyAuthenticator::class,
ZendAuthenticator::class,
] ]
], ],
'storefront' => [ 'storefront' => [

View File

@ -1,5 +1,8 @@
symfonycasts_tailwind: symfonycasts_tailwind:
binary_version: 'v3.3.0' binary_version: 'v3.3.0'
input_css: input_css:
- 'assets/tailwind/css/login.css'
- 'assets/tailwind/css/backend.css' - 'assets/tailwind/css/backend.css'
- 'assets/tailwind/css/login.css'
symfonycasts_sass:
root_sass: 'assets/backend/dashboard/less/base.scss'

View File

@ -12,6 +12,7 @@ PSC\Shop\EntityBundle\Entity\Contact:
zip: "17506" zip: "17506"
street: "Musterstraße" street: "Musterstraße"
house_number: "24b" house_number: "24b"
account: '@account_1'
contact_2: contact_2:
username: test@shop.de username: test@shop.de
@ -26,6 +27,7 @@ PSC\Shop\EntityBundle\Entity\Contact:
zip: "17506" zip: "17506"
street: "Chausseestraße" street: "Chausseestraße"
house_number: "24b" house_number: "24b"
account: '@account_1'
contact_3: contact_3:
username: test3@shop.de username: test3@shop.de
@ -40,6 +42,7 @@ PSC\Shop\EntityBundle\Entity\Contact:
zip: "175063" zip: "175063"
street: "Chausseestraße3" street: "Chausseestraße3"
house_number: "24b3" house_number: "24b3"
account: '@account_1'
contact_4: contact_4:
username: company@shop.de username: company@shop.de
@ -55,6 +58,7 @@ PSC\Shop\EntityBundle\Entity\Contact:
zip: "17506" zip: "17506"
street: "Chausseestraße" street: "Chausseestraße"
house_number: "24b" house_number: "24b"
account: '@account_2'
contact_5: contact_5:
username: association@shop.de username: association@shop.de
@ -70,6 +74,7 @@ PSC\Shop\EntityBundle\Entity\Contact:
zip: "17506" zip: "17506"
street: "Chausseestraße" street: "Chausseestraße"
house_number: "24b" house_number: "24b"
account: '@account_1'
PSC\Shop\EntityBundle\Entity\ContactAddress: PSC\Shop\EntityBundle\Entity\ContactAddress:

View File

@ -80,9 +80,18 @@ PSC\Shop\EntityBundle\Entity\Product:
</contact.accountType> </contact.accountType>
</option> </option>
<option id="calc_rabatt_account" type="Hidden">
<contact.account default="1">
<grenze calc_value="1">1</grenze>
<grenze calc_value="8">2</grenze>
<grenze calc_value="5">3</grenze>
</contact.account>
</option>
<option id="calc" type="Hidden"> <option id="calc" type="Hidden">
<auflage> <auflage>
<grenze formel="0.26*$Vauflage$V*$CVcalc_rabatt_contact.accountType$CV">1-</grenze> <grenze formel="0.26*$Vauflage$V*$CVcalc_rabatt_account_contact.account$CV*$CVcalc_rabatt_contact.accountType$CV">1-</grenze>
</auflage> </auflage>
</option> </option>

View File

@ -33,13 +33,6 @@ return [
'@hotwired/stimulus' => [ '@hotwired/stimulus' => [
'version' => '3.2.2', 'version' => '3.2.2',
], ],
'tom-select/dist/css/tom-select.bootstrap5.css' => [
'version' => '2.4.1',
'type' => 'css',
],
'tom-select' => [
'version' => '2.4.1',
],
'@orchidjs/sifter' => [ '@orchidjs/sifter' => [
'version' => '1.1.0', 'version' => '1.1.0',
], ],
@ -89,10 +82,6 @@ return [
'version' => '5.3.3', 'version' => '5.3.3',
'type' => 'css', 'type' => 'css',
], ],
'tom-select/dist/css/tom-select.default.css' => [
'version' => '2.4.1',
'type' => 'css',
],
'summernote/dist/summernote-lite.min.css' => [ 'summernote/dist/summernote-lite.min.css' => [
'version' => '0.9.1', 'version' => '0.9.1',
'type' => 'css', 'type' => 'css',
@ -107,8 +96,218 @@ return [
'@kurkle/color' => [ '@kurkle/color' => [
'version' => '0.3.4', 'version' => '0.3.4',
], ],
'tom-select/dist/css/tom-select.default.min.css' => [ 'tom-select' => [
'version' => '2.4.1', 'version' => '2.4.1',
],
'david-ai' => [
'version' => '1.0.6',
],
'ckeditor5' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-adapter-ckfinder/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-alignment/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-autoformat/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-autosave/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-basic-styles/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-block-quote/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-bookmark/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-ckbox/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-ckfinder/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-clipboard/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-cloud-services/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-code-block/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-core/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-easy-image/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-editor-balloon/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-editor-classic/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-editor-decoupled/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-editor-inline/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-editor-multi-root/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-engine/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-enter/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-essentials/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-find-and-replace/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-font/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-heading/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-highlight/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-horizontal-line/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-html-embed/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-html-support/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-image/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-indent/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-language/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-link/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-list/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-markdown-gfm/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-media-embed/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-mention/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-minimap/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-page-break/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-paragraph/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-paste-from-office/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-remove-format/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-restricted-editing/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-select-all/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-show-blocks/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-source-editing/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-special-characters/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-style/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-table/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-typing/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-ui/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-undo/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-upload/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-utils/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-watchdog/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-widget/dist/index.js' => [
'version' => '44.1.0',
],
'@ckeditor/ckeditor5-word-count/dist/index.js' => [
'version' => '44.1.0',
],
'lodash-es' => [
'version' => '4.17.21',
],
'blurhash' => [
'version' => '2.0.5',
],
'marked' => [
'version' => '4.0.12',
],
'turndown' => [
'version' => '7.2.0',
],
'turndown-plugin-gfm' => [
'version' => '1.0.2',
],
'color-parse' => [
'version' => '1.4.2',
],
'color-convert' => [
'version' => '2.0.1',
],
'vanilla-colorful/lib/entrypoints/hex' => [
'version' => '0.7.2',
],
'color-name' => [
'version' => '1.1.4',
],
'ckeditor5/dist/ckeditor5.min.css' => [
'version' => '44.1.0',
'type' => 'css', 'type' => 'css',
], ],
'ckeditor5/translations/de.js' => [
'version' => '44.1.0',
],
]; ];

View File

@ -121,12 +121,12 @@
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
<script> <script>
$(function() { window.addEventListener("load", (event) => {
$('.syncDomain').click(function() { document.querySelector('.syncDomain').addEventListener("click", (event) => {
$.getJSON('{{ path('psc_backend_domain_list_sync') }}', [], function() { fetch('{{ path('psc_backend_domain_list_sync') }}').then((result) => {
document.location='{{ path('psc_backend_login') }}'; document.location='{{ path('psc_backend_login') }}';
})
}); });
}) })
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace PSC\Libraries\AceEditorBundle\Form\Extension;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\UX\StimulusBundle\Helper\StimulusHelper;
/**
* @extends AbstractType<string>
*/
final class CKEditor5Type extends AbstractType
{
public function __construct(
#[Autowire(service: 'stimulus.helper')]
private readonly StimulusHelper $stimulusHelper,
) {
}
public function finishView(FormView $view, FormInterface $form, array $options): void
{
parent::finishView($view, $form, $options);
$attr = $this->stimulusHelper->createStimulusAttributes();
$attr->addController('ckeditor5');
$view->vars['attr'] = $attr->toArray();
}
public function getParent(): string
{
return TextareaType::class;
}
}

View File

@ -36,7 +36,7 @@ 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;
@ -125,6 +125,18 @@ class AccountType extends AbstractType
->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(
'class' => 'PSC\Shop\EntityBundle\Entity\Cms',
'choice_label' => 'title',
'choice_value' => 'uid',
'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) use ($tempCms) {
return $er->createQueryBuilder('u')
->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'])
@ -198,7 +210,7 @@ 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));
} }

View File

@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
@ -23,13 +24,8 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class Add extends AbstractController class Add extends AbstractController
{ {
private EventDispatcherInterface $eventDispatcher; public function __construct(private readonly EntityManagerInterface $entityManager, private readonly EventDispatcherInterface $eventDispatcher, private readonly TokenStorageInterface $tokenStorage)
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager, EventDispatcherInterface $eventDispatcher)
{ {
$this->entityManager = $entityManager;
$this->eventDispatcher = $eventDispatcher;
} }
/** /**
@ -59,39 +55,40 @@ class Add extends AbstractController
$product = $this->entityManager->getRepository(Product::class)->findOneBy(['uuid' => $data->productUUId]); $product = $this->entityManager->getRepository(Product::class)->findOneBy(['uuid' => $data->productUUId]);
if ($product) { if ($product) {
if(!$data->dispatchNoEvents) { if (!$data->dispatchNoEvents) {
$event = new PSCAdd($data); $event = new PSCAdd($data);
$this->eventDispatcher->dispatch($event, PSCAdd::NAME); $this->eventDispatcher->dispatch($event, PSCAdd::NAME);
} }
$articles = $_SESSION['Basket']['Articles']; $articles = $_SESSION['Basket']['Articles'];
/** /**
* @var \TP_Basket_Item $basketItem * @var \TP_Basket_Item $basketItem
*/ */
$basketItem = clone($_SESSION['Basket']['TempProduct'][$data->productUUId]); $basketItem = clone($_SESSION['Basket']['TempProduct'][$data->productUUId]);
$basketItem->setDeliveryDate((string)$data->deliveryDate); $basketItem->setDeliveryDate((string)$data->deliveryDate);
$basketItem->setDeliveryInfo((string)$data->deliveryInfo); $basketItem->setDeliveryInfo((string)$data->deliveryInfo);
if((string)$data->ref != "") { if ((string)$data->ref != "") {
$basketItem->setRef($data->ref); $basketItem->setRef($data->ref);
} }
if((string)$data->basketField1 != "") { if ((string)$data->basketField1 != "") {
$basketItem->setRef($data->basketField1); $basketItem->setRef($data->basketField1);
} }
if((string)$data->basketField2 != "") { if ((string)$data->basketField2 != "") {
$basketItem->setKst($data->basketField2); $basketItem->setKst($data->basketField2);
} }
$basketItem->setXmlProduct((string)$data->xmlProduct); $basketItem->setXmlProduct((string)$data->xmlProduct);
if((string)$data->layouterUuid != "") { if ((string)$data->layouterUuid != "") {
$basketItem->setLayouterId((string)$data->layouterUuid); $basketItem->setLayouterId((string)$data->layouterUuid);
} }
$itemId = $articles->addItem($basketItem); $itemId = $articles->addItem($basketItem);
if ($data->clearTempItem) {
$_SESSION['Basket']['TempProduct'][$data->productUUId] = new \TP_Basket_Item();
}
$output = new Output(); $output = new Output();
$output->success = true; $output->success = true;
$output->basketUUId = $itemId; $output->basketUUId = $itemId;
if($data->clearTempItem) {
$_SESSION['Basket']['TempProduct'][$data->productUUId] = new \TP_Basket_Item();
}
return $this->json(new Output()); return $this->json(new Output());
} }

View File

@ -108,6 +108,8 @@ class EditController extends AbstractController
$cmsDoc->setExtraSettings($cms->getExtraSettings()); $cmsDoc->setExtraSettings($cms->getExtraSettings());
$cmsDoc->setPluginSettings($cms->getPluginSettings()); $cmsDoc->setPluginSettings($cms->getPluginSettings());
$cmsDoc->setNoIndex($cms->isNoIndex()); $cmsDoc->setNoIndex($cms->isNoIndex());
$cmsDoc->setAccounts($cms->getAccounts());
$documentManager->persist($cmsDoc); $documentManager->persist($cmsDoc);
$documentManager->flush(); $documentManager->flush();
@ -164,13 +166,14 @@ class EditController extends AbstractController
if (!$request->isMethod('POST') && $cmsDoc) { if (!$request->isMethod('POST') && $cmsDoc) {
$cms->setExtraSettings($cmsDoc->getExtraSettings()); $cms->setExtraSettings($cmsDoc->getExtraSettings());
$cms->setPluginSettings($cmsDoc->getPluginSettings()); $cms->setPluginSettings($cmsDoc->getPluginSettings());
$cms->setAccounts($cmsDoc->getAccounts());
$cms->setNoIndex($cmsDoc->isNoIndex()); $cms->setNoIndex($cmsDoc->isNoIndex());
} elseif (!$cmsDoc) { } elseif (!$cmsDoc) {
$cmsDoc = new \PSC\Shop\EntityBundle\Document\Cms(); $cmsDoc = new \PSC\Shop\EntityBundle\Document\Cms();
$cmsDoc->setUid($cms->getUid()); $cmsDoc->setUid($cms->getUid());
$cmsDoc->setExtraSettings($cms->getExtraSettings()); $cmsDoc->setExtraSettings($cms->getExtraSettings());
$cmsDoc->setNoIndex($cms->isNoIndex()); $cmsDoc->setNoIndex($cms->isNoIndex());
$cmsDoc->setAccounts($cms->getAccounts());
$documentManager->persist($cmsDoc); $documentManager->persist($cmsDoc);
$documentManager->flush(); $documentManager->flush();
} }
@ -185,7 +188,7 @@ class EditController extends AbstractController
$cmsDoc->setPluginSettings($cms->getPluginSettings()); $cmsDoc->setPluginSettings($cms->getPluginSettings());
$cmsDoc->setExtraSettings($cms->getExtraSettings()); $cmsDoc->setExtraSettings($cms->getExtraSettings());
$cmsDoc->setNoIndex($cms->isNoIndex()); $cmsDoc->setNoIndex($cms->isNoIndex());
$cmsDoc->setAccounts($cms->getAccounts());
$this->historyService->createHistoryEntry(new PSCHistory((string)$cms->getUid()), $cms, $cmsDoc); $this->historyService->createHistoryEntry(new PSCHistory((string)$cms->getUid()), $cms, $cmsDoc);
$entityManager->persist($cms); $entityManager->persist($cms);

View File

@ -16,6 +16,7 @@ namespace PSC\Shop\CmsBundle\Form\Backend;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Lexik\Bundle\FormFilterBundle\Filter\Query\QueryInterface; use Lexik\Bundle\FormFilterBundle\Filter\Query\QueryInterface;
use PSC\Shop\EntityBundle\Entity\Account;
use PSC\Shop\EntityBundle\Entity\Cms; use PSC\Shop\EntityBundle\Entity\Cms;
use PSC\Shop\ThemeBundle\Core\ThemeHolder; use PSC\Shop\ThemeBundle\Core\ThemeHolder;
use PSC\Shop\ThemeBundle\Core\ThemeHolderInterface; use PSC\Shop\ThemeBundle\Core\ThemeHolderInterface;
@ -46,12 +47,12 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class CmsType extends AbstractType class CmsType extends AbstractType
{ {
protected $shop = null; protected $shop = null;
/** @var Field */ /** @var Field */
protected $fields; protected $fields;
/** @var ThemeSourceInterface */ /** @var ThemeSourceInterface */
protected $themeSource; protected $themeSource;
protected $formFactory; protected $formFactory;
/** @var Language */ /** @var Language */
public $language; public $language;
public function __construct(Field $fields, Shop $shop, ThemeSource $themeSource, FormFactoryInterface $formFactory, Language $language, EntityManagerInterface $entityManager) public function __construct(Field $fields, Shop $shop, ThemeSource $themeSource, FormFactoryInterface $formFactory, Language $language, EntityManagerInterface $entityManager)
{ {
@ -83,7 +84,14 @@ class CmsType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$accounts = $this->entityManager->getRepository(Account::class)->createQueryBuilder('u')
->join('u.shops', 's')
->where('s.uid = :shop')->setParameter('shop', $this->shop->getSelectedShop()->getId())->getQuery()->execute();
$defaultAccounts = [];
foreach ($accounts as $account) {
$defaultAccounts[$account->getTitle()] = $account->getUid();
}
dump($defaultAccounts);
$tmp = $this->buildCmsTree(['Oberste Ebene' => 0]); $tmp = $this->buildCmsTree(['Oberste Ebene' => 0]);
$builder $builder
->add('title', TextType::class, ['label' => 'psc_shop_cms.Name', 'required' => false]) ->add('title', TextType::class, ['label' => 'psc_shop_cms.Name', 'required' => false])
@ -127,8 +135,14 @@ class CmsType extends AbstractType
'choices' => $this->language->getLanguageArrayForContent(), 'choices' => $this->language->getLanguageArrayForContent(),
'required' => true, 'required' => true,
)) ))
->add('accounts', ChoiceType::class, array(
'label' => 'psc_shop_cms.Accounts',
'choices' => $defaultAccounts,
'multiple' => true,
'required' => false,
))
->add('metaOgDescription', TextAreaType::class, ['label' => 'psc_shop_cms.OGDescription', 'required' => false]); ->add('metaOgDescription', TextAreaType::class, ['label' => 'psc_shop_cms.OGDescription', 'required' => false]);
/** @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::Cms) as $field) { foreach ($this->fields->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Cms) as $field) {
$builder->add($field->buildForm($this->formFactory->createNamedBuilder($field->getGroup(), FormType::class, null, ['mapped' => false]), $options)); $builder->add($field->buildForm($this->formFactory->createNamedBuilder($field->getGroup(), FormType::class, null, ['mapped' => false]), $options));
} }

View File

@ -1,5 +1,6 @@
psc_shop_cms: psc_shop_cms:
List: Liste List: Liste
Filter: Filter
Search: Suche Search: Suche
Active: Aktiv Active: Aktiv
Title: Titel Title: Titel
@ -23,6 +24,7 @@ psc_shop_cms:
OnTop: Oberste Ebene OnTop: Oberste Ebene
Sort: Sortierung Sort: Sortierung
Language: Sprache Language: Sprache
Accounts: Firmen
Private: Privat Private: Privat
onlyLoggedIn: nur anzeigen wenn eingelogged? onlyLoggedIn: nur anzeigen wenn eingelogged?
SEO: SEO SEO: SEO

View File

@ -37,6 +37,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#extend" role="tab">{{ 'psc_shop_cms.Extended'|trans }}</a> <a class="nav-link" data-bs-toggle="tab" href="#extend" role="tab">{{ 'psc_shop_cms.Extended'|trans }}</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#filter" role="tab">{{ 'psc_shop_cms.Filter'|trans }}</a>
</li>
{% for customGroup in customGroups %} {% for customGroup in customGroups %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#{{ customGroup.id }}" role="tab">{{ customGroup.title }}</a> <a class="nav-link" data-bs-toggle="tab" href="#{{ customGroup.id }}" role="tab">{{ customGroup.title }}</a>
@ -270,6 +273,17 @@
{{ form_errors(form.extraSettings) }} {{ form_errors(form.extraSettings) }}
</div> </div>
</div> </div>
{% for customGroup in customGroups %}
<div class="row mb-3">
<label class="col-md-3 form-control-label">
{{ form_label(form.accounts) }}
</label>
<div class="col-md-9">
{{ form_widget(form.accounts) }}
</div>
{{ form_errors(form.accounts) }}
</div>
</div>
{% for customGroup in customGroups %} {% for customGroup in customGroups %}
<div class="tab-pane" id="{{ customGroup.id }}" role="tabpanel"> <div class="tab-pane" id="{{ customGroup.id }}" role="tabpanel">
{% for customField in customFields %} {% for customField in customFields %}

View File

@ -37,6 +37,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#extend" role="tab">{{ 'psc_shop_cms.Extended'|trans }}</a> <a class="nav-link" data-bs-toggle="tab" href="#extend" role="tab">{{ 'psc_shop_cms.Extended'|trans }}</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#filter" role="tab">{{ 'psc_shop_cms.Filter'|trans }}</a>
</li>
</ul> </ul>
</div> </div>
<div class="col-md-10"> <div class="col-md-10">
@ -236,6 +239,17 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tab-pane" id="filter" role="tabpanel">
<div class="row mb-3">
<label class="col-md-3 form-control-label">
{{ form_label(form.accounts) }}
</label>
<div class="col-md-9">
{{ form_widget(form.accounts) }}
</div>
{{ form_errors(form.accounts) }}
</div>
</div>
<div class="tab-pane" id="extend" role="tabpanel"> <div class="tab-pane" id="extend" role="tabpanel">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">

View File

@ -132,6 +132,7 @@ class ContactType extends AbstractType
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'multiple' => true, 'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) use ($tempPayments) { 'query_builder' => function (EntityRepository $er) use ($tempPayments) {
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
@ -152,6 +153,7 @@ class ContactType extends AbstractType
}, },
'choice_value' => 'uid', 'choice_value' => 'uid',
'multiple' => true, 'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) use ($tempProductGroups) { 'query_builder' => function (EntityRepository $er) use ($tempProductGroups) {
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
@ -162,6 +164,7 @@ class ContactType extends AbstractType
'class' => 'PSC\Shop\EntityBundle\Entity\Shipping', 'class' => 'PSC\Shop\EntityBundle\Entity\Shipping',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'required' => false,
'multiple' => true, 'multiple' => true,
'query_builder' => function (EntityRepository $er) use ($tempShippings) { 'query_builder' => function (EntityRepository $er) use ($tempShippings) {
@ -173,6 +176,7 @@ class ContactType extends AbstractType
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'required' => false,
'multiple' => true, 'multiple' => true,
'query_builder' => function (EntityRepository $er) use ($tempProducts) { 'query_builder' => function (EntityRepository $er) use ($tempProducts) {
@ -184,6 +188,7 @@ class ContactType extends AbstractType
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'required' => false,
'multiple' => true, 'multiple' => true,
'query_builder' => function (EntityRepository $er) use ($tempProducts) { 'query_builder' => function (EntityRepository $er) use ($tempProducts) {
@ -196,6 +201,7 @@ class ContactType extends AbstractType
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'multiple' => true, 'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) use ($tempCms) { 'query_builder' => function (EntityRepository $er) use ($tempCms) {
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
@ -206,6 +212,7 @@ class ContactType extends AbstractType
'class' => 'PSC\Shop\EntityBundle\Entity\Account', 'class' => 'PSC\Shop\EntityBundle\Entity\Account',
'choice_label' => 'title', 'choice_label' => 'title',
'choice_value' => 'uid', 'choice_value' => 'uid',
'required' => false,
'multiple' => true, 'multiple' => true,
'query_builder' => function (EntityRepository $er) { 'query_builder' => function (EntityRepository $er) {
@ -217,12 +224,14 @@ class ContactType extends AbstractType
->add('shops', EntityType::class, array( ->add('shops', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Shop', 'class' => 'PSC\Shop\EntityBundle\Entity\Shop',
'choice_label' => 'title', 'choice_label' => 'title',
'required' => false,
'choice_value' => 'uid', 'choice_value' => 'uid',
'multiple' => true 'multiple' => true
)) ))
->add('rolesForm', EntityType::class, array( ->add('rolesForm', EntityType::class, array(
'class' => 'PSC\Shop\EntityBundle\Entity\Role', 'class' => 'PSC\Shop\EntityBundle\Entity\Role',
'choice_label' => 'title', 'choice_label' => 'title',
'required' => false,
'choice_value' => 'uid', 'choice_value' => 'uid',
'multiple' => true 'multiple' => true
)) ))

View File

@ -1576,33 +1576,34 @@
<script> <script>
var wto; var wto;
window.addEventListener("load", (event) => {
$(function() { document.querySelector('#contact_username').addEventListener("keyup", (event) => {
$('#contact_username').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#contact_username').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/contact/edit/check/username/" + event.srcElement.value)
$.getJSON("/apps/backend/contact/edit/check/username/" + $('#contact_username').val(),[], function(data) { .then((result) => {
$('#contact_username').removeClass('is-valid'); return result.json();
$('#contact_username').removeClass('is-invalid'); })
$('#contact_username').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#contact_username').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#contact_username').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#contact_username').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
});
}));
}); });
</script> </script>

View File

@ -1704,33 +1704,34 @@
<script> <script>
var wto; var wto;
window.addEventListener("load", (event) => {
$(function() { document.querySelector('#contact_username').addEventListener("keyup", (event) => {
$('#contact_username').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#contact_username').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/contact/edit/check/username/" + event.srcElement.value)
$.getJSON("/apps/backend/contact/edit/check/username/" + $('#contact_username').val(),[], function(data) { .then((result) => {
$('#contact_username').removeClass('is-valid'); return result.json();
$('#contact_username').removeClass('is-invalid'); })
$('#contact_username').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#contact_username').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#contact_username').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#contact_username').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
});
}));
}); });
</script> </script>

View File

@ -4,6 +4,8 @@ namespace PSC\Shop\ContactBundle\Transformer\Model;
use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use PSC\Shop\AccountBundle\Model\Account as PSCAccount;
use PSC\Shop\AccountBundle\Transformer\Account;
use PSC\Shop\ContactBundle\Model\Role; use PSC\Shop\ContactBundle\Model\Role;
use PSC\Shop\ContactBundle\Repository\ContactRepository; use PSC\Shop\ContactBundle\Repository\ContactRepository;
use PSC\Shop\MediaBundle\Model\Media; use PSC\Shop\MediaBundle\Model\Media;
@ -13,7 +15,7 @@ use PSC\System\SettingsBundle\Service\Shop;
class Contact class Contact
{ {
public function __construct(private readonly MediaManager $mediaManager, private readonly ContactRepository $contactRepository, private readonly Shop $shopService, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager, private readonly PSCMedia $mediaTransformer) public function __construct(private readonly MediaManager $mediaManager, private readonly ContactRepository $contactRepository, private readonly Shop $shopService, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager, private readonly PSCMedia $mediaTransformer, private readonly Account $accountTransformer)
{ {
} }
@ -139,6 +141,12 @@ class Contact
$contactDoc->setUid($contactEntity->getUid()); $contactDoc->setUid($contactEntity->getUid());
} }
$account = new PSCAccount();
if ($contactEntity->getAccount() != null) {
$this->accountTransformer->fromEntity($account, $contactEntity->getAccount());
}
$contact->setAccount($account);
$contact->setUUId((string)$contactEntity->getUuid()); $contact->setUUId((string)$contactEntity->getUuid());
$contact->setEMail((string)$contactEntity->getEmail()); $contact->setEMail((string)$contactEntity->getEmail());
$contact->setUid((int)$contactEntity->getUid()); $contact->setUid((int)$contactEntity->getUid());

View File

@ -29,6 +29,8 @@ class Cms
#[Field(type: 'boolean')] #[Field(type: 'boolean')]
protected bool $noIndex = false; protected bool $noIndex = false;
#[Field(type: 'hash')]
protected array $accounts = [];
#[Field(type: 'hash')] #[Field(type: 'hash')]
protected $pluginSettings = []; protected $pluginSettings = [];
@ -118,4 +120,13 @@ class Cms
{ {
$this->noIndex = $noIndex; $this->noIndex = $noIndex;
} }
public function getAccounts(): array
{
return (array)$this->accounts;
}
public function setAccounts(array $var): void
{
$this->accounts = $var;
}
} }

View File

@ -33,7 +33,7 @@ class Account
protected $productsOrg; protected $productsOrg;
protected $priceFactor; protected $priceFactor;
protected $extraSettings; protected $extraSettings;
/** /**
* Id der Firma * Id der Firma
* *
* @var integer * @var integer
@ -42,202 +42,202 @@ class Account
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')] #[ORM\GeneratedValue(strategy: 'AUTO')]
protected $uid; protected $uid;
/** /**
* Titel der Firma * Titel der Firma
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'company', type: 'string', length: 255)] #[ORM\Column(name: 'company', type: 'string', length: 255)]
protected $title; protected $title;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'appendix', type: 'string', length: 255)] #[ORM\Column(name: 'appendix', type: 'string', length: 255)]
protected $appendix; protected $appendix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'street', type: 'string', length: 255)] #[ORM\Column(name: 'street', type: 'string', length: 255)]
protected $street; protected $street;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'destrict', type: 'string', length: 255)] #[ORM\Column(name: 'destrict', type: 'string', length: 255)]
protected $destrict; protected $destrict;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'zip', type: 'string', length: 255)] #[ORM\Column(name: 'zip', type: 'string', length: 255)]
protected $zip; protected $zip;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'city', type: 'string', length: 255)] #[ORM\Column(name: 'city', type: 'string', length: 255)]
protected $city; protected $city;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'state', type: 'string', length: 255)] #[ORM\Column(name: 'state', type: 'string', length: 255)]
protected $state; protected $state;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'country', type: 'string', length: 255)] #[ORM\Column(name: 'country', type: 'string', length: 255)]
protected $country; protected $country;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'email', type: 'string', length: 255)] #[ORM\Column(name: 'email', type: 'string', length: 255)]
protected $email; protected $email;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'house_number', type: 'string', length: 255)] #[ORM\Column(name: 'house_number', type: 'string', length: 255)]
protected $houseNumber; protected $houseNumber;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'homepage', type: 'string', length: 255)] #[ORM\Column(name: 'homepage', type: 'string', length: 255)]
protected $homepage; protected $homepage;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'phone_lv', type: 'string', length: 255)] #[ORM\Column(name: 'phone_lv', type: 'string', length: 255)]
protected $phoneAreaCode; protected $phoneAreaCode;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'phone_vorwahl', type: 'string', length: 255)] #[ORM\Column(name: 'phone_vorwahl', type: 'string', length: 255)]
protected $phonePrefix; protected $phonePrefix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'phone', type: 'string', length: 255)] #[ORM\Column(name: 'phone', type: 'string', length: 255)]
protected $phone; protected $phone;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'phone_durchwahl', type: 'string', length: 255)] #[ORM\Column(name: 'phone_durchwahl', type: 'string', length: 255)]
protected $phoneAppendix; protected $phoneAppendix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'mobile_lv', type: 'string', length: 255)] #[ORM\Column(name: 'mobile_lv', type: 'string', length: 255)]
protected $mobileAreaCode; protected $mobileAreaCode;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'mobile_vorwahl', type: 'string', length: 255)] #[ORM\Column(name: 'mobile_vorwahl', type: 'string', length: 255)]
protected $mobilePrefix; protected $mobilePrefix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'mobile', type: 'string', length: 255)] #[ORM\Column(name: 'mobile', type: 'string', length: 255)]
protected $mobile; protected $mobile;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'mobile_durchwahl', type: 'string', length: 255)] #[ORM\Column(name: 'mobile_durchwahl', type: 'string', length: 255)]
protected $mobileAppendix; protected $mobileAppendix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'fax_lv', type: 'string', length: 255)] #[ORM\Column(name: 'fax_lv', type: 'string', length: 255)]
protected $faxAreaCode; protected $faxAreaCode;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'fax_vorwahl', type: 'string', length: 255)] #[ORM\Column(name: 'fax_vorwahl', type: 'string', length: 255)]
protected $faxPrefix; protected $faxPrefix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'fax', type: 'string', length: 255)] #[ORM\Column(name: 'fax', type: 'string', length: 255)]
protected $fax; protected $fax;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'fax_durchwahl', type: 'string', length: 255)] #[ORM\Column(name: 'fax_durchwahl', type: 'string', length: 255)]
protected $faxAppendix; protected $faxAppendix;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'alternativ_lv', type: 'string', length: 255)] #[ORM\Column(name: 'alternativ_lv', type: 'string', length: 255)]
protected $alternativAreaCode; protected $alternativAreaCode;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'alternativ_type', type: 'string', length: 255)] #[ORM\Column(name: 'alternativ_type', type: 'string', length: 255)]
protected $alternativType; protected $alternativType;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'alternativ', type: 'string', length: 255)] #[ORM\Column(name: 'alternativ', type: 'string', length: 255)]
protected $alternativ; protected $alternativ;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'alternativ_durchwahl', type: 'string', length: 255)] #[ORM\Column(name: 'alternativ_durchwahl', type: 'string', length: 255)]
protected $alternativAppendix; protected $alternativAppendix;
/** /**
* Vorgänger der Firma * Vorgänger der Firma
*/ */
#[ORM\ManyToOne(targetEntity: 'Account', inversedBy: 'children')] #[ORM\ManyToOne(targetEntity: 'Account', inversedBy: 'children')]
#[ORM\JoinColumn(name: 'filiale_id', referencedColumnName: 'id')] #[ORM\JoinColumn(name: 'filiale_id', referencedColumnName: 'id')]
protected $parent; protected $parent;
/** /**
* Vorgänger der Firma * Vorgänger der Firma
* *
* @var int * @var int
*/ */
#[ORM\Column(name: 'filiale_id', type: 'integer', nullable: true)] #[ORM\Column(name: 'filiale_id', type: 'integer', nullable: true)]
protected $parentId = 0; protected $parentId = 0;
/** /**
* Unterfirmen der Firma * Unterfirmen der Firma
*/ */
#[ORM\OneToMany(targetEntity: 'Account', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Account', mappedBy: 'parent')]
protected $children; protected $children;
/** /**
* Gesperter Account * Gesperter Account
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'locked', type: 'boolean')] #[ORM\Column(name: 'locked', type: 'boolean')]
protected $locked; protected $locked;
/** /**
* Benutze Account als Rechnungsadresse * Benutze Account als Rechnungsadresse
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'use_account_as_invoice', type: 'boolean')] #[ORM\Column(name: 'use_account_as_invoice', type: 'boolean')]
protected $useAccountAsInvoiceAddress; protected $useAccountAsInvoiceAddress;
/** /**
* Install * Install
* *
* @var int * @var int
@ -275,175 +275,183 @@ class Account
#[ORM\InverseJoinColumn(name: 'productgroup_id', referencedColumnName: 'id')] #[ORM\InverseJoinColumn(name: 'productgroup_id', referencedColumnName: 'id')]
#[ORM\ManyToMany(targetEntity: 'Productgroup', inversedBy: 'accounts')] #[ORM\ManyToMany(targetEntity: 'Productgroup', inversedBy: 'accounts')]
public $productGroups; public $productGroups;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_name', type: 'string', length: 255)] #[ORM\Column(name: 'bank_name', type: 'string', length: 255)]
protected $bankKtoName; protected $bankKtoName;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_kto', type: 'string', length: 255)] #[ORM\Column(name: 'bank_kto', type: 'string', length: 255)]
protected $bankKTO; protected $bankKTO;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_blz', type: 'string', length: 255)] #[ORM\Column(name: 'bank_blz', type: 'string', length: 255)]
protected $bankBLZ; protected $bankBLZ;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_iban', type: 'string', length: 255)] #[ORM\Column(name: 'bank_iban', type: 'string', length: 255)]
protected $bankIban; protected $bankIban;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_bic', type: 'string', length: 255)] #[ORM\Column(name: 'bank_bic', type: 'string', length: 255)]
protected $bankBic; protected $bankBic;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'bank_bank_name', type: 'string', length: 255)] #[ORM\Column(name: 'bank_bank_name', type: 'string', length: 255)]
protected $bankName; protected $bankName;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'usid', type: 'string', length: 255)] #[ORM\Column(name: 'usid', type: 'string', length: 255)]
protected $ustid; protected $ustid;
/** /**
* *
* @var int * @var int
*/ */
#[ORM\Column(name: 'typ', type: 'integer', length: 2)] #[ORM\Column(name: 'typ', type: 'integer', length: 2)]
protected $typ; protected $typ;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'logo1', type: 'string', length: 255)] #[ORM\Column(name: 'logo1', type: 'string', length: 255)]
protected $image; protected $image;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'template_switch', type: 'string', length: 255)] #[ORM\Column(name: 'template_switch', type: 'string', length: 255)]
protected $templateSwitch; protected $templateSwitch;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'informations', type: 'string')] #[ORM\Column(name: 'informations', type: 'string')]
protected $information; protected $information;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'mega_code', type: 'string', length: 255)] #[ORM\Column(name: 'mega_code', type: 'string', length: 255)]
protected $megaCode; protected $megaCode;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'hotel_name', type: 'string', length: 255)] #[ORM\Column(name: 'hotel_name', type: 'string', length: 255)]
protected $hotelName; protected $hotelName;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'sub_hotel_name', type: 'string', length: 255)] #[ORM\Column(name: 'sub_hotel_name', type: 'string', length: 255)]
protected $subHotelName; protected $subHotelName;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'email_gm', type: 'string', length: 255)] #[ORM\Column(name: 'email_gm', type: 'string', length: 255)]
protected $emailGm; protected $emailGm;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'zimmer', type: 'string', length: 255)] #[ORM\Column(name: 'zimmer', type: 'string', length: 255)]
protected $room; protected $room;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'gz', type: 'string', length: 255)] #[ORM\Column(name: 'gz', type: 'string', length: 255)]
protected $gz; protected $gz;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'gf', type: 'string', length: 255)] #[ORM\Column(name: 'gf', type: 'string', length: 255)]
protected $gf; protected $gf;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'gsitz', type: 'string', length: 255)] #[ORM\Column(name: 'gsitz', type: 'string', length: 255)]
protected $gSitz; protected $gSitz;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'handelsregister', type: 'string', length: 255)] #[ORM\Column(name: 'handelsregister', type: 'string', length: 255)]
protected $handelsRegister; protected $handelsRegister;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'hrb', type: 'string', length: 255)] #[ORM\Column(name: 'hrb', type: 'string', length: 255)]
protected $hrb; protected $hrb;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'vorsitz', type: 'string', length: 255)] #[ORM\Column(name: 'vorsitz', type: 'string', length: 255)]
protected $vorsitz; protected $vorsitz;
/** /**
* *
* @var int * @var int
*/ */
#[ORM\Column(name: 'anrede1', type: 'integer', length: 2)] #[ORM\Column(name: 'anrede1', type: 'integer', length: 2)]
protected $salutation1; protected $salutation1;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'firstname1', type: 'string', length: 255)] #[ORM\Column(name: 'firstname1', type: 'string', length: 255)]
protected $firstname1; protected $firstname1;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'lastname1', type: 'string', length: 255)] #[ORM\Column(name: 'lastname1', type: 'string', length: 255)]
protected $lastname1; protected $lastname1;
/** /**
* *
* @var int * @var int
*/ */
#[ORM\Column(name: 'anrede2', type: 'integer', length: 2)] #[ORM\Column(name: 'anrede2', type: 'integer', length: 2)]
protected $salutation2; protected $salutation2;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'firstname2', type: 'string', length: 255)] #[ORM\Column(name: 'firstname2', type: 'string', length: 255)]
protected $firstname2; protected $firstname2;
/** /**
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'lastname2', type: 'string', length: 255)] #[ORM\Column(name: 'lastname2', type: 'string', length: 255)]
protected $lastname2; protected $lastname2;
/**
#[ORM\JoinTable(name: 'account_cms')]
#[ORM\JoinColumn(name: 'account_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'account_id', referencedColumnName: 'id')]
#[ORM\ManyToMany(targetEntity: 'Cms', inversedBy: 'accounts')]
public $cms;
/**
* Constructor * Constructor
* @param null $id * @param null $id
*/ */

View File

@ -29,6 +29,7 @@ class Cms
{ {
protected $extraSettings; protected $extraSettings;
protected $accounts = [];
protected $noIndex = false; protected $noIndex = false;
protected $pluginSettings = []; protected $pluginSettings = [];
@ -44,42 +45,42 @@ class Cms
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')] #[ORM\GeneratedValue(strategy: 'IDENTITY')]
private $uid; private $uid;
/** /**
* Titel * Titel
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'title', type: 'string', length: 255)] #[ORM\Column(name: 'title', type: 'string', length: 255)]
protected $title; protected $title;
/** /**
* Sort * Sort
* *
* @var float * @var float
*/ */
#[ORM\Column(name: 'sor', type: 'integer')] #[ORM\Column(name: 'sor', type: 'integer')]
protected $sort; protected $sort;
/** /**
* Enable * Enable
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'enable', type: 'boolean')] #[ORM\Column(name: 'enable', type: 'boolean')]
protected $enable; protected $enable;
/** /**
* Pos * Pos
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'pos', type: 'text')] #[ORM\Column(name: 'pos', type: 'text')]
protected $pos; protected $pos;
/** /**
* Menu * Menu
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'menu', type: 'text')] #[ORM\Column(name: 'menu', type: 'text')]
protected $menu; protected $menu;
/** /**
* Shop zu welcher zu dem Shop gehört * Shop zu welcher zu dem Shop gehört
* *
* @var int * @var int
@ -87,121 +88,121 @@ class Cms
#[ORM\ManyToOne(targetEntity: 'Shop')] #[ORM\ManyToOne(targetEntity: 'Shop')]
#[ORM\JoinColumn(name: 'shop_id', referencedColumnName: 'id')] #[ORM\JoinColumn(name: 'shop_id', referencedColumnName: 'id')]
protected $shop; protected $shop;
/** /**
* Text * Text
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'text1', type: 'text')] #[ORM\Column(name: 'text1', type: 'text')]
protected $text; protected $text;
/** /**
* NotInMenu * NotInMenu
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'notinmenu', type: 'boolean')] #[ORM\Column(name: 'notinmenu', type: 'boolean')]
protected $notInMenu; protected $notInMenu;
#[ORM\Column(name: 'url', length: 255, unique: true)] #[ORM\Column(name: 'url', length: 255, unique: true)]
protected $url; protected $url;
/** /**
* Language * Language
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'language', type: 'string')] #[ORM\Column(name: 'language', type: 'string')]
protected $language; protected $language;
/** /**
* private * private
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'private', type: 'boolean')] #[ORM\Column(name: 'private', type: 'boolean')]
protected $private; protected $private;
/** /**
* displayTitle * displayTitle
* *
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'display_title', type: 'boolean')] #[ORM\Column(name: 'display_title', type: 'boolean')]
protected $displayTitle; protected $displayTitle;
/** /**
* @var boolean * @var boolean
*/ */
#[ORM\Column(name: 'display_only_logged_in', type: 'boolean')] #[ORM\Column(name: 'display_only_logged_in', type: 'boolean')]
protected $displayOnlyWhenLoggedIn; protected $displayOnlyWhenLoggedIn;
/** /**
* metaKeywords * metaKeywords
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_keywords', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_keywords', type: 'string', nullable: true)]
protected $metaKeywords; protected $metaKeywords;
/** /**
* metaAuthor * metaAuthor
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_author', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_author', type: 'string', nullable: true)]
protected $metaAuthor; protected $metaAuthor;
/** /**
* metaDescription * metaDescription
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_description', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_description', type: 'string', nullable: true)]
protected $metaDescription; protected $metaDescription;
/** /**
* metaCustomTitle * metaCustomTitle
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_custom_title', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_custom_title', type: 'string', nullable: true)]
protected $metaCustomTitle; protected $metaCustomTitle;
/** /**
* metaOgTitle * metaOgTitle
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_og_title', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_og_title', type: 'string', nullable: true)]
protected $metaOgTitle; protected $metaOgTitle;
/** /**
* metaOgType * metaOgType
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_og_type', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_og_type', type: 'string', nullable: true)]
protected $metaOgType; protected $metaOgType;
/** /**
* metaOgUrl * metaOgUrl
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_og_url', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_og_url', type: 'string', nullable: true)]
protected $metaOgUrl; protected $metaOgUrl;
/** /**
* metaOgImage * metaOgImage
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_og_image', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_og_image', type: 'string', nullable: true)]
protected $metaOgImage; protected $metaOgImage;
/** /**
* metaOgDescription * metaOgDescription
* *
* @var string * @var string
*/ */
#[ORM\Column(name: 'meta_og_description', type: 'string', nullable: true)] #[ORM\Column(name: 'meta_og_description', type: 'string', nullable: true)]
protected $metaOgDescription; protected $metaOgDescription;
/** /**
* Parent * Parent
* *
* @var integer * @var integer
*/ */
#[ORM\Column(name: 'parent', type: 'integer')] #[ORM\Column(name: 'parent', type: 'integer')]
protected $parentRaw; protected $parentRaw;
#[ORM\OneToMany(targetEntity: 'Cms', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Cms', mappedBy: 'parent')]
private $children; private $children;
#[ORM\ManyToOne(targetEntity: 'Cms', inversedBy: 'children')] #[ORM\ManyToOne(targetEntity: 'Cms', inversedBy: 'children')]
#[ORM\JoinColumn(name: 'parent', referencedColumnName: 'id')] #[ORM\JoinColumn(name: 'parent', referencedColumnName: 'id')]
private $parent; private $parent;
@ -693,4 +694,13 @@ class Cms
{ {
$this->noIndex = $noIndex; $this->noIndex = $noIndex;
} }
public function getAccounts(): array
{
return (array)$this->accounts;
}
public function setAccounts(array $var): void
{
$this->accounts = $var;
}
} }

View File

@ -1,25 +1,25 @@
{% extends 'form_div_layout.html.twig' %} {% extends 'form_div_layout.html.twig' %}
{% block media_image_widget %} {% block media_image_widget %}
{% apply spaceless %} {% apply spaceless %}
<div class="imageHolder_{{ id }}"> <div class="imageHolder_{{ id }}">
</div> </div>
{{ block('hidden_widget') }} {{ block('hidden_widget') }}
<button class="btn btn-info btn_{{ id }}">Bild auswählen</button> <button class="btn btn-info btn_{{ id }}">Bild auswählen</button>
<script> <script>
$(function() { window.addEventListener("load", (event) => {
$('.btn_{{ id }}').click(function() { document.querySelector('.btn_{{ id }}').addEventListener("click", (event) => {
window.open( window.open(
"{{ path('psc_shop_media_backend_folder_show', {uuid: 0, modal: 1, htmlId: id}) }}", "{{ path('psc_shop_media_backend_folder_show', {uuid: 0, modal: 1, htmlId: id}) }}",
"", "",
"width=1000, height=600, resizable=yes, scrollbars=no, status=no, toolbar=no" "width=1000, height=600, resizable=yes, scrollbars=no, status=no, toolbar=no"
); );
return false; return false;
})
}); });
}); </script>
</script> {% endapply %}
{% endapply %}
{% endblock %} {% endblock %}

View File

@ -13,6 +13,7 @@
namespace PSC\Shop\NewsBundle\Form\Backend; namespace PSC\Shop\NewsBundle\Form\Backend;
use PSC\Libraries\AceEditorBundle\Form\Extension\CKEditor5Type;
use PSC\System\PluginBundle\Form\Chain\Field; use PSC\System\PluginBundle\Form\Chain\Field;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
@ -51,7 +52,7 @@ class NewsType extends AbstractType
'Englisch' => 'en_EN' 'Englisch' => 'en_EN'
], ],
'required' => true]) 'required' => true])
->add('text', TextareaType::class, array( ->add('text', CKEditor5Type::class, array(
'label' => 'Text', 'label' => 'Text',
'required' => false 'required' => false
)); ));

View File

@ -1,154 +1,135 @@
{% extends 'backend_base.html.twig' %} {% extends 'backend_tailwind_base.html.twig' %}
{% form_theme form 'tailwind_formtheme.html.twig' %}
{% trans_default_domain 'core_news_edit' %} {% 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 }} {{ 'edit'|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">
<div class="header"> {{ form_start(form, {attr: {class: ''}}) }}
<div class="row"> <div class="tab-group flex-none md:flex w-full" data-dui-orientation="vertical">
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6"> <div role="tablist" class="relative mr-5 rounded-sm flex flex-col p-1 w-full md:w-2/12">
<h3> <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>
<i class="fa-fw fa fa-newspaper"></i> <a href="#" class="tab-link flex items-center text-sm active px-4 py-2 relative" data-dui-tab-target="all">
{{'News'|trans}} <span>> <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">
{{'edit'|trans}} </span> <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>
</h3> <path d="M3.52844 7.29357L11.7086 11.8381C11.8898 11.9388 12.1102 11.9388 12.2914 11.8381L20.5 7.27777" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
</div> <path d="M12 21L12 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 text-end"> <path d="M11.6914 11.8285L3.89139 7.49521C3.49147 7.27304 3 7.56222 3 8.01971V16.647C3 16.8649 3.11813 17.0656 3.30861 17.1715L11.1086 21.5048C11.5085 21.727 12 21.4378 12 20.9803V12.353C12 12.1351 11.8819 11.9344 11.6914 11.8285Z" fill="currentColor" stroke="currentColor" stroke-linejoin="round"></path>
<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> {{'back'|trans}}</a> </svg> {{ 'General'|trans }}</a>
</div> <a href="#" class="tab-link flex items-center text-sm px-4 py-2 text-gray-700 relative" data-dui-tab-target="text">
</div> <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">
</div> <path d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M4.271 18.3457C4.271 18.3457 6.50002 15.5 12 15.5C17.5 15.5 19.7291 18.3457 19.7291 18.3457" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
<div class="body"> <path d="M12 12C13.6569 12 15 10.6569 15 9C15 7.34315 13.6569 6 12 6C10.3431 6 9 7.34315 9 9C9 10.6569 10.3431 12 12 12Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
{{ form_start(form, { 'attr': {'class': ''}}) }} </svg> {{ 'Text'|trans }}</a>
<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">{{'General'|trans}}</a>
</li>
<li class="nav-item">
<a class="nav-link" data-bs-toggle="tab" href="#text" role="tab">{{'Text'|trans}}</a>
</li>
{% for customGroup in customGroups %} {% for customGroup in customGroups %}
<li class="nav-item"> <a href="#" class="tab-link flex items-center text-sm px-4 py-2 text-gray-700 relative" data-dui-tab-target="{{ customGroup.id }}">
<a class="nav-link" data-bs-toggle="tab" href="#{{ customGroup.id }}" role="tab">{{ customGroup.title }}</a> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="button-icon">
</li> <path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
</svg>
{{ customGroup.title }} </a>
{% endfor %} {% endfor %}
</ul>
</div> </div>
<div class="col-md-10"> <div class="rounded-sm w-full border bg-white p-5 bg-lime-600 shadow-lg dark:border-strokedark dark:bg-boxdark">
<div class="tab-content"> <div id="all" class="tab-content w-full text-stone-500 text-sm block grid grid-col-4">
<div class="tab-pane active" id="all" role="tabpanel"> <h6 class="text-sm mt-3 mb-6 font-bold uppercase">
<div class="row"> {{ 'General'|trans }}
<div class="col-md-4"> </h6>
<div class="row mb-3">
<label class="col-md-3 form-control-label">{{ form_label(form.title) }}</label>
<div class="col-md-9"> <div class="flex flex-wrap">
{{ form_widget(form.title) }} <div class="w-full lg:w-6/12 px-4">
{{ form_row(form.title) }}
</div>
<div class="w-full lg:w-6/12 px-4">
{{ form_row(form.url) }}
</div> </div>
</div> </div>
<div class="flex flex-wrap">
<div class="w-full md:w-2/12 px-4 content-center">
{{ form_widget(form.enable)}}
</div> </div>
<div class="col-md-4"> <div class="w-full md:w-5/12 px-4">
<div class="row mb-3"> {{ form_row(form.sortDate)}}
<label class="col-md-3 form-control-label">{{ form_label(form.url) }}</label> </div>
<div class="col-md-9"> <div class="w-full md:w-5/12 px-4">
{{ form_widget(form.url) }} {{ form_row(form.language)}}
</div> </div>
</div> </div>
</div> <div class="w-full px-4">
<div class="col-md-4"> {{ form_row(form.introduction)}}
<div class="row">
<div class="col-md-6">{{ form_widget(form.enable) }}</div>
</div> </div>
</div> </div>
</div> <div id="text" class="tab-content w-full text-stone-500 text-sm hidden p-4">
<div class="row"> {{ form_widget(form.text) }}
<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> </div>
{% for customGroup in customGroups %} {% for customGroup in customGroups %}
<div class="tab-pane" id="{{ customGroup.id }}" role="tabpanel"> <div class="tab-pane" id="{{ customGroup.id }}" role="tabpanel">
{% for customField in customFields %} {% for customField in customFields %}
{% if customField.group == customGroup.id and customField.getTemplate %} {% if customField.group == customGroup.id and customField.getTemplate %}
{{ include(customField.getTemplate, { 'form': form }) }} {{ include(customField.getTemplate, {form: form}) }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div> <div class="text-end my-2">
</div> {{ form_widget(form.save, {attr: {class: 'psc-button-save'}}) }}
</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> </div>
{{ form_end(form) }} {{ form_end(form) }}
</div> </div>
{{ summernote_mediabundle_init('default') }} <h4 class="text-psc text-xl font-medium flex flex-row gap-1 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="button-icon">
<div class="panel"> <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" />
<div class="header"> </svg>
<h4>{{ '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="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">
{{ 'Date'|trans }}
</div>
<div class="col-span-1 px-6 py-3">
{{ 'Username'|trans }}
</div>
<div class="col-span-2 px-6 py-3">
{{ 'Changes'|trans }}
</div>
</div> </div>
<div class="body">
<table class="table">
<thead>
<tr><th>{{ 'Date'|trans }}</th><th>{{ 'Username'|trans }}</th><th>{{'Changes'|trans}}</th></tr>
</thead>
<tbody>
{% for change in changes %} {% for change in changes %}
<tr><td>{{ change.created|date('H:i:s d.m.Y') }}</td><td>{{ change.username }}</td><td> <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">
{% for key,set in change.changeset %} <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 %} {% 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> <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 %} {% endif %}
{% endfor %} {% endfor %}
<td></tr> </div>
</div>
{% endfor %} {% endfor %}
</tbody>
</table> </div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -64,14 +64,7 @@ class EditController extends AbstractController
$this->logService = $logService; $this->logService = $logService;
$this->historyService = $historyService; $this->historyService = $historyService;
} }
/**
* edit
*
* @param Request $request
* @param EntityManagerInterface $entityManager
* @param $uid
* @return JsonResponse
*/
#[Route(path: '/edit/save/lang/data/{uid}', name: 'backend_production_product_edit_save_lang_data')] #[Route(path: '/edit/save/lang/data/{uid}', name: 'backend_production_product_edit_save_lang_data')]
public function saveLangDataAction(Request $request, EntityManagerInterface $entityManager, $uid) public function saveLangDataAction(Request $request, EntityManagerInterface $entityManager, $uid)
{ {
@ -83,11 +76,11 @@ class EditController extends AbstractController
$tmp = $product->getLangData(); $tmp = $product->getLangData();
$tmp[$request->get('langcode')] = [ $tmp[$request->getPayload()->get('langcode')] = [
'title' => $request->get('title'), 'title' => $request->getPayload()->get('title'),
'einleitung' => $request->get('einleitung'), 'einleitung' => $request->getPayload()->get('einleitung'),
'text_art' => $request->get('text_art'), 'text_art' => $request->getPayload()->get('text_art'),
'info' => $request->get('info'), 'info' => $request->getPayload()->get('info'),
'uuid' => Uuid::uuid4() 'uuid' => Uuid::uuid4()
]; ];
@ -96,7 +89,7 @@ class EditController extends AbstractController
$entityManager->flush(); $entityManager->flush();
} }
return new JsonResponse(['success' => true, 'langcode' => $request->get('langcode')]); return new JsonResponse(['success' => true, 'langcode' => $request->getPayload()->get('langcode')]);
} }
/** /**
@ -113,12 +106,11 @@ class EditController extends AbstractController
$product = $entityManager $product = $entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findOneBy(['uid' => $uid]); ->getRepository('PSC\Shop\EntityBundle\Entity\Product')->findOneBy(['uid' => $uid]);
if ($product) { if ($product) {
$tmp = $product->getLangData(); $tmp = $product->getLangData();
if (!isset($tmp[$request->get('langcode')])) { if (!isset($tmp[$request->getPayload()->get('langcode')])) {
$tmp[$request->get('langcode')] = ['title' => $product->getTitle(), 'einleitung' => '', 'text_art' => '', 'info' => '', 'uuid' => Uuid::uuid4()]; $tmp[$request->getPayload()->get('langcode')] = ['title' => $product->getTitle(), 'einleitung' => '', 'text_art' => '', 'info' => '', 'uuid' => Uuid::uuid4()];
$product->setLangData($tmp); $product->setLangData($tmp);
$entityManager->persist($product); $entityManager->persist($product);
@ -126,7 +118,7 @@ class EditController extends AbstractController
} }
} }
return new JsonResponse(['success' => true, 'langcode' => $request->get('langcode')]); return new JsonResponse(['success' => true, 'langcode' => $request->getPayload()->get('langcode')]);
} }
/** /**

View File

@ -80,23 +80,15 @@ class EditController extends AbstractController
->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]); ->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]);
if ($productgroup) { if ($productgroup) {
$tmp = $productgroup->getLangData(); $tmp = $productgroup->getLangData();
$tmp[$request->get('langcode')] = ['title' => $request->get('title'), 'uuid' => Uuid::uuid4()]; $tmp[$request->getPayload()->get('langcode')] = ['title' => $request->getPayload()->get('title'), 'uuid' => Uuid::uuid4()];
$productgroup->setLangData($tmp); $productgroup->setLangData($tmp);
$entityManager->persist($productgroup); $entityManager->persist($productgroup);
$entityManager->flush(); $entityManager->flush();
} }
return new JsonResponse(['success' => true, 'langcode' => $request->get('langcode')]); return new JsonResponse(['success' => true, 'langcode' => $request->getPayload()->get('langcode')]);
} }
/**
* edit
*
* @param Request $request
* @param EntityManagerInterface $entityManager
* @param $uid
* @return JsonResponse
*/
#[Route(path: '/edit/add/lang/data/{uid}', name: 'backend_production_productgroup_edit_add_lang_data')] #[Route(path: '/edit/add/lang/data/{uid}', name: 'backend_production_productgroup_edit_add_lang_data')]
public function addLangDataAction( public function addLangDataAction(
Request $request, Request $request,
@ -107,15 +99,15 @@ class EditController extends AbstractController
->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]); ->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]);
if ($productgroup) { if ($productgroup) {
$tmp = $productgroup->getLangData(); $tmp = $productgroup->getLangData();
if (!isset($tmp[$request->get('langcode')])) { if (!isset($tmp[$request->getPayload()->get('langcode')])) {
$tmp[$request->get('langcode')] = ['title' => $productgroup->getTitle(), 'uuid' => Uuid::uuid4()]; $tmp[$request->getPayload()->get('langcode')] = ['title' => $productgroup->getTitle(), 'uuid' => Uuid::uuid4()];
$productgroup->setLangData($tmp); $productgroup->setLangData($tmp);
$entityManager->persist($productgroup); $entityManager->persist($productgroup);
$entityManager->flush(); $entityManager->flush();
} }
} }
return new JsonResponse(['success' => true, 'langcode' => $request->get('langcode')]); return new JsonResponse(['success' => true, 'langcode' => $request->getPayload()->get('langcode')]);
} }
/** /**
@ -204,7 +196,7 @@ class EditController extends AbstractController
{ {
$customFields = $fieldService->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup); $customFields = $fieldService->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup);
$customGroups = $fieldService->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup); $customGroups = $fieldService->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
$productgroup = new Productgroup(); $productgroup = new Productgroup();
$productgroup->setShop($selectedShop); $productgroup->setShop($selectedShop);
@ -268,11 +260,11 @@ class EditController extends AbstractController
$customFields = $fieldService->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup); $customFields = $fieldService->getFields(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup);
$customGroups = $fieldService->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup); $customGroups = $fieldService->getGroups(\PSC\System\PluginBundle\Form\Interfaces\Field::Productgroup);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
/** @var Productgroup $productgroup */ /** @var Productgroup $productgroup */
$productgroup = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]); $productgroup = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]);
/** @var \PSC\Shop\EntityBundle\Document\Productgroup $productGroupDoc */ /** @var \PSC\Shop\EntityBundle\Document\Productgroup $productGroupDoc */
$productGroupDoc = $documentManager $productGroupDoc = $documentManager
->getRepository('PSC\Shop\EntityBundle\Document\Productgroup') ->getRepository('PSC\Shop\EntityBundle\Document\Productgroup')
->findOneBy(array('uid' => (string)$productgroup->getUid())); ->findOneBy(array('uid' => (string)$productgroup->getUid()));
@ -334,7 +326,7 @@ class EditController extends AbstractController
/** @var Productgroup $productgroup */ /** @var Productgroup $productgroup */
$productgroup = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]); $productgroup = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findOneBy(['uid' => $uid]);
$subGroups = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findByParent($uid); $subGroups = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Productgroup')->findByParent($uid);
/** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */ /** @var \PSC\Shop\EntityBundle\Entity\Shop $selectedShop */
$selectedShop = $shopService->getSelectedShop(); $selectedShop = $shopService->getSelectedShop();
if (count($subGroups) > 0) { if (count($subGroups) > 0) {
$session->getFlashBag()->add('danger', 'Productgroup \'' . $productgroup->getTitle() . '\' has subgroups and can not be deleted!'); $session->getFlashBag()->add('danger', 'Productgroup \'' . $productgroup->getTitle() . '\' has subgroups and can not be deleted!');

View File

@ -136,6 +136,7 @@ class ProductType extends AbstractType
} }
}, },
'multiple' => true, 'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) { 'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop')->setParameter('shop', $this->shop->getSelectedShop()->getId());
@ -145,6 +146,7 @@ class ProductType extends AbstractType
'class' => 'PSC\Shop\EntityBundle\Entity\Product', 'class' => 'PSC\Shop\EntityBundle\Entity\Product',
'choice_label' => 'title', 'choice_label' => 'title',
'multiple' => true, 'multiple' => true,
'required' => false,
'query_builder' => function (EntityRepository $er) { 'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u') return $er->createQueryBuilder('u')
->where('u.shop = :shop AND u.originalProduct = 0')->setParameter('shop', $this->shop->getSelectedShop()->getId()); ->where('u.shop = :shop AND u.originalProduct = 0')->setParameter('shop', $this->shop->getSelectedShop()->getId());

View File

@ -934,34 +934,35 @@
{{ parent() }} {{ parent() }}
<script type="module"> <script type="module">
var wto; let wto;
import $ from 'jquery' window.addEventListener("load", (event) => {
$(function() { document.querySelector('#product_url').addEventListener("keyup", (event) => {
$('#product_url').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#product_url').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/product/edit/check/url/" + event.srcElement.value)
$.getJSON("/apps/backend/product/edit/check/url/" + $('#product_url').val(),[], function(data) { .then((result) => {
$('#product_url').removeClass('is-valid'); return result.json();
$('#product_url').removeClass('is-invalid'); })
$('#product_url').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#product_url').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#product_url').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#product_url').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
})
}));
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1106,86 +1106,99 @@ a[href^="#formlayouter"] {display:none;}
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
<script type="module"> <script type="module">
import $ from 'jquery' let wto;
var wto; window.addEventListener("load", (event) => {
document.querySelector('#product_url').addEventListener("keyup", (event) => {
function loadLangData() {
$('#lang table tbody').empty();
$.getJSON("/apps/backend/product/edit/fetch/lang/data/" + {{ product.uid }},[], function(data) {
$(data.langData).each(function(index, row) {
$('#lang table tbody').append('<tr><td>' + row.code + '</td><td><input type="text" data-id="' + row.uuid + '" class="title form-control form-control-sm" value="' + row.title + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="einleitung form-control form-control-sm" value="' + row.einleitung + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="text_art form-control form-control-sm" value="' + row.text_art + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="info form-control form-control-sm" value="' + row.info + '"/></td><td><button data-langcode="' + row.code + '" type="button" class="btn btn-success btn-sm saveLang">Speichern</button></td></tr>');
});
$('.saveLang').click(function() {
var elm = $(this);
elm.parent().parent().find('input.title').removeClass('is-valid');
elm.parent().parent().find('input.text_art').removeClass('is-valid');
elm.parent().parent().find('input.einleitung').removeClass('is-valid');
elm.parent().parent().find('input.info').removeClass('is-valid');
$.getJSON("/apps/backend/product/edit/save/lang/data/" + {{ product.uid }},{
langcode : elm.data('langcode'),
title: elm.parent().parent().find('input.title').val(),
text_art: elm.parent().parent().find('input.text_art').val(),
einleitung: elm.parent().parent().find('input.einleitung').val(),
info: elm.parent().parent().find('input.info').val()
}, function(data) {
elm.parent().parent().find('input.title').addClass('is-valid');
elm.parent().parent().find('input.text_art').addClass('is-valid');
elm.parent().parent().find('input.einleitung').addClass('is-valid');
elm.parent().parent().find('input.info').addClass('is-valid');
});
});
});
};
$(function() {
loadLangData();
$('#addLang').change(function() {
$.getJSON("/apps/backend/product/edit/add/lang/data/" + {{ product.uid }},{ langcode : $(this).find('option:selected').attr('id') }, function(data) {
loadLangData();
});
});
$('#product_url').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#product_url').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/product/edit/check/url/" + event.srcElement.value)
$.getJSON("/apps/backend/product/edit/check/url/" + $('#product_url').val(),[], function(data) { .then((result) => {
$('#product_url').removeClass('is-valid'); return result.json();
$('#product_url').removeClass('is-invalid'); })
$('#product_url').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#product_url').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#product_url').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#product_url').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
}));
}); });
document.querySelector('#addLang').addEventListener("change", (event) => {
fetch("/apps/backend/product/edit/add/lang/data/" + {{ product.uid }}, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
langcode : event.srcElement.options[event.srcElement.selectedIndex].id
})
}).
then((result) => {
loadLangData();
});
});
loadLangData();
});
function loadLangData() {
document.querySelectorAll('#lang table tbody tr').forEach((elm) => {
elm.remove();
})
fetch("/apps/backend/product/edit/fetch/lang/data/" + {{ product.uid }}).
then((result) => { return result.json() }).
then((data) => {
data.langData.forEach(function(row, index, array) {
document.querySelector('#lang table tbody').insertAdjacentHTML('afterend', '<tr><td>' + row.code + '</td><td><input type="text" data-id="' + row.uuid + '" class="title form-control form-control-sm" value="' + row.title + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="einleitung form-control form-control-sm" value="' + row.einleitung + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="text_art form-control form-control-sm" value="' + row.text_art + '"/></td><td><input type="text" data-id="' + row.uuid + '" class="info form-control form-control-sm" value="' + row.info + '"/></td><td><button data-langcode="' + row.code + '" type="button" class="btn btn-success btn-sm saveLang">Speichern</button></td></tr>');
});
document.querySelectorAll('.saveLang').forEach((btn) => {
btn.addEventListener('click', (event) => {
let elm = event.srcElement;
elm.parentElement.parentElement.querySelector('input.title').classList.remove('is-valid');
elm.parentElement.parentElement.querySelector('input.text_art').classList.remove('is-valid');
elm.parentElement.parentElement.querySelector('input.einleitung').classList.remove('is-valid');
elm.parentElement.parentElement.querySelector('input.info').classList.remove('is-valid');
fetch("/apps/backend/product/edit/save/lang/data/" + {{ product.uid }}, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
langcode : elm.dataset.langcode,
title: elm.parentElement.parentElement.querySelector('input.title').value,
text_art: elm.parentElement.parentElement.querySelector('input.text_art').value,
einleitung: elm.parentElement.parentElement.querySelector('input.einleitung').value,
info: elm.parentElement.parentElement.querySelector('input.info').value
})
}).then((result) => {
elm.parentElement.parentElement.querySelector('input.title').classList.add('is-valid');
elm.parentElement.parentElement.querySelector('input.text_art').classList.add('is-valid');
elm.parentElement.parentElement.querySelector('input.einleitung').classList.add('is-valid');
elm.parentElement.parentElement.querySelector('input.info').classList.add('is-valid');
});
});
})
});
};
</script> </script>
{% endblock %} {% endblock %}

View File

@ -319,32 +319,34 @@
<script> <script>
var wto; var wto;
window.addEventListener("load", (event) => {
$(function() { document.querySelector('#productgroup_url').addEventListener("keyup", (event) => {
$('#productgroup_url').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#productgroup_url').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/productgroup/edit/check/url/" + event.srcElement.value)
$.getJSON("/apps/backend/productgroup/edit/check/url/" + $('#productgroup_url').val(),[], function(data) { .then((result) => {
$('#productgroup_url').removeClass('is-valid'); return result.json();
$('#productgroup_url').removeClass('is-invalid'); })
$('#productgroup_url').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#productgroup_url').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#productgroup_url').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#productgroup_url').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
});
}));
}); });
</script> </script>

View File

@ -362,76 +362,88 @@
<script> <script>
var wto; var wto;
window.addEventListener("load", (event) => {
function loadLangData() { document.querySelector('#productgroup_edit_url').addEventListener("keyup", (event) => {
$('#lang table tbody').empty();
$.getJSON("/apps/backend/productgroup/edit/fetch/lang/data/" + {{ productgroup.uid }},[], function(data) {
$(data.langData).each(function(index, row) {
$('#lang table tbody').append('<tr><td>' + row.code + '</td><td><input type="text" data-id="' + row.uuid + '" class="form-control form-control-sm" value="' + row.title + '"/></td><td><button data-langcode="' + row.code + '" type="button" class="btn btn-success btn-sm saveLang">Speichern</button></td></tr>');
});
$('.saveLang').click(function() {
var elm = $(this);
elm.parent().parent().find('input').removeClass('is-valid');
$.getJSON("/apps/backend/productgroup/edit/save/lang/data/" + {{ productgroup.uid }},{
langcode : elm.data('langcode'),
title: elm.parent().parent().find('input').val()
}, function(data) {
elm.parent().parent().find('input').addClass('is-valid');
});
});
});
};
$(function() {
loadLangData();
$('#addLang').change(function() {
$.getJSON("/apps/backend/productgroup/edit/add/lang/data/" + {{ productgroup.uid }},{ langcode : $(this).find('option:selected').attr('id') }, function(data) {
loadLangData();
});
});
$('#productgroup_url').on('keyup', (function() {
clearTimeout(wto); clearTimeout(wto);
wto = setTimeout(function() { wto = setTimeout(function() {
if($('#productgroup_url').val() != "") { if(event.srcElement.value != "") {
fetch("/apps/backend/productgroup/edit/check/url/" + event.srcElement.value)
$.getJSON("/apps/backend/productgroup/edit/check/url/" + $('#productgroup_url').val(),[], function(data) { .then((result) => {
$('#productgroup_url').removeClass('is-valid'); return result.json();
$('#productgroup_url').removeClass('is-invalid'); })
$('#productgroup_url').parent().find('.invalid-feedback').remove(); .then((data) => {
event.srcElement.classList.remove('is-valid');
event.srcElement.classList.remove('is-invalid');
if(event.srcElement.parentElement.querySelector('.invalid-feedback')) {
event.srcElement.parentElement.querySelector('.invalid-feedback').remove();
}
if(data.found) { if(data.found) {
$('#productgroup_url').addClass('is-invalid'); event.srcElement.classList.add('is-invalid');
$('#productgroup_url').after('<div class="invalid-feedback">\n' + let elm = document.createElement('div');
'Schon vorhanden: ' + data.error + '\n' + elm.classList.add('invalid-feedback');
'</div>'); elm.append(new Text('Schon vorhanden: ' + data.error))
event.srcElement.after(elm);
}else{ }else{
$('#productgroup_url').addClass('is-valid'); event.srcElement.classList.add('is-valid');
} }
}); });
} }
}, 1000); }, 1000);
}));
}); });
document.querySelector('#addLang').addEventListener("change", (event) => {
fetch("/apps/backend/productgroup/edit/add/lang/data/" + {{ productgroup.uid }}, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
langcode : event.srcElement.options[event.srcElement.selectedIndex].id
})
}).
then((result) => {
loadLangData();
});
});
loadLangData();
});
function loadLangData() {
document.querySelectorAll('#lang table tbody tr').forEach((elm) => {
elm.remove();
})
fetch("/apps/backend/productgroup/edit/fetch/lang/data/" + {{ productgroup.uid }}).
then((result) => { return result.json() }).
then((data) => {
data.langData.forEach(function(row, index, array) {
document.querySelector('#lang table tbody').insertAdjacentHTML('afterend', '<tr><td>' + row.code + '</td><td><input type="text" data-id="' + row.uuid + '" class="title form-control form-control-sm" value="' + row.title + '"/></td><td><button data-langcode="' + row.code + '" type="button" class="btn btn-success btn-sm saveLang">Speichern</button></td></tr>');
});
document.querySelectorAll('.saveLang').forEach((btn) => {
btn.addEventListener('click', (event) => {
let elm = event.srcElement;
elm.parentElement.parentElement.querySelector('input.title').classList.remove('is-valid');
fetch("/apps/backend/productgroup/edit/save/lang/data/" + {{ productgroup.uid }}, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
langcode : elm.dataset.langcode,
title: elm.parentElement.parentElement.querySelector('input.title').value,
})
}).then((result) => {
elm.parentElement.parentElement.querySelector('input.title').classList.add('is-valid');
});
});
})
});
};
</script> </script>
{% endblock %} {% endblock %}

View File

@ -13,9 +13,9 @@ class Url
*/ */
#[Field(type: 'string')] #[Field(type: 'string')]
protected $url; protected $url;
/** #[Field(type: 'string')]
* @return string protected $message;
*/
public function getUrl() public function getUrl()
{ {
return $this->url; return $this->url;
@ -28,4 +28,14 @@ class Url
{ {
$this->url = $url; $this->url = $url;
} }
public function setMessage(?string $message): void
{
$this->message = $message;
}
public function getMessage(): string
{
return (string)$this->message;
}
} }

View File

@ -14,5 +14,15 @@
</div> </div>
</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.message) }}</label>
<div class="col-md-11">
{{ form_widget(form.message) }}
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -8,10 +8,13 @@ use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use LogicException; use LogicException;
use PSC\Libraries\AceEditorBundle\Form\Extension\AceEditorType;
use PSC\Shop\EntityBundle\Document\Queue; use PSC\Shop\EntityBundle\Document\Queue;
use PSC\Shop\QueueBundle\Event\EventInterface; use PSC\Shop\QueueBundle\Event\EventInterface;
use PSC\Shop\QueueBundle\Event\Order\Create;
use PSC\Shop\QueueBundle\Event\Position\Printpartner\Notify; use PSC\Shop\QueueBundle\Event\Position\Printpartner\Notify;
use PSC\System\PluginBundle\Event\EveryRun; use PSC\System\PluginBundle\Event\EveryRun;
use PSC\System\SettingsBundle\Service\TemplateVars;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Form; use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
@ -27,11 +30,16 @@ class Url implements QueueInterface, ConfigurableElementInterface
private $_entityManager = null; private $_entityManager = null;
private $_doctrine_mongodb = null; private $_doctrine_mongodb = null;
private $_error = null; private $_error = null;
function __construct(FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, DocumentManager $doctrine_mongodb) private $_template = null;
protected $_templateVars = null;
public function __construct(TemplateVars $templateVars, FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, DocumentManager $doctrine_mongodb, \Twig\Environment $template)
{ {
$this->_formFactory = $formFactory; $this->_formFactory = $formFactory;
$this->_entityManager = $entityManager; $this->_entityManager = $entityManager;
$this->_doctrine_mongodb = $doctrine_mongodb; $this->_doctrine_mongodb = $doctrine_mongodb;
$this->_template = $template;
$this->_templateVars = $templateVars;
} }
/** /**
@ -63,18 +71,35 @@ class Url implements QueueInterface, ConfigurableElementInterface
public function getForm(FormBuilderInterface $builder, $form_options, EventInterface $event) public function getForm(FormBuilderInterface $builder, $form_options, EventInterface $event)
{ {
$builder->add("url", TextType::class, array('label' => 'Url', 'attr' => array('class' => 'form-element'))); $builder->add("url", TextType::class, array('label' => 'Url', 'attr' => array('class' => 'form-element')));
$builder->add("message", AceEditorType::class, array(
'wrapper_attr' => array(), // aceeditor wrapper html attributes.
'width' => '100%',
'height' => '500',
'font_size' => 14,
'mode' => 'ace/mode/json', // every single default mode must have ace/mode/* prefix
'theme' => 'ace/theme/monokai', // every single default theme must have ace/theme/* prefix
'tab_size' => null,
'read_only' => null,
'use_soft_tabs' => null,
'use_wrap_mode' => null,
'show_print_margin' => null,
'required' => false,
'highlight_active_line' => null,
'label' => 'Message', 'attr' => array('class' => 'form-element')));
} }
public function injectDocument(Form $form, EventInterface $event, Queue $objQueue) public function injectDocument(Form $form, EventInterface $event, Queue $objQueue)
{ {
$url = new \PSC\Shop\QueueBundle\Document\Queue\Url(); $url = new \PSC\Shop\QueueBundle\Document\Queue\Url();
$url->setUrl($form->get('url')->getData()); $url->setUrl($form->get('url')->getData());
$url->setMessage($form->get('message')->getData());
$objQueue->setQueueDocument($url); $objQueue->setQueueDocument($url);
} }
public function setFormData(Form $form, EventInterface $event, Queue $queueObj) public function setFormData(Form $form, EventInterface $event, Queue $queueObj)
{ {
$form->get('url')->setData($queueObj->getQueueDocument()->getUrl()); $form->get('url')->setData($queueObj->getQueueDocument()->getUrl());
$form->get('message')->setData($queueObj->getQueueDocument()->getMessage());
} }
public function getTemplate() public function getTemplate()
@ -89,6 +114,7 @@ class Url implements QueueInterface, ConfigurableElementInterface
public function execute(EventInterface $event, Queue $urlDoc) public function execute(EventInterface $event, Queue $urlDoc)
{ {
$templateVars = $this->_templateVars;
/** @var \PSC\Shop\QueueBundle\Document\Queue\Url $doc */ /** @var \PSC\Shop\QueueBundle\Document\Queue\Url $doc */
$doc = $urlDoc->getQueueDocument(); $doc = $urlDoc->getQueueDocument();
try { try {
@ -102,6 +128,24 @@ class Url implements QueueInterface, ConfigurableElementInterface
$client = new Client(); $client = new Client();
$res = $client->request('GET', $doc->getUrl()); $res = $client->request('GET', $doc->getUrl());
} }
if ($event instanceof Create) {
$client = new Client();
$urlTemplate = $this->_template->createTemplate($doc->getUrl());
$messageTemplate = $this->_template->createTemplate($doc->getMessage());
$templateVars->loadOrder($event->getOrder());
$urlString = $urlTemplate->render($templateVars->getTwigVars());
$messageString = $messageTemplate->render($templateVars->getTwigVars());
$res = $client->request(
'POST',
$urlString,
[
'headers' => [
'Accept' => 'application/json',
],
'body' => $messageString
]
);
}
} catch (\Exception $e) { } catch (\Exception $e) {
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
return false; return false;

View File

@ -23,7 +23,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPasspor
class ApiKeyAuthenticator extends AbstractAuthenticator class ApiKeyAuthenticator extends AbstractAuthenticator
{ {
public function __construct(private readonly Instance $instance, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager) public function __construct(private readonly Instance $instance, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager)
{ {
} }
@ -66,7 +65,11 @@ class ApiKeyAuthenticator extends AbstractAuthenticator
$shop = $this->entityManager->getRepository(Shop::class)->findOneBy(['apiKey' => $apiToken]); $shop = $this->entityManager->getRepository(Shop::class)->findOneBy(['apiKey' => $apiToken]);
if ($shop) { if ($shop) {
return new UserBadge($apiToken); return new SelfValidatingPassport(
new UserBadge($shop->getUid(), function () use ($shop) {
return $shop;
})
);
} }
$instance = $this->documentManager $instance = $this->documentManager
@ -74,7 +77,11 @@ class ApiKeyAuthenticator extends AbstractAuthenticator
->findOneBy(['supporttoken' => $apiToken]); ->findOneBy(['supporttoken' => $apiToken]);
if ($instance) { if ($instance) {
return new UserBadge($apiToken); return new SelfValidatingPassport(
new UserBadge($instance->getId(), function () use ($instance) {
return $instance;
})
);
} }
throw new \Exception('No API token provided'); throw new \Exception('No API token provided');

View File

@ -23,7 +23,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPasspor
class ZendAuthenticator extends AbstractAuthenticator class ZendAuthenticator extends AbstractAuthenticator
{ {
public function __construct(private readonly Instance $instance, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager) public function __construct(private readonly Instance $instance, private readonly EntityManagerInterface $entityManager, private readonly DocumentManager $documentManager)
{ {
} }

View File

@ -96,12 +96,12 @@
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
<script> <script>
$(function() { window.addEventListener("load", (event) => {
$('.upgrade').click(function() { document.querySelector('.upgrade').addEventListener("click", (event) => {
$.getJSON('{{ path('psc_backend_system_settings_upgrade') }}', [], function() { fetch('{{ path('psc_backend_system_settings_upgrade') }}').then((result) => {
document.location='{{ path('psc_backend_login') }}'; document.location='{{ path('psc_backend_login') }}';
})
}); });
}) })
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -435,12 +435,12 @@
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
<script> <script>
$(function() { window.addEventListener("load", (event) => {
$('.upgrade').click(function() { document.querySelector('.upgrade').addEventListener("click", (event) => {
$.getJSON('{{ path('psc_backend_system_settings_upgrade') }}', [], function() { fetch('{{ path('psc_backend_system_settings_upgrade') }}').then((result) => {
document.location='{{ path('psc_backend_login') }}'; document.location='{{ path('psc_backend_login') }}';
})
}); });
}) })
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,17 @@
<?php
namespace PSC\System\UpdateBundle\Migrations;
class Version20250702215721 extends Base
{
public function migrateDatabase(): void
{
$this->entityManager->getConnection()->exec("CREATE TABLE `account_cms` (
`account_id` bigint(20) NOT NULL DEFAULT 0,
`cms_id` bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (`account_id`,`cms_id`),
KEY `cms_id` (`cms_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
");
}
}

View File

@ -997,6 +997,15 @@
"twig/twig": { "twig/twig": {
"version": "v2.12.5" "version": "v2.12.5"
}, },
"vincentlanglet/twig-cs-fixer": {
"version": "3.5",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "3.0",
"ref": "d42582ae1bce86fd43491d6264c738b0867f8ffe"
}
},
"webmozart/assert": { "webmozart/assert": {
"version": "1.7.0" "version": "1.7.0"
}, },

View File

@ -59,7 +59,7 @@
{%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%} {%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%}
{% set required = false %} {% set required = false %}
{%- endif -%} {%- endif -%}
{% if multiple %} {% if false and multiple %}
<div class="row"> <div class="row">
<div class="col-5"> <div class="col-5">
<select name="{{ full_name }}_from" id="{{ full_name|md5 }}" class="form-control form-control-sm multiple" size="8" multiple="multiple"> <select name="{{ full_name }}_from" id="{{ full_name|md5 }}" class="form-control form-control-sm multiple" size="8" multiple="multiple">

View File

@ -0,0 +1,522 @@
{# Widgets #}
{%- block form_widget -%}
{% if compound %}
{{- block('form_widget_compound') -}}
{% else %}
{{- block('form_widget_simple') -}}
{% endif %}
{%- endblock form_widget -%}
{%- block form_widget_simple -%}
{%- set type = type|default('text') -%}
{%- if type == 'range' or type == 'color' -%}
{# Attribute "required" is not supported #}
{%- set required = false -%}
{%- endif -%}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{%- endblock form_widget_simple -%}
{%- block form_widget_compound -%}
<div {{ block('widget_container_attributes') }}>
{%- if form is rootform -%}
{{ form_errors(form) }}
{%- endif -%}
{{- block('form_rows') -}}
{{- form_rest(form) -}}
</div>
{%- endblock form_widget_compound -%}
{%- block collection_widget -%}
{% if prototype is defined and not prototype.rendered %}
{%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%}
{% endif %}
{{- block('form_widget') -}}
{%- endblock collection_widget -%}
{%- block textarea_widget -%}
<textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
{%- endblock textarea_widget -%}
{%- block choice_widget -%}
{% if expanded %}
{{- block('choice_widget_expanded') -}}
{% else %}
{{- block('choice_widget_collapsed') -}}
{% endif %}
{%- endblock choice_widget -%}
{%- block choice_widget_expanded -%}
<div {{ block('widget_container_attributes') }}>
{%- for child in form %}
{{- form_widget(child) -}}
{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}
{% endfor -%}
</div>
{%- endblock choice_widget_expanded -%}
{%- block choice_widget_collapsed -%}
{%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%}
{% set required = false %}
{%- endif -%}
{% if false and multiple %}
<div class="row">
<div class="col-5">
<select name="{{ full_name }}_from" id="{{ full_name|md5 }}" class="form-control form-control-sm multiple" size="8" multiple="multiple">
{%- set options = choices -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% if choice is not validateChoice(value) %}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is validateChoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{%- endif -%}
{% endfor %}
</select>
</div>
<div class="col-2">
<button type="button" id="{{ full_name|md5 }}_rightAll" class="btn btn-sm btn-block"><i class="fa fa-forward"></i></button>
<button type="button" id="{{ full_name|md5 }}_rightSelected" class="btn btn-sm btn-block"><i class="fa fa-chevron-right"></i></button>
<button type="button" id="{{ full_name|md5 }}_leftSelected" class="btn btn-sm btn-block"><i class="fa fa-chevron-left"></i></button>
<button type="button" id="{{ full_name|md5 }}_leftAll" class="btn btn-sm btn-block"><i class="fa fa-backward"></i></button>
</div>
<div class="col-5">
<select name="{{ full_name }}" id="{{ full_name|md5 }}_to" class="form-control form-control-sm" size="8" multiple="multiple">
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% if choice is validateChoice(value) %}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is validateChoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{%- endif -%}
{% endfor %}
</select>
</div>
</div>
{% else %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- if placeholder is not none -%}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}</option>
{%- endif -%}
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{% set render_preferred_choices = true %}
{{- block('choice_widget_options') -}}
{%- if choices|length > 0 and separator is not none -%}
<option disabled="disabled">{{ separator }}</option>
{%- endif -%}
{%- endif -%}
{%- set options = choices -%}
{%- set render_preferred_choices = false -%}
{{- block('choice_widget_options') -}}
</select>
{% endif %}
{%- endblock choice_widget_collapsed -%}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if not render_preferred_choices|default(false) and choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans(choice.labelTranslationParameters, choice_translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
{%- block checkbox_widget -%}
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{%- endblock checkbox_widget -%}
{%- block radio_widget -%}
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{%- endblock radio_widget -%}
{%- block datetime_widget -%}
{% if widget == 'single_text' %}
{{- block('form_widget_simple') -}}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form.date) -}}
{{- form_errors(form.time) -}}
{{- form_widget(form.date) -}}
{{- form_widget(form.time) -}}
</div>
{%- endif -%}
{%- endblock datetime_widget -%}
{%- block date_widget -%}
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{{- date_pattern|replace({
'{{ year }}': form_widget(form.year),
'{{ month }}': form_widget(form.month),
'{{ day }}': form_widget(form.day),
})|raw -}}
</div>
{%- endif -%}
{%- endblock date_widget -%}
{%- block time_widget -%}
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
{%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%}
<div {{ block('widget_container_attributes') }}>
{{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %}
</div>
{%- endif -%}
{%- endblock time_widget -%}
{%- block dateinterval_widget -%}
{%- if widget == 'single_text' -%}
{{- block('form_widget_simple') -}}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form) -}}
<table class="{{ table_class|default('') }}" role="presentation">
<thead>
<tr>
{%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%}
{%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%}
{%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%}
{%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%}
{%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%}
{%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%}
{%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%}
</tr>
</thead>
<tbody>
<tr>
{%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%}
{%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%}
{%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%}
{%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%}
{%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%}
{%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%}
{%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%}
</tr>
</tbody>
</table>
{%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
</div>
{%- endif -%}
{%- endblock dateinterval_widget -%}
{%- block number_widget -%}
{# type="number" doesn't work with floats in localized formats #}
{%- set type = type|default('text') -%}
{{ block('form_widget_simple') }}
{%- endblock number_widget -%}
{%- block integer_widget -%}
{%- set type = type|default('number') -%}
{{ block('form_widget_simple') }}
{%- endblock integer_widget -%}
{%- block money_widget -%}
{{ money_pattern|form_encode_currency(block('form_widget_simple')) }}
{%- endblock money_widget -%}
{%- block url_widget -%}
{%- set type = type|default('url') -%}
{{ block('form_widget_simple') }}
{%- endblock url_widget -%}
{%- block search_widget -%}
{%- set type = type|default('search') -%}
{{ block('form_widget_simple') }}
{%- endblock search_widget -%}
{%- block percent_widget -%}
{%- set type = type|default('text') -%}
{{ block('form_widget_simple') }}{% if symbol %} {{ symbol|default('%') }}{% endif %}
{%- endblock percent_widget -%}
{%- block password_widget -%}
{%- set type = type|default('password') -%}
{{ block('form_widget_simple') }}
{%- endblock password_widget -%}
{%- block hidden_widget -%}
{%- set type = type|default('hidden') -%}
{{ block('form_widget_simple') }}
{%- endblock hidden_widget -%}
{%- block email_widget -%}
{%- set type = type|default('email') -%}
{{ block('form_widget_simple') }}
{%- endblock email_widget -%}
{%- block range_widget -%}
{% set type = type|default('range') %}
{{- block('form_widget_simple') -}}
{%- endblock range_widget %}
{%- block button_widget -%}
{%- if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- elseif label is not same as(false) -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{%- if translation_domain is same as(false) -%}
{%- if label_html is same as(false) -%}
{{- label -}}
{%- else -%}
{{- label|raw -}}
{%- endif -%}
{%- else -%}
{%- if label_html is same as(false) -%}
{{- label|trans(label_translation_parameters, translation_domain) -}}
{%- else -%}
{{- label|trans(label_translation_parameters, translation_domain)|raw -}}
{%- endif -%}
{%- endif -%}
</button>
{%- endblock button_widget -%}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{{ block('button_widget') }}
{%- endblock submit_widget -%}
{%- block reset_widget -%}
{%- set type = type|default('reset') -%}
{{ block('button_widget') }}
{%- endblock reset_widget -%}
{%- block tel_widget -%}
{%- set type = type|default('tel') -%}
{{ block('form_widget_simple') }}
{%- endblock tel_widget -%}
{%- block color_widget -%}
{%- set type = type|default('color') -%}
{{ block('form_widget_simple') }}
{%- endblock color_widget -%}
{%- block week_widget -%}
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
{%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%}
<div {{ block('widget_container_attributes') }}>
{{ form_widget(form.year, vars) }}-{{ form_widget(form.week, vars) }}
</div>
{%- endif -%}
{%- endblock week_widget -%}
{# Labels #}
{%- block form_label -%}
{% if label is not same as(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>
{%- if translation_domain is same as(false) -%}
{%- if label_html is same as(false) -%}
{{- label -}}
{%- else -%}
{{- label|raw -}}
{%- endif -%}
{%- else -%}
{%- if label_html is same as(false) -%}
{{- label|trans(label_translation_parameters, translation_domain) -}}
{%- else -%}
{{- label|trans(label_translation_parameters, translation_domain)|raw -}}
{%- endif -%}
{%- endif -%}
</{{ element|default('label') }}>
{%- endif -%}
{%- endblock form_label -%}
{%- block button_label -%}{%- endblock -%}
{# Help #}
{% block form_help -%}
{%- if help is not empty -%}
{%- set help_attr = help_attr|merge({class: (help_attr.class|default('') ~ ' help-text')|trim}) -%}
<p id="{{ id }}_help"{% with { attr: help_attr } %}{{ block('attributes') }}{% endwith %}>
{%- if translation_domain is same as(false) -%}
{%- if help_html is same as(false) -%}
{{- help -}}
{%- else -%}
{{- help|raw -}}
{%- endif -%}
{%- else -%}
{%- if help_html is same as(false) -%}
{{- help|trans(help_translation_parameters, translation_domain) -}}
{%- else -%}
{{- help|trans(help_translation_parameters, translation_domain)|raw -}}
{%- endif -%}
{%- endif -%}
</p>
{%- endif -%}
{%- endblock form_help %}
{# Rows #}
{%- block repeated_row -%}
{#
No need to render the errors here, as all errors are mapped
to the first child (see RepeatedTypeValidatorExtension).
#}
{{- block('form_rows') -}}
{%- endblock repeated_row -%}
{%- block form_row -%}
{%- set widget_attr = {} -%}
{%- if help is not empty -%}
{%- set widget_attr = {attr: {'aria-describedby': id ~"_help"}} -%}
{%- endif -%}
<div{% with {attr: row_attr} %}{{ block('attributes') }}{% endwith %}>
{{- form_label(form) -}}
{{- form_errors(form) -}}
{{- form_widget(form, widget_attr) -}}
{{- form_help(form) -}}
</div>
{%- endblock form_row -%}
{%- block button_row -%}
<div{% with {attr: row_attr} %}{{ block('attributes') }}{% endwith %}>
{{- form_widget(form) -}}
</div>
{%- endblock button_row -%}
{%- block hidden_row -%}
{{ form_widget(form) }}
{%- endblock hidden_row -%}
{# Misc #}
{%- block form -%}
{{ form_start(form) }}
{{- form_widget(form) -}}
{{ form_end(form) }}
{%- endblock form -%}
{%- block form_start -%}
{%- do form.setMethodRendered() -%}
{% set method = method|upper %}
{%- if method in ["GET", "POST"] -%}
{% set form_method = method %}
{%- else -%}
{% set form_method = "POST" %}
{%- endif -%}
<form{% if name != '' %} name="{{ name }}"{% endif %} method="{{ form_method|lower }}"{% if action != '' %} action="{{ action }}"{% endif %}{{ block('attributes') }}{% if multipart %} enctype="multipart/form-data"{% endif %}>
{%- if form_method != method -%}
<input type="hidden" name="_method" value="{{ method }}" />
{%- endif -%}
{%- endblock form_start -%}
{%- block form_end -%}
{%- if not render_rest is defined or render_rest -%}
{{ form_rest(form) }}
{%- endif -%}
</form>
{%- endblock form_end -%}
{%- block form_errors -%}
{%- if errors|length > 0 -%}
<ul>
{%- for error in errors -%}
<li>{{ error.message }}</li>
{%- endfor -%}
</ul>
{%- endif -%}
{%- endblock form_errors -%}
{%- block form_rest -%}
{% for child in form -%}
{% if not child.rendered %}
{{- form_row(child) -}}
{% endif %}
{%- endfor -%}
{% if not form.methodRendered and form is rootform %}
{%- do form.setMethodRendered() -%}
{% set method = method|upper %}
{%- if method in ["GET", "POST"] -%}
{% set form_method = method %}
{%- else -%}
{% set form_method = "POST" %}
{%- endif -%}
{%- if form_method != method -%}
<input type="hidden" name="_method" value="{{ method }}" />
{%- endif -%}
{% endif -%}
{% endblock form_rest %}
{# Support #}
{%- block form_rows -%}
{% for child in form|filter(child => not child.rendered) %}
{{- form_row(child) -}}
{% endfor %}
{%- endblock form_rows -%}
{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
{%- if disabled %} disabled="disabled"{% endif -%}
{%- if required %} required="required"{% endif -%}
{{ block('attributes') }}
{%- endblock widget_attributes -%}
{%- block widget_container_attributes -%}
{%- if id is not empty %}id="{{ id }}"{% endif -%}
{{ block('attributes') }}
{%- endblock widget_container_attributes -%}
{%- block button_attributes -%}
id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif -%}
{{ block('attributes') }}
{%- endblock button_attributes -%}
{% block attributes -%}
{%- for attrname, attrvalue in attr -%}
{{- " " -}}
{%- if attrname in ['placeholder', 'title'] -%}
{{- attrname }}="{{ translation_domain is same as(false) or attrvalue is null ? attrvalue : attrvalue|trans(attr_translation_parameters, translation_domain) }}"
{%- elseif attrvalue is same as(true) -%}
{{- attrname }}="{{ attrname }}"
{%- elseif attrvalue is not same as(false) -%}
{{- attrname }}="{{ attrvalue }}"
{%- endif -%}
{%- endfor -%}
{%- endblock attributes -%}

View File

@ -0,0 +1,468 @@
{%- block form_widget -%}
{% if compound %}
{{- block('form_widget_compound') -}}
{% else %}
{{- block('form_widget_simple') -}}
{% endif %}
{%- endblock form_widget -%}
{%- block form_widget_simple -%}
{%- set type = type|default('text') -%}
{% if type == 'text' %}
{%- set attr = attr|merge({for: id}) -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' border-1 px-3 py-3 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150' )|trim}) -%}
{% endif %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{%- endblock form_widget_simple -%}
{%- block form_widget_compound -%}
<div {{ block('widget_container_attributes') }}>
{%- if form.parent is empty -%}
{{ form_errors(form) }}
{%- endif -%}
{{- block('form_rows') -}}
{{- form_rest(form) -}}
</div>
{%- endblock form_widget_compound -%}
{%- block textarea_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' border-1 px-3 py-3 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150' )|trim}) -%}
<textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
{%- endblock textarea_widget -%}
{%- block choice_widget -%}
{% if expanded %}
{{- block('choice_widget_expanded') -}}
{% else %}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' border-1 px-3 py-3 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150')|trim}) -%}
{{- block('choice_widget_collapsed') -}}
{% endif %}
{%- endblock choice_widget -%}
{%- block choice_widget_expanded -%}
<div {{ block('widget_container_attributes') }}>
{%- for child in form %}
{{- form_widget(child) -}}
{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}
{% endfor -%}
</div>
{%- endblock choice_widget_expanded -%}
{%- block choice_widget_collapsed -%}
{%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%}
{% set required = false %}
{%- endif -%}
{% if multiple %}
<div class="row">
<div class="col-5">
<select name="{{ full_name }}_from" id="{{ full_name|md5 }}" class="form-control form-control-sm multiple" size="8" multiple="multiple">
{%- set options = choices -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% if choice is not validateChoice(value) %}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is validateChoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{%- endif -%}
{% endfor %}
</select>
</div>
<div class="col-2">
<button type="button" id="{{ full_name|md5 }}_rightAll" class="btn btn-sm btn-block"><i class="fa fa-forward"></i></button>
<button type="button" id="{{ full_name|md5 }}_rightSelected" class="btn btn-sm btn-block"><i class="fa fa-chevron-right"></i></button>
<button type="button" id="{{ full_name|md5 }}_leftSelected" class="btn btn-sm btn-block"><i class="fa fa-chevron-left"></i></button>
<button type="button" id="{{ full_name|md5 }}_leftAll" class="btn btn-sm btn-block"><i class="fa fa-backward"></i></button>
</div>
<div class="col-5">
<select name="{{ full_name }}" id="{{ full_name|md5 }}_to" class="form-control form-control-sm" size="8" multiple="multiple">
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{% if choice is validateChoice(value) %}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is validateChoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{%- endif -%}
{% endfor %}
</select>
</div>
</div>
{% else %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- if placeholder is not none -%}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}</option>
{%- endif -%}
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{%- if choices|length > 0 and separator is not none -%}
<option disabled="disabled">{{ separator }}</option>
{%- endif -%}
{%- endif -%}
{%- set options = choices -%}
{{- block('choice_widget_options') -}}
</select>
{% endif %}
{%- endblock choice_widget_collapsed -%}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is validateChoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
{%- block checkbox_widget -%}
<div class="flex flex-row gap-2">
<input type="checkbox" data-toggle="toggle" data-size="small" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{{- form_label(form) -}}
</div>
{%- endblock checkbox_widget -%}
{%- block radio_widget -%}
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{%- endblock radio_widget -%}
{%- block datetime_widget -%}
{% if widget == 'single_text' %}
{{- block('form_widget_simple') -}}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form.date) -}}
{{- form_errors(form.time) -}}
{{- form_widget(form.date) -}}
{{- form_widget(form.time) -}}
</div>
{%- endif -%}
{%- endblock datetime_widget -%}
{%- block date_widget -%}
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
<div class="flex flex-row gap-2" {{ block('widget_container_attributes') }}>
{{- date_pattern|replace({
'{{ year }}': form_widget(form.year),
'{{ month }}': form_widget(form.month),
'{{ day }}': form_widget(form.day),
})|raw -}}
</div>
{%- endif -%}
{%- endblock date_widget -%}
{%- block time_widget -%}
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
{%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%}
<div {{ block('widget_container_attributes') }}>
{{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %}
</div>
{%- endif -%}
{%- endblock time_widget -%}
{%- block dateinterval_widget -%}
{%- if widget == 'single_text' -%}
{{- block('form_widget_simple') -}}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form) -}}
<table class="{{ table_class|default('') }}">
<thead>
<tr>
{%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%}
{%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%}
{%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%}
{%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%}
{%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%}
{%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%}
{%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%}
</tr>
</thead>
<tbody>
<tr>
{%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%}
{%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%}
{%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%}
{%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%}
{%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%}
{%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%}
{%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%}
</tr>
</tbody>
</table>
{%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
</div>
{%- endif -%}
{%- endblock dateinterval_widget -%}
{%- block number_widget -%}
{# type="number" doesn't work with floats #}
{%- set type = type|default('text') -%}
{{ block('form_widget_simple') }}
{%- endblock number_widget -%}
{%- block integer_widget -%}
{%- set type = type|default('number') -%}
{{ block('form_widget_simple') }}
{%- endblock integer_widget -%}
{%- block money_widget -%}
{{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }}
{%- endblock money_widget -%}
{%- block url_widget -%}
{%- set type = type|default('url') -%}
{{ block('form_widget_simple') }}
{%- endblock url_widget -%}
{%- block search_widget -%}
{%- set type = type|default('search') -%}
{{ block('form_widget_simple') }}
{%- endblock search_widget -%}
{%- block percent_widget -%}
{%- set type = type|default('text') -%}
{{ block('form_widget_simple') }} %
{%- endblock percent_widget -%}
{%- block password_widget -%}
{%- set type = type|default('password') -%}
{{ block('form_widget_simple') }}
{%- endblock password_widget -%}
{%- block hidden_widget -%}
{%- set type = type|default('hidden') -%}
{{ block('form_widget_simple') }}
{%- endblock hidden_widget -%}
{%- block email_widget -%}
{%- set type = type|default('email') -%}
{{ block('form_widget_simple') }}
{%- endblock email_widget -%}
{%- block range_widget -%}
{% set type = type|default('range') %}
{{- block('form_widget_simple') -}}
{%- endblock range_widget %}
{%- block button_widget -%}
{%- if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- elseif label is same as(false) -%}
{% set translation_domain = false %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{% if icon_before is defined and icon_before is not null %}
<i class="fa {{ icon_before }}"></i>
{% endif %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% if icon_after is defined and icon_after is not null %}
<i class="fa {{ icon_after }}"></i>
{% endif %}
</button>
{%- endblock button_widget -%}
{% block checkbox_radio_label -%}
{{- form_label(form) -}}
{% endblock %}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{{ block('button_widget') }}
{%- endblock submit_widget -%}
{%- block reset_widget -%}
{%- set type = type|default('reset') -%}
{{ block('button_widget') }}
{%- endblock reset_widget -%}
{%- block tel_widget -%}
{%- set type = type|default('tel') -%}
{{ block('form_widget_simple') }}
{%- endblock tel_widget -%}
{%- block color_widget -%}
{%- set type = type|default('color') -%}
{{ block('form_widget_simple') }}
{%- endblock color_widget -%}
{# Labels #}
{%- block form_label -%}
{% if label is not same as(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
{%- set label_attr = label_attr|merge({for: id}) -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' block uppercase text-xs font-bold mb-2' )|trim}) -%}
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}</{{ element|default('label') }}>
{%- endif -%}
{%- endblock form_label -%}
{%- block button_label -%}{%- endblock -%}
{# Rows #}
{%- block repeated_row -%}
{#
No need to render the errors here, as all errors are mapped
to the first child (see RepeatedTypeValidatorExtension).
#}
{{- block('form_rows') -}}
{%- endblock repeated_row -%}
{%- block form_row -%}
<div class="mb-3">
{{- form_label(form) -}}
{{- form_errors(form) -}}
{{- form_widget(form) -}}
</div>
{%- endblock form_row -%}
{%- block button_row -%}
<div>
{{- form_widget(form) -}}
</div>
{%- endblock button_row -%}
{%- block hidden_row -%}
{{ form_widget(form) }}
{%- endblock hidden_row -%}
{# Misc #}
{%- block form -%}
{{ form_start(form) }}
{{- form_widget(form) -}}
{{ form_end(form) }}
{%- endblock form -%}
{%- block form_start -%}
{%- do form.setMethodRendered() -%}
{% set method = method|upper %}
{%- if method in ["GET", "POST"] -%}
{% set form_method = method %}
{%- else -%}
{% set form_method = "POST" %}
{%- endif -%}
<form name="{{ name }}" method="{{ form_method|lower }}"{% if action != '' %} action="{{ action }}"{% endif %}{% for attrname, attrvalue in attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}{% if multipart %} enctype="multipart/form-data"{% endif %}>
{%- if form_method != method -%}
<input type="hidden" name="_method" value="{{ method }}" />
{%- endif -%}
{%- endblock form_start -%}
{%- block form_end -%}
{%- if not render_rest is defined or render_rest -%}
{{ form_rest(form) }}
{%- endif -%}
</form>
{%- endblock form_end -%}
{%- block form_errors -%}
{%- if errors|length > 0 -%}
<ul>
{%- for error in errors -%}
<li>{{ error.message }}</li>
{%- endfor -%}
</ul>
{%- endif -%}
{%- endblock form_errors -%}
{%- block form_rest -%}
{% for child in form -%}
{% if not child.rendered %}
{{- form_row(child) -}}
{% endif %}
{%- endfor %}
{% if not form.methodRendered and form.parent is null %}
{%- do form.setMethodRendered() -%}
{% set method = method|upper %}
{%- if method in ["GET", "POST"] -%}
{% set form_method = method %}
{%- else -%}
{% set form_method = "POST" %}
{%- endif -%}
{%- if form_method != method -%}
<input type="hidden" name="_method" value="{{ method }}" />
{%- endif -%}
{% endif %}
{% endblock form_rest %}
{# Support #}
{%- block form_rows -%}
{% for child in form %}
{{- form_row(child) -}}
{% endfor %}
{%- endblock form_rows -%}
{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
{%- if disabled %} disabled="disabled"{% endif -%}
{%- if required %} required="required"{% endif -%}
{{ block('attributes') }}
{%- endblock widget_attributes -%}
{%- block widget_container_attributes -%}
{%- if id is not empty %}id="{{ id }}"{% endif -%}
{{ block('attributes') }}
{%- endblock widget_container_attributes -%}
{%- block button_attributes -%}
id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif -%}
{{ block('attributes') }}
{%- endblock button_attributes -%}
{% block attributes -%}
{%- for attrname, attrvalue in attr -%}
{{- " " -}}
{%- if attrname in ['placeholder', 'title'] -%}
{{- attrname }}="{{ translation_domain is same as(false) ? attrvalue : attrvalue|trans({}, translation_domain) }}"
{%- elseif attrvalue is same as(true) -%}
{{- attrname }}="{{ attrname }}"
{%- elseif attrvalue is not same as(false) -%}
{{- attrname }}="{{ attrvalue }}"
{%- endif -%}
{%- endfor -%}
{%- endblock attributes -%}

View File

@ -0,0 +1,31 @@
<?php
namespace Tests\PSC\Shop\Basket\Lagacy;
use PSC\Shop\ContactBundle\Repository\ContactRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Tests\RefreshDatabaseTrait;
class AddTest extends WebTestCase
{
use RefreshDatabaseTrait;
public function testAddLagacyBasketWithAccountCalc(): void
{
$client = static::createClient();
$userRepository = static::getContainer()->get(ContactRepository::class);
$testUser = $userRepository->loadUserByUsername('company@shop.de');
$client->loginUser($testUser, 'api');
$client->jsonRequest('POST', '/api/basket/legacy/add', [
'productUUId' => '01938686-0e4d-7da9-bae3-b2e1b1681f9f',
'count' => 1
], []);
$this->assertResponseIsSuccessful();
$data = json_decode($client->getResponse()->getContent(), true);
var_dump($data);
self::assertSame(16640, $data['netto']);
}
}

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Tests\PSC\Shop\Entity; namespace Tests\PSC\Shop\Entity;
use Tests\RefreshDatabaseTrait; use Tests\RefreshDatabaseTrait;
use PSC\Shop\EntityBundle\Entity\Order; use PSC\Shop\EntityBundle\Entity\Order;

View File

@ -1,5 +1,6 @@
<?php <?php
namespace App\Tests\PSC\Shop\Order\Api;
namespace Tests\PSC\Shop\Order\Api;
use PSC\Shop\EntityBundle\Repository\JobRepository; use PSC\Shop\EntityBundle\Repository\JobRepository;
use Tests\RefreshDatabaseTrait; use Tests\RefreshDatabaseTrait;
@ -30,9 +31,11 @@ class CopyAndChangeContactTest extends WebTestCase
$paymentRepository = static::getContainer()->get(PaymentRepository::class); $paymentRepository = static::getContainer()->get(PaymentRepository::class);
$client->jsonRequest( $client->jsonRequest(
'POST', '/api/order/create', [ 'POST',
'/api/order/create',
[
'shop' => [ 'shop' => [
'uuid' => (String)$shop->getUuid() 'uuid' => (string)$shop->getUuid()
], ],
'type' => 2, 'type' => 2,
'shipping' => [ 'shipping' => [
@ -96,15 +99,19 @@ class CopyAndChangeContactTest extends WebTestCase
] ]
] ]
] ]
], ['HTTP_apiKey' => $shop->getApiKey()] ],
['HTTP_apiKey' => $shop->getApiKey()]
); );
self::assertSame(200, $client->getResponse()->getStatusCode()); self::assertSame(200, $client->getResponse()->getStatusCode());
$data = json_decode($client->getResponse()->getContent(), true); $data = json_decode($client->getResponse()->getContent(), true);
$client->jsonRequest( $client->jsonRequest(
'POST', '/api/order/copy', [ 'POST',
'/api/order/copy',
[
'uuid' => $data['uuid'], 'uuid' => $data['uuid'],
], ['HTTP_apiKey' => $shop->getApiKey()] ],
['HTTP_apiKey' => $shop->getApiKey()]
); );
self::assertSame(200, $client->getResponse()->getStatusCode()); self::assertSame(200, $client->getResponse()->getStatusCode());
@ -126,10 +133,13 @@ class CopyAndChangeContactTest extends WebTestCase
$contact = $contactRepository->findOneBy(['username' => 'test@shop.de']); $contact = $contactRepository->findOneBy(['username' => 'test@shop.de']);
$client->jsonRequest( $client->jsonRequest(
'POST', '/api/order/changecontact', [ 'POST',
'/api/order/changecontact',
[
'uuid' => $data['uuid'], 'uuid' => $data['uuid'],
'contact' => $contact->getUuid() 'contact' => $contact->getUuid()
], ['HTTP_apiKey' => $shop->getApiKey()] ],
['HTTP_apiKey' => $shop->getApiKey()]
); );
$data = json_decode($client->getResponse()->getContent(), true); $data = json_decode($client->getResponse()->getContent(), true);
self::assertNotSame($contactId, $data['contact']['uid']); self::assertNotSame($contactId, $data['contact']['uid']);

View File

@ -36,7 +36,7 @@ class GetPriceTest extends WebTestCase
$data = json_decode($client->getResponse()->getContent(), true); $data = json_decode($client->getResponse()->getContent(), true);
self::assertSame(2080, $data['netto']); self::assertSame(16640, $data['netto']);
} }
public function testGetPriceWithAssociation(): void public function testGetPriceWithAssociation(): void

View File

@ -0,0 +1,20 @@
#!/bin/sh
# This script drives the standalone dart-sass package, which bundles together a
# Dart executable and a snapshot of dart-sass.
follow_links() {
# Use `readlink -f` if it exists, but fall back to manually following symlnks
# for systems (like older Mac OS) where it doesn't.
file="$1"
if readlink -f "$file" 2>&-; then return; fi
while [ -h "$file" ]; do
file="$(readlink "$file")"
done
echo "$file"
}
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
path=`dirname "$(follow_links "$0")"`
exec "$path/src/dart" "$path/src/sass.snapshot" "$@"

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -314,7 +314,7 @@
.card-fullscreen { .card-fullscreen {
display: block; display: block;
z-index: 9999; z-index: 9999;
position: fixed; position: fixed !important;
width: 100%; width: 100%;
height: 100%; height: 100%;
top: 0; top: 0;
@ -328,6 +328,8 @@
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
{% autoescape 'js' %} {% autoescape 'js' %}
<script type="module">
import $ from 'jquery'
var productUUId = "{{product.uuid}}"; var productUUId = "{{product.uuid}}";
var formContact = false; var formContact = false;
$(function() { $(function() {
@ -343,7 +345,7 @@
var editorElm = $('#' + id); var editorElm = $('#' + id);
if(card.hasClass("card-fullscreen")) { if(card.hasClass("modal-fullscreen card-fullscreen")) {
editorElm.height(editorElm.data('height')); editorElm.height(editorElm.data('height'));
}else{ }else{
if(typeof card.data('height') === 'undefined') { if(typeof card.data('height') === 'undefined') {
@ -352,7 +354,8 @@
editorElm.height('100%'); editorElm.height('100%');
} }
card.toggleClass("card-fullscreen"); card.toggleClass("modal-fullscreen card-fullscreen");
card.css('display', 'flex'); card.css('display', 'flex');
var editor = ace.edit(id); var editor = ace.edit(id);
editor.resize(); editor.resize();

View File

@ -6,20 +6,21 @@ use Doctrine\ORM\EntityManagerInterface;
use PSC\Library\Calc\Engine; use PSC\Library\Calc\Engine;
use PSC\Library\Calc\PaperContainer; use PSC\Library\Calc\PaperContainer;
use PSC\Shop\BasketBundle\Event\Legacy\Add as PSCAdd; use PSC\Shop\BasketBundle\Event\Legacy\Add as PSCAdd;
use PSC\Shop\ContactBundle\Model\Contact as PSCContact;
use PSC\Shop\ContactBundle\Transformer\Model\Contact;
use PSC\System\SettingsBundle\Service\PaperDB; use PSC\System\SettingsBundle\Service\PaperDB;
use PSC\System\SettingsBundle\Service\Shop; use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class Add implements EventSubscriberInterface class Add implements EventSubscriberInterface
{ {
private EntityManagerInterface $entityManager; public function __construct(
private PaperDB $paperDB; private readonly EntityManagerInterface $entityManager,
private readonly PaperDB $paperDB,
public function __construct(EntityManagerInterface $entityManager, private readonly TokenStorageInterface $tokenStorage,
PaperDB $paperDB) private readonly Contact $contactTransformer
{ ) {
$this->entityManager = $entityManager;
$this->paperDB = $paperDB;
} }
public static function getSubscribedEvents(): array public static function getSubscribedEvents(): array
@ -46,7 +47,7 @@ class Add implements EventSubscriberInterface
$engine = new Engine(); $engine = new Engine();
$engine->setPaperRepository($this->paperDB); $engine->setPaperRepository($this->paperDB);
$engine->setPaperContainer($paperContainer); $engine->setPaperContainer($paperContainer);
if($product->getShop()->getInstall()->getCalcTemplates()) { if ($product->getShop()->getInstall()->getCalcTemplates()) {
$engine->setTemplates('<root>'.$product->getShop()->getInstall()->getCalcTemplates().'</root>'); $engine->setTemplates('<root>'.$product->getShop()->getInstall()->getCalcTemplates().'</root>');
} }
$engine->loadString($product->getCalcXml()); $engine->loadString($product->getCalcXml());
@ -54,6 +55,12 @@ class Add implements EventSubscriberInterface
$engine->setFormulas($product->getShop()->getFormel()); $engine->setFormulas($product->getShop()->getFormel());
$engine->setParameters($product->getShop()->getParameter()); $engine->setParameters($product->getShop()->getParameter());
$engine->setVariables($event->getData()->values); $engine->setVariables($event->getData()->values);
if ($this->tokenStorage->getToken()) {
$contact = new PSCContact();
$this->contactTransformer->fromDb($contact, $this->tokenStorage->getToken()->getUser());
$engine->setVariable('contact.accountType', $contact->getAccountType()->value);
$engine->setVariable('contact.account', $contact->getAccount()->getUid());
}
$engine->setTax($product->getMwert()); $engine->setTax($product->getMwert());
$basketItem->setNetto($engine->getPrice()); $basketItem->setNetto($engine->getPrice());
$basketItem->setBrutto($engine->getCompletePrice()); $basketItem->setBrutto($engine->getCompletePrice());

View File

@ -0,0 +1,275 @@
html, body {
background: #f0f3f4;
height: 100%;
}
html > div, body > div {
padding: 0 !important;
}
html > #overlay_loading, body > #overlay_loading {
background: #ffffff;
color: #666666;
position: fixed;
height: 100%;
width: 100%;
z-index: 5000;
top: 0;
left: 0;
float: left;
text-align: center;
padding-top: 25%;
opacity: 0.8;
}
html > #overlay_loading > .spinner, body > #overlay_loading > .spinner {
margin: 0 auto;
height: 64px;
width: 64px;
animation: rotate 0.8s infinite linear;
border: 5px solid firebrick;
border-right-color: transparent;
border-radius: 50%;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
i.fa.fa-lg.fa-fw.fa-question-circle {
color: #007bff;
font-size: 1.6em;
}
.toast-container {
z-index: 999999;
}
.toast-container .toast-body {
background: white;
}
body > header > .header {
background: #EA641b;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
padding: 10px;
margin: 0;
color: white;
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 990;
}
body > header > .header #help a {
font-size: 1.5em;
color: white;
}
body > header > .header > h4 {
margin: 0;
}
body > header > .header .form-group {
margin-bottom: 0;
}
body > header > .header .btnLogout {
background: #343a40 !important;
border-left: 1px solid white;
border-top: 1px solid white;
border-bottom: 1px solid white;
border-right: 1px solid white;
}
body > header > .header .btnWiki {
background: #343a40 !important;
border-left: 1px solid white;
border-top: 1px solid white;
border-bottom: 1px solid white;
}
body > header > .header .btnTicket {
background: #343a40 !important;
border-left: 1px solid white;
border-top: 1px solid white;
border-bottom: 1px solid white;
}
.sideMenu {
overflow-x: hidden;
overflow-y: auto;
color: #aeb1bc;
position: fixed;
top: 0;
/* rtl:raw:
right: 0;
*/
bottom: 0;
/* rtl:remove */
left: 0;
z-index: 100; /* Behind the navbar */
padding: 60px 0 0; /* Height of navbar */
}
.sideMenu h5 {
color: white;
}
.sideMenu .collapse-menu {
float: right;
margin-top: 5px;
margin-right: 10px;
}
.sideMenu .nav {
flex-wrap: nowrap !important;
}
.sideMenu .nav > li {
cursor: pointer;
}
.sideMenu .nav > li > a {
padding: 5px 5px;
display: block;
}
.sideMenu .nav > li > a:hover {
color: white;
background: #555;
text-decoration: none;
}
.sideMenu .nav > li > a:hover i {
color: white;
}
.sideMenu .nav > li > ul {
display: none;
margin-left: 10px;
}
.sideMenu .nav > li.open > ul {
display: block;
}
.sideMenu .nav li.active a {
color: white;
}
.sideMenu .nav li.active a i {
color: white;
}
.sideMenu a {
color: #b4b6bd;
}
.sideMenu a i {
color: #898ba3;
}
.content {
padding: 0 10px 0 10px;
margin-top: 50px;
}
.content h3, .content h4 {
margin: 0;
}
.content .header {
padding: 10px;
color: #373a3c;
background: #f6f8f8;
border-bottom: 1px solid #dee5e7;
}
.content .body {
padding: 10px;
}
.content .body .btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.content .body .searchForm {
margin-bottom: 10px;
}
.content .body .panel {
margin-top: 10px;
border: 1px solid #dee5e7;
background: white;
border-radius: 2px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
.content .body .panel > .header {
background: #f6f8f8;
border-bottom: 1px solid #edf1f2;
color: #333;
padding: 10px;
}
.content .body .panel > .body {
padding: 10px;
}
.content .body .panel > .body .tab-content {
margin-top: 10px;
}
.content .body .panel > .body .nav-tabs .nav-link.active, .content .body .panel > .body .nav-tabs .nav-link.active:focus, .content .body .panel > .body .nav-tabs .nav-link.active:hover, .content .body .panel > .body .nav-tabs .nav-item.open .nav-link, .content .body .panel > .body .nav-tabs .nav-item.open .nav-link:focus, .content .body .panel > .body .nav-tabs .nav-item.open .nav-link:hover {
background-color: #0275d8;
border-color: #ddd #ddd transparent;
border: 1px solid;
border-radius: 4px;
color: white;
}
.content .body .panel > .body .overlay {
position: absolute;
height: 100%;
width: 100%;
background: rgba(234, 100, 27, 0.75);
z-index: 1;
text-align: center;
vertical-align: middle;
font-size: xx-large;
padding-top: 150px;
color: #444;
margin: -5px;
}
.content .body .panel > .body .table > tbody > tr.divider > td {
background: #EA641b;
height: 2px;
padding: 0;
}
.content .body .panel > .body .table .thead-dark th {
background-color: #343a40;
}
.content .body .panel > .body .table .thead-dark a {
color: white;
text-decoration: underline;
}
.ajax-modal__body {
padding: 0;
height: 80vh;
}
.no-margin-top {
margin-top: 0;
}
/** MODAL **/
.modal-lg {
width: 90vw;
max-width: none;
}
/** bg table **/
.bg-lightdanger {
background-color: #ffcece;
}
.bg-lightsuccess {
background-color: #dbffdb;
}
.bg-lightdark {
background-color: lightgrey;
}
.form-check {
margin-bottom: 12px;
}
.thead-dark > tr > th {
color: white !important;
}
.btn-xs,
.btn-group-xs > .btn {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,%22sourceRoot%22:%22%22,%22sources%22:%5B%22../../assets/backend/dashboard/less/base.scss%22,%22../../assets/backend/dashboard/less/toogle/toogle.scss%22%5D,%22names%22:%5B%5D,%22mappings%22:%22AAAA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;IACE;;EAEF;IACE;;;;AAKN;EACE;EACA;;;AAGF;EACE;;AACA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;AACA;AAAA;AAAA;EAGA;AACA;EACA;EACA;EACA;;AACA;EACE;;AAGF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AACA;EACE;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAGJ;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EAIE;;AAHA;EACE;;;AAON;EACE;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AACA;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EAmDE;EACA;EACA;EACA;EACA;;AArDA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AACA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGA;EACE;;AAEF;EACE;EACA;;;AAaZ;EACE;EACA;;;AAGF;EACE;;;AAGF;AACA;EACE;EACA;;;AAGF;AACA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAEF;EACE;;;AAGF;EACE;;;ACnRF;AAAA;EAEE;EACA;EACA;EACA%22,%22file%22:%22base.output.css%22%7D */

View File

@ -778,6 +778,10 @@ html {
border-width: 0; border-width: 0;
} }
.pointer-events-none{
pointer-events: none;
}
.visible{ .visible{
visibility: visible; visibility: visible;
} }
@ -847,6 +851,10 @@ html {
isolation: isolate; isolation: isolate;
} }
.z-0{
z-index: 0;
}
.z-10{ .z-10{
z-index: 10; z-index: 10;
} }
@ -892,11 +900,21 @@ html {
margin-right: -0.75rem; margin-right: -0.75rem;
} }
.mx-1{
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.mx-auto{ .mx-auto{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.mb-0{ .mb-0{
margin-bottom: 0px; margin-bottom: 0px;
} }
@ -952,6 +970,10 @@ html {
margin-right: 0.75rem; margin-right: 0.75rem;
} }
.mr-5{
margin-right: 1.25rem;
}
.ms-1{ .ms-1{
-webkit-margin-start: 0.25rem; -webkit-margin-start: 0.25rem;
margin-inline-start: 0.25rem; margin-inline-start: 0.25rem;
@ -1153,6 +1175,10 @@ html {
flex: 1 1 0%; flex: 1 1 0%;
} }
.flex-none{
flex: none;
}
.flex-shrink{ .flex-shrink{
flex-shrink: 1; flex-shrink: 1;
} }
@ -1187,6 +1213,28 @@ html {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
} }
.rotate-180{
--tw-rotate: 180deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-100{
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-95{
--tw-scale-x: .95;
--tw-scale-y: .95;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-x-0{
--tw-scale-x: 0;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform{ .transform{
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
} }
@ -1219,6 +1267,10 @@ html {
flex-wrap: wrap; flex-wrap: wrap;
} }
.content-center{
align-content: center;
}
.items-start{ .items-start{
align-items: flex-start; align-items: flex-start;
} }
@ -1427,6 +1479,11 @@ html {
background-color: rgb(220 252 231 / var(--tw-bg-opacity)); background-color: rgb(220 252 231 / var(--tw-bg-opacity));
} }
.bg-lime-600{
--tw-bg-opacity: 1;
background-color: rgb(101 163 13 / var(--tw-bg-opacity));
}
.bg-psc-500{ .bg-psc-500{
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(234 100 27 / var(--tw-bg-opacity)); background-color: rgb(234 100 27 / var(--tw-bg-opacity));
@ -1489,6 +1546,14 @@ html {
padding: 0.75rem; padding: 0.75rem;
} }
.p-4{
padding: 1rem;
}
.p-5{
padding: 1.25rem;
}
.p-8{ .p-8{
padding: 2rem; padding: 2rem;
} }
@ -1711,6 +1776,11 @@ html {
color: rgb(153 27 27 / var(--tw-text-opacity)); color: rgb(153 27 27 / var(--tw-text-opacity));
} }
.text-stone-500{
--tw-text-opacity: 1;
color: rgb(120 113 108 / var(--tw-text-opacity));
}
.text-white{ .text-white{
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
@ -1835,10 +1905,22 @@ html {
transition-delay: 100ms; transition-delay: 100ms;
} }
.duration-150{
transition-duration: 150ms;
}
.duration-300{
transition-duration: 300ms;
}
.duration-75{ .duration-75{
transition-duration: 75ms; transition-duration: 75ms;
} }
.ease-linear{
transition-timing-function: linear;
}
.\[-_\:\.a-zA-Z0-9\C0-\FFFF\]{ .\[-_\:\.a-zA-Z0-9\C0-\FFFF\]{
-_: .a-zA-Z0-9À-￿; -_: .a-zA-Z0-9À-￿;
} }
@ -1855,6 +1937,10 @@ html {
a-z-a--z0-9_: \\.-; a-z-a--z0-9_: \\.-;
} }
.\[a-zA-Z\:_\]{
a-z-a--z: ;
}
:root { :root {
--sidebar-width: 20rem; --sidebar-width: 20rem;
--collapsed-sidebar-width: 5.4rem; --collapsed-sidebar-width: 5.4rem;
@ -1920,6 +2006,49 @@ html {
width: 1.5rem; width: 1.5rem;
} }
.psc-button-save{
display: inline-flex;
min-height: 2.25rem;
align-items: center;
justify-content: center;
gap: 0.25rem;
border-radius: 0.125rem;
--tw-bg-opacity: 1;
background-color: rgb(234 100 27 / var(--tw-bg-opacity));
padding-top: 0.25rem;
padding-bottom: 0.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 500;
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.psc-button-save:hover{
--tw-bg-opacity: 1;
background-color: rgb(172 48 37 / var(--tw-bg-opacity));
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-ring-opacity: 1;
--tw-ring-color: rgb(234 100 27 / var(--tw-ring-opacity));
--tw-ring-offset-width: 2px;
}
.form-label{
margin-bottom: 0.5rem;
display: block;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 700;
text-transform: uppercase;
}
.hover\:bg-gray-200:hover{ .hover\:bg-gray-200:hover{
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity)); background-color: rgb(229 231 235 / var(--tw-bg-opacity));
@ -2149,6 +2278,18 @@ html {
display: inline; display: inline;
} }
.md\:flex{
display: flex;
}
.md\:w-2\/12{
width: 16.666667%;
}
.md\:w-5\/12{
width: 41.666667%;
}
.md\:flex-row{ .md\:flex-row{
flex-direction: row; flex-direction: row;
} }
@ -2176,6 +2317,10 @@ html {
display: none; display: none;
} }
.lg\:w-6\/12{
width: 50%;
}
.lg\:max-w-\[var\(--collapsed-sidebar-width\)\]{ .lg\:max-w-\[var\(--collapsed-sidebar-width\)\]{
max-width: var(--collapsed-sidebar-width); max-width: var(--collapsed-sidebar-width);
} }
@ -2278,3 +2423,5 @@ html {
padding-right: 1.75rem; padding-right: 1.75rem;
} }
} }

View File

@ -803,6 +803,10 @@ select{
border-width: 0; border-width: 0;
} }
.pointer-events-none{
pointer-events: none;
}
.visible{ .visible{
visibility: visible; visibility: visible;
} }
@ -872,6 +876,10 @@ select{
isolation: isolate; isolation: isolate;
} }
.z-0{
z-index: 0;
}
.z-10{ .z-10{
z-index: 10; z-index: 10;
} }
@ -904,6 +912,10 @@ select{
margin: 0.25rem; margin: 0.25rem;
} }
.m-10{
margin: 2.5rem;
}
.m-2{ .m-2{
margin: 0.5rem; margin: 0.5rem;
} }
@ -912,16 +924,35 @@ select{
margin: auto; margin: auto;
} }
.m-5{
margin: 1.25rem;
}
.-mx-3{ .-mx-3{
margin-left: -0.75rem; margin-left: -0.75rem;
margin-right: -0.75rem; margin-right: -0.75rem;
} }
.mx-1{
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.mx-auto{ .mx-auto{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.mx-2{
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.mb-0{ .mb-0{
margin-bottom: 0px; margin-bottom: 0px;
} }
@ -961,6 +992,10 @@ select{
margin-left: 1rem; margin-left: 1rem;
} }
.ml-5{
margin-left: 1.25rem;
}
.ml-auto{ .ml-auto{
margin-left: auto; margin-left: auto;
} }
@ -977,6 +1012,10 @@ select{
margin-right: 0.75rem; margin-right: 0.75rem;
} }
.mr-5{
margin-right: 1.25rem;
}
.ms-1{ .ms-1{
-webkit-margin-start: 0.25rem; -webkit-margin-start: 0.25rem;
margin-inline-start: 0.25rem; margin-inline-start: 0.25rem;
@ -998,6 +1037,10 @@ select{
margin-top: 1rem; margin-top: 1rem;
} }
.mt-5{
margin-top: 1.25rem;
}
.block{ .block{
display: block; display: block;
} }
@ -1130,6 +1173,10 @@ select{
width: 2.5rem; width: 2.5rem;
} }
.w-10\/12{
width: 83.333333%;
}
.w-4{ .w-4{
width: 1rem; width: 1rem;
} }
@ -1146,6 +1193,10 @@ select{
width: 1.5rem; width: 1.5rem;
} }
.w-6\/12{
width: 50%;
}
.w-\[var\(--sidebar-width\)\]{ .w-\[var\(--sidebar-width\)\]{
width: var(--sidebar-width); width: var(--sidebar-width);
} }
@ -1162,6 +1213,18 @@ select{
width: 100vw; width: 100vw;
} }
.w-8\/12{
width: 66.666667%;
}
.w-3\/12{
width: 25%;
}
.w-2\/12{
width: 16.666667%;
}
.max-w-7xl{ .max-w-7xl{
max-width: 80rem; max-width: 80rem;
} }
@ -1212,6 +1275,28 @@ select{
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
} }
.rotate-180{
--tw-rotate: 180deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-100{
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-95{
--tw-scale-x: .95;
--tw-scale-y: .95;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-x-0{
--tw-scale-x: 0;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform{ .transform{
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
} }
@ -1244,6 +1329,10 @@ select{
flex-wrap: wrap; flex-wrap: wrap;
} }
.content-end{
align-content: flex-end;
}
.items-start{ .items-start{
align-items: flex-start; align-items: flex-start;
} }
@ -1331,6 +1420,14 @@ select{
border-color: rgb(243 244 246 / var(--tw-divide-opacity)); border-color: rgb(243 244 246 / var(--tw-divide-opacity));
} }
.place-self-end{
place-self: end;
}
.self-end{
align-self: flex-end;
}
.overflow-hidden{ .overflow-hidden{
overflow: hidden; overflow: hidden;
} }
@ -1486,6 +1583,21 @@ select{
background-color: rgb(234 179 8 / var(--tw-bg-opacity)); background-color: rgb(234 179 8 / var(--tw-bg-opacity));
} }
.bg-lime-600{
--tw-bg-opacity: 1;
background-color: rgb(101 163 13 / var(--tw-bg-opacity));
}
.bg-psc{
--tw-bg-opacity: 1;
background-color: rgb(234 100 27 / var(--tw-bg-opacity));
}
.bg-psc-600{
--tw-bg-opacity: 1;
background-color: rgb(172 48 37 / var(--tw-bg-opacity));
}
.bg-cover{ .bg-cover{
background-size: cover; background-size: cover;
} }
@ -1514,6 +1626,10 @@ select{
padding: 0.75rem; padding: 0.75rem;
} }
.p-4{
padding: 1rem;
}
.p-8{ .p-8{
padding: 2rem; padding: 2rem;
} }
@ -1736,6 +1852,11 @@ select{
color: rgb(153 27 27 / var(--tw-text-opacity)); color: rgb(153 27 27 / var(--tw-text-opacity));
} }
.text-stone-500{
--tw-text-opacity: 1;
color: rgb(120 113 108 / var(--tw-text-opacity));
}
.text-white{ .text-white{
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
@ -1860,6 +1981,10 @@ select{
transition-delay: 100ms; transition-delay: 100ms;
} }
.duration-300{
transition-duration: 300ms;
}
.duration-75{ .duration-75{
transition-duration: 75ms; transition-duration: 75ms;
} }

File diff suppressed because one or more lines are too long

View File

@ -1,33 +0,0 @@
var components = {
"packages": [
{
"name": "elfinder",
"main": "elfinder-built.js"
},
{
"name": "jquery",
"main": "jquery-built.js"
},
{
"name": "jquery-ui",
"main": "jquery-ui-built.js"
}
],
"shim": {
"jquery-ui": {
"deps": [
"jquery"
],
"exports": "jQuery"
}
},
"baseUrl": "components"
};
if (typeof require !== "undefined" && require.config) {
require.config(components);
} else {
var require = components;
}
if (typeof exports !== "undefined" && typeof module !== "undefined") {
module.exports = components;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -38,10 +38,12 @@ class Cms extends BaseCms
protected $mongoLoaded = false; protected $mongoLoaded = false;
protected bool $noIndex = false; protected bool $noIndex = false;
protected array $accounts = [];
protected $extraSettings; protected $extraSettings;
public function setUp() { public function setUp()
{
parent::setUp(); parent::setUp();
$this->hasOne('Cms', array( $this->hasOne('Cms', array(
@ -59,12 +61,14 @@ class Cms extends BaseCms
$obj = $m->Cms->findOne(array('uid' => (string)$this->id)); $obj = $m->Cms->findOne(array('uid' => (string)$this->id));
if ($obj) { if ($obj) {
$this->extraSettings = $obj['extraSettings']; $this->extraSettings = $obj['extraSettings'];
$this->accounts = (array)$obj['accounts'];
$this->noIndex = (bool)$obj['noIndex']; $this->noIndex = (bool)$obj['noIndex'];
$this->mongoLoaded = true; $this->mongoLoaded = true;
} }
} }
public function postDelete($obj) { public function postDelete($obj)
{
TP_Util::clearCache(); TP_Util::clearCache();
Zend_Registry::get('filecache')->clean( Zend_Registry::get('filecache')->clean(
@ -73,7 +77,8 @@ class Cms extends BaseCms
); );
} }
public function getRiakData() { public function getRiakData()
{
return array( return array(
'title' => $this->title, 'title' => $this->title,
'shop_id' => $this->shop_id, 'shop_id' => $this->shop_id,
@ -88,7 +93,8 @@ class Cms extends BaseCms
* *
* @return void * @return void
*/ */
public function preSave($obj) { public function preSave($obj)
{
if ($this->menu == "") { if ($this->menu == "") {
$this->menu = $this->title; $this->menu = $this->title;
@ -105,11 +111,13 @@ class Cms extends BaseCms
* *
* @return void * @return void
*/ */
public function postSave($obj) { public function postSave($obj)
{
TP_Util::clearShop($this->Shop); TP_Util::clearShop($this->Shop);
} }
public function getLiveedit($field, $type = 'INPUT') { public function getLiveedit($field, $type = 'INPUT')
{
$mode = new Zend_Session_Namespace('adminmode'); $mode = new Zend_Session_Namespace('adminmode');
if ($mode->liveedit && $type == 'NO') { if ($mode->liveedit && $type == 'NO') {
return $this->$field; return $this->$field;
@ -121,7 +129,8 @@ class Cms extends BaseCms
return $this->$field; return $this->$field;
} }
public function getText() { public function getText()
{
$templates = array([]); $templates = array([]);
$twig = new \Twig\Environment(new \Twig\Loader\ArrayLoader($templates)); $twig = new \Twig\Environment(new \Twig\Loader\ArrayLoader($templates));
@ -174,6 +183,11 @@ class Cms extends BaseCms
$this->extraSettings = $extraSettings; $this->extraSettings = $extraSettings;
} }
public function getAccounts(): array
{
$this->loadData();
return $this->accounts;
}
public function isNoIndex(): bool public function isNoIndex(): bool
{ {
@ -187,3 +201,4 @@ class Cms extends BaseCms
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,235 @@
<div class="row articletemplates-2">
<div class="col-xs-12">
<a class="btn-large pull-right" href="<?php echo $this->backurl ?>"><?php echo $this->translate('Zurück') ?></a>
<h1><?php echo $this->article->title ?></h1>
</div>
<div class="col-xs-12">
<ul class="nav nav-tabs" role="tablist">
<li class="active" role="presentation" ><a href="#details" data-toggle="tab"><?php echo $this->translate('Produkt') ?></a></li>
<?php if(!$this->designsettings()->get('einbetten')): ?><li><a href="#einbetten" data-toggle="tab">Einbetten</a></li><?php endif; ?>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="details">
<div class="col-md-4">
<div class="thumbnail">
<?php echo $this->image()->thumbnailImage($this->article->title, 'layouter', $this->article->file); ?>
<br/>
<!-- vorschau-bilder -->
<?php if($this->article->file1 != "" || $this->article->file2 != "" || $this->article->file3 != "" || $this->article->file4 != "" || $this->article->file5 != ""): ?>
<div class="thumbnail vorschau-bilder-klein clearfix">
<?php if($this->article->file1 != ""): ?>
<a data-toggle="modal" href="#" data-target="#preview1" title="<?php echo $this->article->title ?>"><?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file1); ?></a>
<!-- Modal: -->
<div class="modal fade" id="preview1" tabindex="-1" role="dialog" aria-labelledby="preview1Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Schließen</span></button>
<h4 class="modal-title" id="preview1Label"><?php echo $this->translate('Vorschau')?></h4>
</div>
<div class="modal-body">
<img class="center-block" src="/<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file1, true); ?>"/>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if($this->article->file2 != ""): ?>
<a data-toggle="modal" href="#" data-target="#preview2" title="<?php echo $this->article->title ?>"><?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file2); ?></a>
<!-- Modal: -->
<div class="modal fade" id="preview2" tabindex="-1" role="dialog" aria-labelledby="preview2Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Schließen</span></button>
<h4 class="modal-title" id="preview2Label"><?php echo $this->translate('Vorschau')?></h4>
</div>
<div class="modal-body">
<img class="center-block" src="/<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file2, true); ?>"/>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if($this->article->file3 != ""): ?>
<a data-toggle="modal" href="#" data-target="#preview3" title="<?php echo $this->article->title ?>"><?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file3); ?></a>
<!-- Modal: -->
<div class="modal fade" id="preview3" tabindex="-1" role="dialog" aria-labelledby="preview3Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Schließen</span></button>
<h4 class="modal-title" id="preview3Label"><?php echo $this->translate('Vorschau')?></h4>
</div>
<div class="modal-body">
<img class="center-block" src="/<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file3, true); ?>"/>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if($this->article->file4 != ""): ?>
<a data-toggle="modal" href="#" data-target="#preview4" title="<?php echo $this->article->title ?>"><?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file4); ?></a>
<!-- Modal: -->
<div class="modal fade" id="preview4" tabindex="-1" role="dialog" aria-labelledby="preview4Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Schließen</span></button>
<h4 class="modal-title" id="preview4Label"><?php echo $this->translate('Vorschau')?></h4>
</div>
<div class="modal-body">
<img class="center-block" src="/<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file4, true); ?>"/>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if($this->article->file5 != ""): ?>
<a data-toggle="modal" href="#" data-target="#preview5" title="<?php echo $this->article->title ?>"><?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file5); ?></a>
<!-- Modal: -->
<div class="modal fade" id="preview5" tabindex="-1" role="dialog" aria-labelledby="preview5Label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Schließen</span></button>
<h4 class="modal-title" id="preview5Label"><?php echo $this->translate('Vorschau')?></h4>
</div>
<div class="modal-body">
<img class="center-block" src="/<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file5, true); ?>"/>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php if ($this->admin && $this->role->level >= 40): ?>
<a class="btn btn-inverse btn-large pop_over" data-trigger="hover" data-placement="bottom" data-content="Bearbeiten Sie die Eigenschaften des Produkts." data-original-title="Eigenschaften" onclick="javascript:window.open('/admin/article/edit?sid=<?= $this->article->shop_id ?>&uid=<?= $this->article->id ?>&type=<?= $this->article->typ ?>', 'contactWindow', 'width=800,height=600,top=10,left=10,directories=no,toolbar=no,location=no,menubar=no,scrollbars=no,status=no,resizable=yes,dependent=no');return false;" href="/myshop/editarticle/<?= $this->article->uuid ?>">
<span class="glyphicon glyphicon-folder-open"></span> &nbsp; Eigenschaften bearbeiten
</a>
<?php endif; ?>
</div>
<?php
/******************************************************************************************************************************************************************************
* Beginn SPalte 2
*/
?>
<div class="col-md-8">
<form method="post" action="">
<dl> <?php echo $this->form->auflage ?></dl> <?php echo $this->form->ajax_calc_id ?>
</form>
<?php
/**
* Produktkonfiguration und Summe:
* Verschachtelte Anzeige: daher: neue Row
*/
?>
<div class="row">
<div class="col-md-7" style="padding:0 2em">
<?php if ($this->article->lager_file_preview != ""): ?>
<a href="<?= $this->image()->thumbnailImage('test', 'test', $this->article->lager_file_preview, true, true) ?>"><?php $this->translate('Vorschau') ?></a>
<?php endif; ?>
<?= $this->article->info ?>
<p><br/></p>
</div>
<div class="col-md-4 col-md-offset-1">
<div class="well" style="padding: 10px;">
<h3><?php echo $this->translate('Summe')?></h3>
<br/>
<table class="table">
<tbody>
<tr>
<td>Preis (netto):</td>
<td class="pull-right"><span
id="price_netto"><?= $this->currency->toCurrency($this->netto) ?></span>
</td>
</tr>
<tr>
<td><?= $this->translate('zzgl. ' . $this->article->mwert . '% MwSt.') ?></td>
<td class="pull-right"><span
id="price_steuer"><?= $this->currency->toCurrency(($this->brutto - $this->netto) * 1) ?></span>
</td>
</tr>
<tr>
<td><strong>Preis (brutto):</strong></td>
<td class="pull-right"><strong><span
id="price_brutto"><?= $this->currency->toCurrency($this->brutto) ?></span></strong>
</td>
</tr>
</tbody>
</table>
<form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" role="form" class="form-horizontal buy" id="buyform" method="POST" style="padding:8px">
<div class="form-group form-group-sm">
<label class="col-sm-3 control-label" for="count">Anzahl: </label>
<div class="col-sm-5 col-sm-offset-4">
<input type="text" value="1" class="form-control" name="count">
</div>
</div>
<?= $this->formHidden('load', $this->load) ?>
<input type="submit" class="btn btn-success btn-large"
value="<?= $this->translate('Buy') ?>">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<?php if(!$this->designsettings()->get('einbetten')): ?>
<div class="tab-pane" id="einbetten">
<h2><?php echo $this->translate('Einbetten') ?></h2>
<p><?php echo $this->translate('Teilen Sie dieses Produkt mit Anderen, bewerben Sie es im eigenen BLOG oder Ihrer Website') ?></p>
<div class="htmlSnippet">
<textarea onclick="this.focus(); this.select();" style="width:99%; height: 180px;">
<?php echo $this->escape($this->htmlsnippet) ?>
</textarea>
</div>
</div>
<?php endif; ?>
</div>
</div> <!-- // row articletemplates-2 -->

View File

@ -0,0 +1,49 @@
<?php
$basketArticle = $this->article['article'];
$filesOptions =$this->article['basketarticle']->getFiles();
?>
<td><?php echo $this->image()->thumbnailImage($basketArticle['title'], 'articlelist', $basketArticle['file']); ?></td>
<td><b><?php echo $basketArticle['title'] ?></b></td>
<td align="center"><?php echo$this->article['basketarticle']->getAuflage() ?></td>
<td align="right"><?php echo $this->currency->toCurrency($this->article['basketarticle']->getNetto()*$this->article['basketarticle']->getCount()) ?><p>
<a href="<?php echo $this->url(array('del' => $this->article['uuid']), 'basketdel') ?>"><?php echo $this->translate('Löschen'); ?></a></p></td>
</tr>
<tr><td colspan="4">
<?php if(is_array($this->article['options'])): ?>
<ul>
<?php foreach ($this->article['options'] as $key => $option): ?>
<li><?php echo $option ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<ul>
<?php foreach ($filesOptions as $key => $option): ?>
<li><b><a href="/uploads/<?php echo $this->shop->uid ?>/article/<?php echo $option['value'] ?>" target="_blank"><?php echo $option['name'] ?></a></b></li>
<?php endforeach; ?>
</ul>
</td>

View File

@ -0,0 +1,67 @@
<?php
$basketArticle = $this->article['article'];
$articleObj = new market_article();
$filesOptions = $this->article['basketarticle']->getFiles();
?>
<td style="text-align:center;">
<?php if(($basketArticle['a6_org_article'] == 0 || $basketArticle['a6_org_article'] == "") && ($this->article['basketarticle']->getLayouterId() == "" || $this->article['basketarticle']->getLayouterId() == false)): ?>
<?php echo $this->image()->thumbnailImage($basketArticle['title'], 'articlelist', $basketArticle['file']); ?>
<?php elseif(($basketArticle['a6_org_article'] != 0 && $basketArticle['file'] != "") && ($this->article['basketarticle']->getLayouterId() == "" || $this->article['basketarticle']->getLayouterId() == false)): ?>
<?php echo $this->image()->thumbnailImage($basketArticle['title'], 'articlelist', $basketArticle['file']); ?>
<?php else: ?>
<?= $articleObj->generatePreview($basketArticle['id'], $this->article['basketarticle']->getLayouterId()); ?>
<?php endif; ?>
</td>
<td>
<?php if(($this->article['basketarticle']->getLayouterId() == "" || $this->article['basketarticle']->getLayouterId() == false)): ?>
<strong><?php echo $basketArticle['title'] ?></strong><br />
<?php else: ?>
<strong><?php echo $this->layouter()->getTitle($this->article['basketarticle']->getLayouterId()); ?></strong><br />
<?php endif; ?>
<?php if(($this->article['options'])): ?>
<ul>
<?php foreach ($this->article['options'] as $key => $option): ?>
<?php
if(stripos($option, 'Auflage') === 0) {
$count = str_replace('Auflage: ', '', $option);
} else {
?>
<li><?php echo $option ?></li>
<?php } ?>
<?php endforeach; ?>
</ul>
<ul>
<?php foreach ($filesOptions as $key => $option): ?>
<li><b><a href="/uploads/<?php echo $this->shop->uid ?>/article/<?php echo $option['value'] ?>" target="_blank"><?php echo $option['name'] ?></a></b></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if($this->shop->basketposfield1 != ""): ?><?php echo $this->shop->basketposfield1 ?>
<form enctype="multipart/form-data" method="post">
<div><input type="text" class="span3" style="margin-bottom: 0;" name="ref_<?php echo $this->article['uuid'] ?>" value="<?php echo $this->article['basketarticle']->getRef(); ?>"/>
<input type="submit" class="btn" style="" value="SPEICHERN"/></div>
</form>
<?php endif; ?>
<?php if($this->shop->basketposfield2 != ""): ?><?php echo $this->shop->basketposfield2 ?>
<form enctype="multipart/form-data" method="post">
<div><input type="text" class="span3" style="margin-bottom: 0;" name="kst_<?php echo $this->article['uuid'] ?>" value="<?php echo $this->article['basketarticle']->getKst(); ?>"/>
<input type="submit" class="btn" style="" value="SPEICHERN"/></div>
</form>
<?php endif; ?>
</td>
<td align="center">
<?php if(isset($count)): ?>
<?php echo $count ?>
<?php else: ?>
<?php echo $this->article['basketarticle']->getCount() ?>
<?php endif; ?>
</td>
<td align="right">
<?php echo $this->currency->toCurrency($this->article['basketarticle']->getBrutto() * $this->article['basketarticle']->getCount()) ?>
<br/><a href="<?php echo $this->url(array('del' => $this->article['uuid']), 'basketdel') ?>"><?php echo $this->translate('Löschen'); ?></a>
<br/><a href="<?php echo $this->url(array('key' => $this->article['uuid']), 'articleload') ?>"><?php echo $this->translate('Bearbeiten') ?></a>
</td>

View File

@ -0,0 +1,25 @@
[approval]
; general form metainformation
user.approval.action = "/article/approval"
user.approval.method = "post"
; approval element
user.approval.elements.type.type = "radio"
user.approval.elements.type.options.label = "Freigabe?"
user.approval.elements.type.options.required = true
user.approval.elements.type.options.multiOptions.2 = "freigeben"
user.approval.elements.type.options.multiOptions.1 = "Nicht freigeben"
; approval element
user.approval.elements.text.type = "textarea"
user.approval.elements.text.options.label = "Text"
user.approval.elements.text.options.rows = 20
user.approval.elements.text.options.cols = 20
user.approval.elements.text.options.style = "width: 470px;height: 100px;"
; submit element
user.approval.elements.submit.type = "submit"
user.approval.elements.submit.options.class = "submit"
user.approval.elements.submit.options.label = "Senden"

View File

@ -0,0 +1,12 @@
elements.b2bshop.type = "checkbox"
elements.b2bshop.options.label = "B2B Shop ja/nein"
elements.b2bshop.options.required = false
elements.display_no_language.type = "checkbox"
elements.display_no_language.options.label = "Sprache nicht benutzen?"
elements.display_no_language.options.required = false
elements.einbetten.type = "checkbox"
elements.einbetten.options.label = "Einbetten nicht anzeigen?"
elements.einbetten.options.required = false

View File

@ -0,0 +1,128 @@
[production]
mode = "imagick"
languageDefault = "de_DE"
images.motivelistoverview.scale.type = "scaleWidth"
images.motivelistoverview.scale.data.width = "240"
images.motivelistoverview.scale.data.direction = "SCALE_DOWN"
images.motivelistoverview.render_copyright = "1"
images.motivelistoverviewbig.scale.type = "scaleWidth"
images.motivelistoverviewbig.scale.data.width = "600"
images.motivelistoverviewbig.scale.data.height = "300"
images.motivelistoverviewbig.scale.data.direction = "SCALE_DOWN"
images.motivelistoverviewbig.render_copyright = "1"
images.articlelist.scale.type = "scaleWidth"
images.articlelist.scale.data.width = "512"
images.articlelist.scale.data.direction = "SCALE_BOTH"
images.motivuploadlist.scale.type = "scaleWidth"
images.motivuploadlist.scale.data.width = "250"
images.motivuploadlist.scale.data.direction = "SCALE_BOTH"
images.articlelist_overview_box.scale.type = "scaleWidth"
images.articlelist_overview_box.scale.data.width = "1410"
images.articlelist_overview_box.scale.data.direction = "SCALE_BOTH"
images.articlelist_box.scale.type = "scaleWidth"
images.articlelist_box.scale.data.width = "525"
images.articlelist_box.scale.data.direction = "SCALE_BOTH"
images.top_modul_list.scale.type = "scaleWidth"
images.top_modul_list.scale.data.width = "94"
images.top_modul_list.scale.data.height = "94"
images.top_modul_list.scale.data.direction = "SCALE_BOTH"
images.motivelist.scale.type = "scaleWidth"
images.motivelist.scale.data.width = "170"
images.motivelist.scale.data.height = "131"
images.motivelist.scale.data.direction = "SCALE_BOTH"
images.motivelist.render_copyright = "1"
images.sliderbg.scale.type = "scaleWidth"
images.sliderbg.scale.data.width = "700"
images.sliderbg.scale.data.direction = "SCALE_BOTH"
images.sliderbgbig.scale.type = "scaleWidth"
images.sliderbgbig.scale.data.width = "1440"
images.sliderbgbig.scale.data.direction = "SCALE_BOTH"
images.stepcrop.scale.type = "scaleWidth"
images.stepcrop.scale.data.width = "520"
images.stepcrop.scale.data.direction = "SCALE_BOTH"
images.shoplist.scale.type = "scaleWidth"
images.shoplist.scale.data.width = "160"
images.shoplist.scale.data.height = "131"
images.shoplist.scale.data.direction = "SCALE_BOTH"
images.articletop.scale.type = "scaleWidth"
images.articletop.scale.data.width = "20"
images.articletop.scale.data.direction = "SCALE_BOTH"
images.admin.scale.type = "scaleWidth"
images.admin.scale.data.width = "90"
images.admin.scale.data.direction = "SCALE_BOTH"
images.contact.scale.type = "scaleWidth"
images.contact.scale.data.height = "106"
images.contact.scale.data.direction = "SCALE_BOTH"
images.account.scale.type = "scaleWidth"
images.account.scale.data.height = "106"
images.account.scale.data.direction = "SCALE_BOTH"
images.logo1.scale.type = "scaleWidth"
images.logo1.scale.data.width = "1440"
images.logo1.scale.data.height = "250"
images.logo1.scale.data.direction = "SCALE_BOTH_MIN"
images.logo2.scale.type = "scaleWidth"
images.logo2.scale.data.width = "1440"
images.logo2.scale.data.direction = "SCALE_BOTH"
images.overview.scale.type = "scaleWidth"
images.overview.scale.data.width = "240"
images.overview.scale.data.direction = "SCALE_DOWN"
images.productbarimage.scale.type = "scaleWidth"
images.productbarimage.scale.data.width = "170"
images.productbarimage.scale.data.height = "110"
images.productbarimage.scale.data.direction = "SCALE_BOTH"
images.articlesingle.scale.type = "scaleWidth"
images.articlesingle.scale.data.width = "350"
images.articlesingle.scale.data.direction = "SCALE_BOTH"
images.waren.scale.type = "scaleWidth"
images.waren.scale.data.width = "100"
images.waren.scale.data.direction = "SCALE_BOTH"
images.layouter.scale.type = "scaleWidth"
images.layouter.scale.data.width = "600"
images.layouter.scale.data.direction = "SCALE_BOTH"
images.designer.scale.type = "scaleWidth"
images.designer.scale.data.width = "300"
images.designer.scale.data.direction = "SCALE_BOTH"
images.little.scale.type = "scaleWidth"
images.little.scale.data.width = "50"
images.little.scale.data.direction = "SCALE_BOTH"
images.articlesinglegreater.scale.type = "scaleWidth"
images.articlesinglegreater.scale.data.width = "800"
images.articlesinglegreater.scale.data.direction = "SCALE_BOTH"
images.product_overview.scale.type = "scaleWidth"
images.product_overview.scale.data.width = "1410"
images.product_card.scale.type = "scaleWidth"
images.product_card.scale.data.width = "525"
[development : production]
[testing : production]

View File

@ -0,0 +1,29 @@
[violation]
violation.action = "/index/violation"
violation.method = "post"
violation.class = "niceform"
violation.elements.what.type = "select"
violation.elements.what.options.label = "Vorauswahl"
violation.elements.what.options.required = true
violation.elements.name.type = "text"
violation.elements.name.options.label = "Name"
violation.elements.name.options.required = true
violation.elements.email.type = "text"
violation.elements.email.options.label = "EMail"
violation.elements.email.options.required = true
violation.elements.text.type = "textarea"
violation.elements.text.options.label = "Text"
violation.elements.text.options.required = true
violation.elements.text.options.rows = 6
violation.elements.text.options.cols = 39
violation.elements.submit.type = "submit"
violation.elements.submit.options.class = "submit"
violation.elements.submit.options.label = "Senden"

View File

@ -0,0 +1,3 @@
title = "Shopdesign"
version = "1.0"
author = "Primabu Presets"

View File

@ -0,0 +1,132 @@
[register]
global.class ="form-horizontal"
; general form metainformation
user.login.method = "post"
; username element
user.login.legend = "Allgemeines"
user.login.prefixPath.element.prefix = "TP_Form_Element"
user.login.prefixPath.element.path = "TP/Form/Element"
; email element
user.login.elements.self_email.type = "Helptext"
user.login.elements.self_email.options.label = "Email*"
user.login.elements.self_email.options.helptext = "Die Emailadresse dient dem Login. Der Anwender erhält automatisch eine Einladung an diese Emailadresse.."
user.login.elements.self_email.options.required = true
user.login.elements.self_email.options.validators.email.validator = "EmailAddress"
user.login.elements.self_email.options.validators.Db_RecordExists.validator = "Db_NoRecordExistsDoctrine"
user.login.elements.self_email.options.validators.Db_RecordExists.options.table = "Contact"
user.login.elements.self_email.options.validators.Db_RecordExists.options.field = "self_email"
; firstname element
user.rech.legend = "Anschrift"
user.rech.elements.self_anrede.type = "select"
user.rech.elements.self_anrede.options.label = "Anrede"
user.rech.elements.self_anrede.options.required = false
user.rech.elements.self_anrede.options.multiOptions.1 = "Herr"
user.rech.elements.self_anrede.options.multiOptions.2 = "Frau"
user.rech.elements.self_anrede.options.multiOptions.3 = "Firma"
user.rech.elements.self_anrede.options.multiOptions.4 = "Herr Dr."
user.rech.elements.self_anrede.options.multiOptions.5 = "Frau Dr."
user.rech.elements.self_anrede.options.multiOptions.6 = "Herr Prof."
user.rech.elements.self_anrede.options.multiOptions.7 = "Frau Prof."
user.rech.elements.self_anrede.options.multiOptions.8 = "Herr Prof. Dr."
user.rech.elements.self_anrede.options.multiOptions.9 = "Frau Prof. Dr."
user.rech.elements.self_firstname.type = "text"
user.rech.elements.self_firstname.options.label = "Firstname*"
user.rech.elements.self_firstname.options.required = true
; lastname element
user.rech.elements.self_lastname.type = "text"
user.rech.elements.self_lastname.options.label = "Lastname*"
user.rech.elements.self_lastname.options.required = true
; lastname element
user.rech.elements.self_department.type = "text"
user.rech.elements.self_department.options.label = "Company"
; street element
user.rech.elements.self_street.type = "text"
user.rech.elements.self_street.options.label = "Street*"
user.rech.elements.self_street.options.required = true
; housenumber element
user.rech.elements.self_house_number.type = "text"
user.rech.elements.self_house_number.options.label = "Housenumber*"
user.rech.elements.self_house_number.options.required = true
; zip element
user.rech.elements.self_zip.type = "text"
user.rech.elements.self_zip.options.label = "Zip*"
user.rech.elements.self_zip.options.required = true
; city element
user.rech.elements.self_city.type = "text"
user.rech.elements.self_city.options.label = "City*"
user.rech.elements.self_city.options.required = true
; tel element
user.rech.elements.self_phone.type = "Mobile"
user.rech.elements.self_phone.options.label = "LV/Vor./Tel/Durch."
; handy element
user.rech.elements.self_mobile.type = "Mobile"
user.rech.elements.self_mobile.options.label = "LV/Vor./Handy"
; fax element
user.rech.elements.self_fax.type = "Mobile"
user.rech.elements.self_fax.options.label = "LV/Vor./Fax/Durch."
; firstname element
user.liefer.legend = "Lieferanschrift"
user.liefer.elements.firstname.type = "text"
user.liefer.elements.firstname.options.label = "Firstname*"
user.liefer.elements.firstname.options.required = true
; lastname element
user.liefer.elements.lastname.type = "text"
user.liefer.elements.lastname.options.label = "Lastname*"
user.liefer.elements.lastname.options.required = true
; lastname element
user.liefer.elements.company.type = "text"
user.liefer.elements.company.options.label = "Firma"
; street element
user.liefer.elements.street.type = "text"
user.liefer.elements.street.options.label = "Street*"
user.liefer.elements.street.options.required = true
; housenumber element
user.liefer.elements.house_number.type = "text"
user.liefer.elements.house_number.options.label = "Housenumber*"
user.liefer.elements.house_number.options.required = true
; zip element
user.liefer.elements.zip.type = "text"
user.liefer.elements.zip.options.label = "Zip*"
user.liefer.elements.zip.options.required = true
; city element
user.liefer.elements.city.type = "text"
user.liefer.elements.city.options.label = "City*"
user.liefer.elements.city.options.required = true
; tel element
user.liefer.elements.phone.type = "text"
user.liefer.elements.phone.options.label = "Tel"
; submit element
user.submit.elements.submit.type = "submit"
user.submit.elements.submit.options.name = "submit"
user.submit.elements.submit.options.label = "Register"
user.liefersubmit.elements.submit.type = "submit"
user.liefersubmit.elements.submit.options.class = "green"
user.liefersubmit.elements.submit.options.name = "st"
user.liefersubmit.elements.submit.options.label = "Use Delivery"

View File

@ -0,0 +1,145 @@
[register]
global.class ="form-horizontal"
; general form metainformation
user.login.action = "/user/register"
user.login.method = "post"
; username element
user.login.legend = "Allgemeines"
user.login.prefixPath.element.prefix = "TP_Form_Element"
user.login.prefixPath.element.path = "TP/Form/Element"
; email element
user.login.elements.self_email.type = "Helptext"
user.login.elements.self_email.options.label = "Email*"
user.login.elements.self_email.options.helptext = "Die Emailadresse dient dem Login. Der Anwender erhält automatisch eine Einladung an diese Emailadresse.."
user.login.elements.self_email.options.required = true
user.login.elements.self_email.options.validators.email.validator = "EmailAddress"
user.login.elements.self_email.options.validators.Db_RecordExists.validator = "Db_NoRecordExistsDoctrine"
user.login.elements.self_email.options.validators.Db_RecordExists.options.table = "Contact"
user.login.elements.self_email.options.validators.Db_RecordExists.options.field = "self_email"
; firstname element
user.rech.legend = "Anschrift"
user.rech.elements.self_anrede.type = "select"
user.rech.elements.self_anrede.options.label = "Anrede"
user.rech.elements.self_anrede.options.required = false
user.rech.elements.self_anrede.options.multiOptions.1 = "Herr"
user.rech.elements.self_anrede.options.multiOptions.2 = "Frau"
user.rech.elements.self_anrede.options.multiOptions.3 = "Firma"
user.rech.elements.self_anrede.options.multiOptions.4 = "Herr Dr."
user.rech.elements.self_anrede.options.multiOptions.5 = "Frau Dr."
user.rech.elements.self_anrede.options.multiOptions.6 = "Herr Prof."
user.rech.elements.self_anrede.options.multiOptions.7 = "Frau Prof."
user.rech.elements.self_anrede.options.multiOptions.8 = "Herr Prof. Dr."
user.rech.elements.self_anrede.options.multiOptions.9 = "Frau Prof. Dr."
user.rech.elements.self_firstname.type = "text"
user.rech.elements.self_firstname.options.label = "Firstname*"
user.rech.elements.self_firstname.options.required = true
; lastname element
user.rech.elements.self_lastname.type = "text"
user.rech.elements.self_lastname.options.label = "Lastname*"
user.rech.elements.self_lastname.options.required = true
; lastname element
user.rech.elements.self_department.type = "text"
user.rech.elements.self_department.options.label = "Company"
; street element
user.rech.elements.self_street.type = "text"
user.rech.elements.self_street.options.label = "Street*"
user.rech.elements.self_street.options.required = true
; housenumber element
user.rech.elements.self_house_number.type = "text"
user.rech.elements.self_house_number.options.label = "Housenumber*"
user.rech.elements.self_house_number.options.required = true
; zip element
user.rech.elements.self_zip.type = "text"
user.rech.elements.self_zip.options.label = "Zip*"
user.rech.elements.self_zip.options.required = true
; city element
user.rech.elements.self_city.type = "text"
user.rech.elements.self_city.options.label = "City*"
user.rech.elements.self_city.options.required = true
; tel element
user.rech.elements.self_phone.type = "Mobile"
user.rech.elements.self_phone.options.label = "LV/Vor./Tel/Durch."
; handy element
user.rech.elements.self_mobile.type = "Mobile"
user.rech.elements.self_mobile.options.label = "LV/Vor./Handy"
; fax element
user.rech.elements.self_fax.type = "Mobile"
user.rech.elements.self_fax.options.label = "LV/Vor./Fax/Durch."
user.addr2.legend = "Anschrift 2"
user.addr2.elements.department_2.type = "text"
user.addr2.elements.department_2.options.label = "Company"
user.addr2.elements.street_2.type = "text"
user.addr2.elements.street_2.options.label = "Straße"
user.addr2.elements.street_2.options.required = false
user.addr2.elements.house_number_2.type = "text"
user.addr2.elements.house_number_2.options.label = "Hausnummer"
user.addr2.elements.house_number_2.options.required = false
user.addr2.elements.zip_2.type = "text"
user.addr2.elements.zip_2.options.label = "PLZ"
user.addr2.elements.zip_2.options.required = false
user.addr2.elements.city_2.type = "text"
user.addr2.elements.city_2.options.label = "Ort"
user.addr2.elements.city_2.options.required = false
user.addr2.elements.phone_2.type = "Mobile"
user.addr2.elements.phone_2.options.label = "LV/Vor./Tel/Durch."
user.addr2.elements.mobile_2.type = "Mobile"
user.addr2.elements.mobile_2.options.label = "LV/Vor./Handy"
user.addr2.elements.fax_2.type = "Mobile"
user.addr2.elements.fax_2.options.label = "LV/Vor./Fax/Durch."
user.addr2.elements.internet_2.type = "text"
user.addr2.elements.internet_2.options.label = "Web"
user.addr2.elements.internet_2.options.required = false
user.addr3.legend = "Anschrift 3"
user.addr3.elements.department_3.type = "text"
user.addr3.elements.department_3.options.label = "Company"
user.addr3.elements.street_3.type = "text"
user.addr3.elements.street_3.options.label = "Straße"
user.addr3.elements.street_3.options.required = false
user.addr3.elements.house_number_3.type = "text"
user.addr3.elements.house_number_3.options.label = "Hausnummer"
user.addr3.elements.house_number_3.options.required = false
user.addr3.elements.zip_3.type = "text"
user.addr3.elements.zip_3.options.label = "PLZ"
user.addr3.elements.zip_3.options.required = false
user.addr3.elements.city_3.type = "text"
user.addr3.elements.city_3.options.label = "Ort"
user.addr3.elements.city_3.options.required = false
user.addr3.elements.phone_3.type = "Mobile"
user.addr3.elements.phone_3.options.label = "LV/Vor./Tel/Durch."
user.addr3.elements.mobile_3.type = "Mobile"
user.addr3.elements.mobile_3.options.label = "LV/Vor./Handy"
user.addr3.elements.fax_3.type = "Mobile"
user.addr3.elements.fax_3.options.label = "LV/Vor./Fax/Durch."
user.addr3.elements.internet_3.type = "text"
user.addr3.elements.internet_3.options.label = "Web"
user.addr3.elements.internet_3.options.required = false
; submit element
user.submit.elements.submit.type = "submit"
user.submit.elements.submit.options.name = "submit"
user.submit.elements.submit.options.label = "Register"
user.liefersubmit.elements.submit.type = "submit"
user.liefersubmit.elements.submit.options.class = "green"
user.liefersubmit.elements.submit.options.name = "st"
user.liefersubmit.elements.submit.options.label = "Use Delivery"

View File

@ -0,0 +1,116 @@
[add]
global.class ="form-horizontal"
; firstname element
user.id ="register"
user.class ="form-horizontal"
user.legend = "Lieferanschrift"
user.elements.anrede.type = "select"
user.elements.anrede.options.label = "Anrede"
user.elements.anrede.options.required = false
user.elements.anrede.options.multiOptions.1 = "Herr"
user.elements.anrede.options.multiOptions.2 = "Frau"
user.elements.anrede.options.multiOptions.3 = "Firma"
user.elements.anrede.options.multiOptions.4 = "Herr Dr."
user.elements.anrede.options.multiOptions.5 = "Frau Dr."
user.elements.anrede.options.multiOptions.6 = "Herr Prof."
user.elements.anrede.options.multiOptions.7 = "Frau Prof."
user.elements.anrede.options.multiOptions.8 = "Herr Prof. Dr."
user.elements.anrede.options.multiOptions.9 = "Frau Prof. Dr."
user.elements.anrede.options.class = "custom-select"
user.elements.company.type = "text"
user.elements.company.options.label = "Firma"
user.elements.company.options.class = "form-control"
user.elements.firstname.type = "text"
user.elements.firstname.options.label = "Firstname*"
user.elements.firstname.options.required = true
user.elements.firstname.options.class = "form-control"
; lastname element
user.elements.lastname.type = "text"
user.elements.lastname.options.label = "Lastname*"
user.elements.lastname.options.required = true
user.elements.lastname.options.class = "form-control"
; lastname element
user.elements.company.type = "text"
user.elements.company.options.label = "Firma"
user.elements.company.options.class = "form-control"
; street element
user.elements.street.type = "text"
user.elements.street.options.label = "Street*"
user.elements.street.options.required = true
user.elements.street.options.class = "form-control"
; housenumber element
user.elements.house_number.type = "text"
user.elements.house_number.options.label = "Housenumber*"
user.elements.house_number.options.required = true
user.elements.house_number.options.class = "form-control"
; zip element
user.elements.zip.type = "text"
user.elements.zip.options.label = "Zip*"
user.elements.zip.options.required = true
user.elements.zip.options.class = "form-control"
; city element
user.elements.city.type = "text"
user.elements.city.options.label = "City*"
user.elements.city.options.required = true
user.elements.city.options.class = "form-control"
; city element
user.elements.country.type = "select"
user.elements.country.options.label = "Land*"
user.elements.country.options.required = true
user.elements.country.options.class = "custom-select"
; tel element
user.elements.phone.type = "text"
user.elements.phone.options.label = "Telefon"
user.elements.phone.options.class = "form-control"
; mobile phone
user.elements.fax.type = "text"
user.elements.fax.options.label = "Fax"
user.elements.fax.options.class = "form-control"
; mobile phone
user.elements.mobil_phone.type = "text"
user.elements.mobil_phone.options.label = "Handy"
user.elements.mobil_phone.options.class = "form-control"
; email phone
user.elements.email.type = "text"
user.elements.email.options.label = "E-Mail"
user.elements.email.options.class = "form-control"
; ustid
user.elements.ustid.type = "text"
user.elements.ustid.options.label = "USt-IdNr."
user.elements.ustid.options.class = "form-control"
; what element
user.elements.type.type = "MultiCheckbox"
user.elements.type.options.label = "Anlegen als"
user.elements.type.options.multiOptions.1 = "Rechnungsadresse"
user.elements.type.options.multiOptions.2 = "Lieferadresse"
user.elements.type.options.multiOptions.3 = "Absendeadresse"
; submit element
user.elements.submit.type = "submit"
user.elements.submit.options.class = "btn btn-primary"
user.elements.submit.options.label = "Anlegen"
user.elements.update.type = "submit"
user.elements.update.options.class = "btn btn-primary"
user.elements.update.options.label = "Speichern"
user.elements.del.type = "submit"
user.elements.del.options.class = "btn btn-primary"
user.elements.del.options.label = "Löschen"

Some files were not shown because too many files have changed in this diff Show More