Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEW] upload media to order #153

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ client/html/tests/tmp
*.junit.xml
*.log
*.ser

.idea
vendor
42 changes: 36 additions & 6 deletions client/html/src/Client/Html/Basket/Standard/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
namespace Aimeos\Client\Html\Basket\Standard;


use Illuminate\Support\Facades\Log;
use Illuminate\Http\UploadedFile;

/**
* Default implementation of standard basket HTML client.
*
Expand Down Expand Up @@ -458,8 +461,18 @@ protected function addCoupon( \Aimeos\MW\View\Iface $view )
*/
protected function addProducts( \Aimeos\MW\View\Iface $view )
{
$attrIds[] = \Aimeos\MShop::create( $this->getContext(), 'attribute' )->find( 'custom', [], 'product', 'upload' )->getId();

$attrIds[] = \Aimeos\MShop::create( $this->getContext(), 'attribute' )->find( 'file', [], 'product', 'upload' )->getId();

$fs = $this->getContext()->fs( 'fs' );

if( !$fs->has('basket-upload' ) ) {
$fs->mkdir( 'basket-upload' );
}

$context = $this->getContext();
$domains = ['attribute', 'media', 'price', 'product', 'text'];
$domains = ['attribute', 'media', 'price', 'product', 'text', 'custom'];

$basketCntl = \Aimeos\Controller\Frontend::create( $context, 'basket' );
$productCntl = \Aimeos\Controller\Frontend::create( $context, 'product' )->uses( $domains );
Expand All @@ -482,12 +495,29 @@ protected function addProducts( \Aimeos\MW\View\Iface $view )
$list = [];
$entries = (array) $view->param( 'b_prod', [] );

foreach( $entries as $values )
{
if( isset( $values['prodid'] ) ) {
$list[] = $values['prodid'];
for($i = 0; $i < count($entries); ++$i) {
$paths = [];
foreach ($attrIds as $attrId) {
if (isset($entries[$i]['attrcustid'][$attrId]) && is_array($entries[$i]['attrcustid'][$attrId])) {
/** @var UploadedFile $file */
foreach ($entries[$i]['attrcustid'][$attrId] as $file) {
$filepath = 'basket-upload/' . md5($file->getFilename() . microtime(true)) . '.' . $file->extension();
try {
$stream = fopen($file->getRealPath(), 'r+');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check return value of fopen()

$fs->writes($filepath, $stream);
fclose($stream);
} catch (\Exception $ex) {
Log::error($ex->getMessage());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log::error() is also Laravel specific. Use $this->getContext()->logger()->log() instead

}
$paths[] = $filepath;
}
$entries[$i]['attrcustid'][$attrId] = $paths;
}
if (isset($entries[$i]['prodid'])) {
$list[] = $entries[$i]['prodid'];
}
}
}
}

foreach( $entries as $values )
{
Expand Down
2 changes: 1 addition & 1 deletion client/html/templates/basket/standard/body-standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<?php if( isset( $this->standardBasket ) ) : ?>
<h1><?= $enc->html( $this->translate( 'client', 'Basket' ), $enc::TRUST ) ?></h1>

<form method="POST" action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, [], [], $basketConfig ) ) ?>">
<form enctype="multipart/form-data" method="POST" action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, [], [], $basketConfig ) ) ?>">
<?= $this->csrf()->formfield() ?>


Expand Down
7 changes: 5 additions & 2 deletions client/html/templates/catalog/detail/body-standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,11 @@
<?= $this->block()->get( 'catalog/detail/service' ) ?>


<form method="POST" action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, ( $basketSite ? ['site' => $basketSite] : [] ), [], $basketConfig ) ) ?>">
<!-- catalog.detail.csrf -->
<form enctype="multipart/form-data"
method="POST"
action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, ( $basketSite ? ['site' => $basketSite] : [] ), [], $basketConfig ) ) ?>"
>
<!-- catalog.detail.csrf asd -->
<?= $this->csrf()->formfield() ?>
<!-- catalog.detail.csrf -->

Expand Down
53 changes: 50 additions & 3 deletions client/html/templates/common/partials/attribute-standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@


?>
<script type="text/javascript">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline JS doesn't work with CSP and must be moved to the JS file

function removeFile(event) {
console.log($(event).parents('.upload-file-entry').remove());
}
function slugName(name) {
return name.toLowerCase().replaceAll(' ', '_').replaceAll('.', '_');
}
function updateFileList() {
$('input[type=file]').each((i, input) => {
$('.upload-file-list').html('');
if(input.files && input.files.length > 0) {
$('.upload-view').addClass('bg-success');
$('.upload-view').attr('data-title', $('.upload-view').attr('data-title').replace('hinzufügen', 'ändern'));
for(let file of input.files) {
const localUrl = URL.createObjectURL(file);
$el = $('<div class="upload-file-entry"></div>');
$el.attr('id', `file-${slugName(file.name)}`);
$el.append(`<img src="${localUrl}" alt="image">`);
$el.append(`<span class="m-2">${file.name}</span>`);
$('.upload-file-list').append($el);
}
}
})
}
if (window.fileListInterval) {
clearInterval(window.fileListInterval);
window.fileListInterval = null;
}

</script>
<ul class="selection">

<?php foreach( $this->typemap( $this->productItem->getRefItems( 'attribute', null, 'config' ) ) as $code => $attributes ) : ?>
Expand Down Expand Up @@ -188,9 +218,10 @@
<ul class="selection">

<?php foreach( $this->productItem->getRefItems( 'attribute', null, 'custom' ) as $id => $attribute ) : $key = $attribute->getType() . '-' . $attribute->getCode() ?>

<li class="select-item <?= $enc->attr( $key ) ?>">
<label for="select-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>" class="select-name"><?= $enc->html( $this->translate( 'client/code', $attribute->getName() ) ) ?></label>
<?php if ( $attribute->getType() !== 'upload' ) { ?>
<label for="select-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>" class="select-name"><?= $enc->html( $this->translate( 'client/code', $attribute->getName() ) ) ?></label>
<?php } ?>

<?php if( $hint = $this->translate( 'client/code', $key . '-hint', null, 0, false ) ) : ?>
<div class="select-hint"><?= $enc->html( $hint ) ?></div>
Expand All @@ -207,10 +238,26 @@
>
<?php break; case 'date': ?>
<input id="select-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>" class="form-control" type="date" name="<?= $enc->attr( $this->formparam( ['b_prod', 0, 'attrcustid', $id] ) ) ?>">
<?php break;case 'upload': ?>
<div class="upload-wrapper">
<div class="upload-view"
data-title="<?= $enc->html( $this->translate( 'client/code', $attribute->getName() ) ) ?> Klicken zum hinzufügen."
onclick="document.querySelector('#upload-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>').click()"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No inline JS please because this won't work because of Content Security Policy rules

>
</div>
<input id="upload-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>"
class="form-control hidden"
type="file"
name="<?= $enc->attr( $this->formparam( ['b_prod', 0, 'attrcustid', $id] ) ) ?>[]"
multiple
onchange="updateFileList()"
>
<div class="upload-file-list p-1">
</div>
</div>
<?php break; default: ?>
<input id="select-<?= $enc->attr( $this->productItem->getId() . '-' . $key ) ?>" class="form-control" type="text" name="<?= $enc->attr( $this->formparam( ['b_prod', 0, 'attrcustid', $id] ) ) ?>">
<?php endswitch ?>

</div>
</li>

Expand Down
5 changes: 4 additions & 1 deletion client/html/templates/common/partials/products-standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,10 @@
$basketConfig = $this->config( 'client/html/basket/standard/url/config', [] );
?>

<form class="basket" method="POST" action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, [], [], $basketConfig ) ) ?>">
<form class="basket"
method="POST"
action="<?= $enc->attr( $this->url( $basketTarget, $basketController, $basketAction, [], [], $basketConfig ) ) ?>"
>
<!-- catalog.lists.items.csrf -->
<?= $this->csrf()->formfield() ?>
<!-- catalog.lists.items.csrf -->
Expand Down
17 changes: 17 additions & 0 deletions client/html/templates/common/summary/detail-standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,23 @@
<?php endif ?>
<?php endforeach ?>

<?php foreach( $product->getAttributeItems( 'custom' ) as $attribute) : ?>
<?php if( $attribute->getCode() === 'upload' ) : ?>
<div class="attr-list attr-type-<?= $enc->attr( $attribute ) ?>">
<span class="name"><?= $attribute->getName() ?></span>
<span class="value">
<span class="image-uploads">
<?php foreach( $attribute->getValue() as $upload) : ?>
<span class="image-upload">
<img src="<?= $enc->attr( $this->content($upload) ) ?>" alt="upload-image" />
</span>
<?php endforeach ?>
</span>
</span>
</div>
<?php endif ?>
<?php endforeach ?>

<?php if( $unhide && ( $attribute = $product->getAttributeItem( 'download', 'hidden' ) ) !== null ) : ?>
<ul class="attr-list attr-list-hidden">
<li class="attr-item attr-code-<?= $enc->attr( $attribute->getCode() ) ?>">
Expand Down
88 changes: 87 additions & 1 deletion client/html/themes/default/aimeos.css
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,77 @@ html.no-js .catalog-filter-price:hover .price-lists {
list-style: none;
}

.catalog-list-items .basket .select-item .upload-wrapper,
.catalog-detail-basket .select-item .upload-wrapper {
display: block;
}

.catalog-list-items .basket .select-item .upload-wrapper input,
.catalog-detail-basket .select-item .upload-wrapper input {
display: none;
}

.catalog-list-items .basket .select-item .upload-wrapper .upload-view,
.catalog-detail-basket .select-item .upload-wrapper .upload-view {
position: relative;
height: 60px;
width: 100%;
border: 1px dashed #929292;
border-radius: 1px;
overflow: hidden;
background-color: #f3f3f3;

cursor: pointer;
}

.catalog-list-items .basket .select-item .upload-wrapper .upload-view::after,
.catalog-detail-basket .select-item .upload-wrapper .upload-view::after {
position: absolute;
content: attr(data-title);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

.catalog-list-items .basket .select-item .upload-wrapper .upload-file-list,
.catalog-detail-basket .select-item .upload-wrapper .upload-file-list {
display: flex;
flex-wrap: wrap;
justify-content: center;

margin-right: -12px;
margin-bottom: -12px;
}


.catalog-list-items .basket .select-item .upload-wrapper .upload-file-list .upload-file-entry,
.catalog-detail-basket .select-item .upload-wrapper .upload-file-list .upload-file-entry {
border: 1px solid #f8f8f8;
border-radius: 1px;

background-color: #fcfcfc;

overflow: hidden;

display: flex;
flex-direction: column;
align-content: center;
justify-content: center;
flex-wrap: nowrap;
align-items: center;

margin-right: 12px;
margin-bottom: 12px;

font-weight: bolder;
}

.catalog-list-items .basket .select-item .upload-wrapper .upload-file-list .upload-file-entry img,
.catalog-detail-basket .select-item .upload-wrapper .upload-file-list .upload-file-entry img {
max-height: 100px;
width: auto;
}

.catalog-list-items .basket .select-name,
.catalog-detail-baske .select-name {
min-width: 5rem;
Expand Down Expand Up @@ -3688,6 +3759,21 @@ html.no-js .catalog-filter-price:hover .price-lists {
content: ":";
}

.aimeos .common-summary-detail .image-uploads {
display: flex;
}

.aimeos .common-summary-detail .image-uploads .image-upload {
margin-right: 1rem;
flex-grow: 1;
flex-shrink: 1;
}

.aimeos .common-summary-detail .image-uploads .image-uploads img {
max-height: 100px;
width: auto;
}

.aimeos .common-summary-detail tfoot tr.quantity,
.aimeos .common-summary-detail tr.subtotal,
.aimeos .common-summary-detail tr.delivery,
Expand Down Expand Up @@ -7182,4 +7268,4 @@ aside .catalog-session-pinned .pinned-items {

.aimeos .card .btn {
margin: 0.5rem 1rem;
}
}
25 changes: 22 additions & 3 deletions client/html/themes/default/aimeos.js
Original file line number Diff line number Diff line change
Expand Up @@ -1318,9 +1318,28 @@ AimeosCatalog = {
$(".catalog-detail-basket form, .catalog-list-items form").on("submit", function(ev) {

Aimeos.createOverlay();
$.post($(this).attr("action"), $(this).serialize(), function(data) {
Aimeos.createContainer(AimeosBasketStandard.updateBasket(data));
});
let fileInput = $("input[type=file]");
if (fileInput.length > 0 && fileInput[0].files.length > 0) {
const formData = new FormData($(this)[0]);
formData.append($(fileInput[0]).attr('name'), $(fileInput[0]).prop('files'));

$.ajax({
url: $(this).attr("action"),
type: 'post',
data: formData,
contentType: false,
processData: false,
success: function(response) {
if(response != 0) {
Aimeos.createContainer(AimeosBasketStandard.updateBasket(response));
}
},
});
} else {
$.post($(this).attr("action"), $(this).serialize(), function (data) {
Aimeos.createContainer(AimeosBasketStandard.updateBasket(data));
});
}

return false;
});
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"aimeos/aimeos-core": "dev-master",
"aimeos/ai-controller-jobs": "dev-master",
"aimeos/ai-controller-frontend": "dev-master",
"illuminate/http": "^8.54.0",
"tecnickcom/tcpdf": "^6.4.1"
},
"require-dev": {
Expand Down
Loading