バージョン選択

フォーラム

メニュー

オンライン状況

45 人のユーザが現在オンラインです。 (17 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 45
もっと...

サイト内検索

質問 > 管理機能 > 画像のアップロードに失敗してしまう

管理機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
r_yamada
投稿日時: 2024/9/21 21:43
対応状況: −−−
常連
登録日: 2024/9/2
居住地:
投稿: 39
画像のアップロードに失敗してしまう
[EC-CUBE]4.3、新規インストール
[レンタルサーバ]ローカル環境
[OS]windows10
[PHP]8.3.11
[データベース]mysql8.0
[WEBサーバ]DockerDesktop4.33.1(Ubuntu)
[ブラウザ]chrome
[導入プラグインの有無]なし
[カスタマイズの有無]なし
[現象]
お世話になっております。
コンテンツ管理に独自のメーカー管理というページを追加し、自身で追加した画像ファイルの入力フォーム(商品登録画面の商品画像と同じ構造)を作成したのですが、画像ファイル選択後のアップロード処理(登録ではなくドラッグアンドドロップした際の処理)にて
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
のエラーが発生し、アップロードをすることができません。
こちらRouteやURLの設定に誤りがあると思い見直しているのですが特定できず、何が誤っているかご教示いただけないでしょうか?
お手数ですがご回答いただけますと幸いです。

・メーカー管理ページのURL
http://localhost:8080/admin/content/maker/1/edit

・app\Customize\Controller\Admin\Content\MakerController.php

namespace Customize\Controller\Admin\Content;

use Eccube\Controller\AbstractController;
use Eccube\Entity\Block;
use Eccube\Entity\Master\DeviceType;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Eccube\Form\Type\Admin\BlockType;
use Eccube\Repository\Master\DeviceTypeRepository;
use Eccube\Util\CacheUtil;
use Eccube\Util\StringUtil;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Twig\Environment;
use Customize\Entity\Master\Maker;
use Customize\Repository\Master\MakerRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Customize\Form\Extension\Admin\MakerType;
use Customize\Entity\MakerImage;
use Customize\Repository\Extension\MakerImageRepository;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
use Symfony\Component\Routing\RouterInterface;

class MakerController extends AbstractController
{
/**
* @var MakerRepository
*/
protected $makerRepository;

/**
* @var MakerImageRepository
* @param MakerImageRepository $makerImageRepository
*/
protected $makerImageRepository;

public function __construct(
MakerRepository $makerRepository,
MakerImageRepository $makerImageRepository
) {
$this->makerRepository = $makerRepository;
}

/**
* メーカー管理ページを表示
*
* @Route("/%eccube_admin_route%/content/maker", name="admin_content_maker", methods={"GET", "POST"})
* @Template("@admin/Content/maker.twig")
*/
public function index(Request $request)
{
$Makers = $this->makerRepository->getList();

$event = new EventArgs(
[
'Makers' => $Makers,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::ADMIN_CONTENT_BLOCK_INDEX_COMPLETE);

return [
'Makers' => $Makers,
];
}

/**
* @Route("/%eccube_admin_route%/content/maker/new", name="admin_content_maker_new", methods={"GET", "POST"})
* @Route("/%eccube_admin_route%/content/maker/{id}/edit", requirements={"id" = "\d+"}, name="admin_content_maker_edit", methods={"GET", "POST"})
* @Template("@admin/Content/maker_edit.twig")
*
*/
public function edit(Request $request, RouterInterface $router, CacheUtil $cacheUtil, $id = null)
{
if ($id) {
$Maker = $this->makerRepository->find($id);
if (!$Maker) {
throw new NotFoundHttpException();
}
} else {
$Maker = new \Customize\Entity\Master\Maker();

}

$builder = $this->formFactory
->createBuilder(MakerType::class, $Maker);

$event = new EventArgs(
[
'builder' => $builder,
'Maker' => $Maker,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::ADMIN_CONTENT_NEWS_EDIT_INITIALIZE);

$form = $builder->getForm();


// ファイルの登録
$images = [];
$MakerImages = $Maker->getMakerImage();
foreach ($MakerImages as $MakerImage) {
$images[] = $MakerImage->getFileName();
}
$form['images']->setData($images);


$form->handleRequest($request);

//更新時
if ($form->isSubmitted() && $form->isValid()) {
$Maker = $form->getData();
$this->makerRepository->save($Maker);


// 画像の登録
$add_images = $form->get('add_images')->getData();
foreach ($add_images as $add_image) {
$MakerImage = new \Eccube\Entity\MakerImage();
$MakerImage
->setFileName($add_image)
->setProduct($Maker)
->setSortNo(1);
$Maker->addMakerImage($MakerImage);
$this->entityManager->persist($MakerImage);

// 移動
$file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image);
$file->move($this->eccubeConfig['eccube_save_image_dir']);
}

// 画像の削除
$delete_images = $form->get('delete_images')->getData();
$fs = new Filesystem();
foreach ($delete_images as $delete_image) {
$MakerImage = $this->makerImageRepository->findOneBy([
'Maker' => $Maker,
'file_name' => $delete_image,
]);

if ($MakerImage instanceof MakerImage) {
$Product->removeMakerImage($MakerImage);
$this->entityManager->remove($MakerImage);
$this->entityManager->flush();

// 他に同じ画像を参照する商品がなければ画像ファイルを削除
if (!$this->makerImageRepository->findOneBy(['file_name' => $delete_image])) {
$fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image);
}
} else {
// 追加してすぐに削除した画像は、Entityに追加されない
$fs->remove($this->eccubeConfig['eccube_temp_image_dir'].'/'.$delete_image);
}
}

$this->entityManager->flush();

if ($maker_image = $request->request->all()['admin_product']['maker_image'] ?? []) {
foreach ($maker_image as $sortNo => $filename) {
$MakerImage = $this->makerImageRepository
->findOneBy([
'file_name' => pathinfo($filename, PATHINFO_BASENAME),
'Maker' => $Maker,
]);
if ($MakerImage !== null) {
$MakerImage->setSortNo($sortNo);
$this->entityManager->persist($MakerImage);
}
}
$this->entityManager->flush();
}


$event = new EventArgs(
[
'form' => $form,
'Maker' => $Maker,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::ADMIN_CONTENT_MAKER_EDIT_COMPLETE);

$this->addSuccess('admin.common.save_complete', 'admin');

// キャッシュの削除
$cacheUtil->clearDoctrineCache();

return $this->redirectToRoute('admin_content_maker_edit', ['id' => $Maker->getId()]);
}

return [
'form' => $form->createView(),
'Maker' => $Maker,
];
}

/**
* 画像アップロード時にリクエストされるメソッド.
*
* @see https://pqina.nl/filepond/docs/api/server/#process
* @Route("/%eccube_admin_route%/content/maker/image/process", name="admin_maker_image_process", methods={"POST"})
*/
public function imageProcess(Request $request)
{
if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
throw new BadRequestHttpException();
}

$images = $request->files->get('admin_maker');

$allowExtensions = ['gif', 'jpg', 'jpeg', 'png'];
$files = [];
if (count($images) > 0) {
foreach ($images as $img) {
foreach ($img as $image) {
// ファイルフォーマット検証
$mimeType = $image->getMimeType();
if (0 !== strpos($mimeType, 'image')) {
throw new UnsupportedMediaTypeHttpException();
}

// 拡張子
$extension = $image->getClientOriginalExtension();
if (!in_array(strtolower($extension), $allowExtensions)) {
throw new UnsupportedMediaTypeHttpException();
}

$filename = date('mdHis').uniqid('_').'.'.$extension;
$image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
$files[] = $filename;
}
}
}

$event = new EventArgs(
[
'images' => $images,
'files' => $files,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::ADMIN_PRODUCT_ADD_IMAGE_COMPLETE);
$files = $event->getArgument('files');

return new Response(array_shift($files));
}

/**
* アップロード画像を取得する際にコールされるメソッド.
*
* @see https://pqina.nl/filepond/docs/api/server/#load
* @Route("/%eccube_admin_route%/content/maker/image/load", name="admin_maker_image_load", methods={"GET"})
*/
public function imageLoad(Request $request)
{
if (!$request->isXmlHttpRequest()) {
throw new BadRequestHttpException();
}

$dirs = [
$this->eccubeConfig['eccube_save_image_dir'],
$this->eccubeConfig['eccube_temp_image_dir'],
];

foreach ($dirs as $dir) {
if (strpos($request->query->get('source'), '..') !== false) {
throw new NotFoundHttpException();
}
$image = \realpath($dir.'/'.$request->query->get('source'));
$dir = \realpath($dir);

if (\is_file($image) && \str_starts_with($image, $dir)) {
$file = new \SplFileObject($image);

return $this->file($file, $file->getBasename());
}
}

throw new NotFoundHttpException();
}

/**
* アップロード画像をすぐ削除する際にコールされるメソッド.
*
* @see https://pqina.nl/filepond/docs/api/server/#revert
* @Route("/%eccube_admin_route%/content/maker/image/revert", name="admin_maker_image_revert", methods={"DELETE"})
*/
public function imageRevert(Request $request)
{
if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
throw new BadRequestHttpException();
}

$tempFile = $this->eccubeConfig['eccube_temp_image_dir'].'/'.$request->getContent();
if (is_file($tempFile) && stripos(realpath($tempFile), $this->eccubeConfig['eccube_temp_image_dir']) === 0) {
$fs = new Filesystem();
$fs->remove($tempFile);

return new Response(null, Response::HTTP_NO_CONTENT);
}

throw new NotFoundHttpException();
}

}

・app\template\admin\Content\maker_edit.twig
{#
This file is part of EC-CUBE

Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.

http://www.ec-cube.co.jp/

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% extends '@admin/default_frame.twig' %}

{% set menus = ['content', 'maker'] %}

{% block title %}{{ 'admin.content.maker_management'|trans }}{% endblock %}
{% block sub_title %}{{ 'admin.content.contents_management'|trans }}{% endblock %}

{% form_theme form '@admin/Form/bootstrap_4_horizontal_layout.html.twig' %}

{% block javascript %}
<script>
$(document).on('drop dragover', function(e) {
e.preventDefault();
});

$(function() {
// ファイルアップロード
// see https://pqina.nl/filepond/
var inputFileElement = document.querySelector('input[type=file]');
{% if eccube_config.locale == 'ja' or eccube_config.locale == 'en' %}
FilePond.setOptions(FilePondLocale_{{ eccube_config.locale }});
{% endif %}
FilePond.setOptions({
server: {
process: {
url: '{{ path('admin_maker_image_process') }}',
headers: {
'ECCUBE-CSRF-TOKEN': $('meta[name="eccube-csrf-token"]').attr('content'),
'X-Requested-With': 'XMLHttpRequest'
}
},
load: {
url: '{{ path('admin_maker_image_load') }}?source=',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
},
revert: {
url: '{{ path('admin_maker_image_revert') }}',
headers: {
'ECCUBE-CSRF-TOKEN': $('meta[name="eccube-csrf-token"]').attr('content'),
'X-Requested-With': 'XMLHttpRequest'
}
}
}
});
var pond = FilePond.create(inputFileElement, {
allowFileTypeValidation: true,
acceptedFileTypes: [
'image/gif',
'image/png',
'image/jpeg'
],
allowFileSizeValidation: true,
maxFileSize: 10000000,
maxFiles: 10,
allowBrowse: true,
allowDrop: true,
allowReorder: true,
labelIdle: '<i class="fa fa-cloud-upload fa-3x text-ec-lightGray mx-3 align-middle" aria-hidden="true" style="font-size: 40px"></i>{{ 'admin.common.drag_and_drop_image_description'|trans }}<span class="filepond--label-action">{{ 'admin.common.file_select'|trans }}</span>',
styleItemPanelAspectRatio: 0.5625,
// 保存されている画像のロード
files: [
{% for image in form.images %}
{
source: '{{ image.vars.value }}',
options: {
type: 'local'
}
},
{% endfor %}
// 追加してすぐの画像のロード. バリデーションエラーの場合など.
{% for add_image in form.add_images %}
{
source: '{{ add_image.vars.value }}',
options: {
type: 'local'
}
},
{% endfor %}
]
});
// 画像が追加されたら add_images にファイル名を追加する
var proto_add = '{{ form_widget(form.add_images.vars.prototype) }}';
pond.on('processfile', function(error, file) {
if (error) {
console.log(error);
} else {
$('#upload-zone').append(
$(proto_add.replace(/__name__/g, file.id))
.val(file.serverId)
.addClass('add_images')
);
}
});
// 画像が削除されたら delete_images にファイル名を追加する
var proto_del = '{{ form_widget(form.delete_images.vars.prototype) }}';
pond.on('removefile', function(error, file) {
if (error) {
console.log(error);
} else {
// file.serverId にはアップロードしたファイル名が格納される.
if (file.serverId) {
$('#upload-zone').append(
$(proto_del.replace(/__name__/g, file.id))
.val(file.serverId)
.addClass('del_images')
);
}
// 追加してすぐ削除した画像があれば削除する
$('#upload-zone').find('#admin_maker_add_images_' + file.id).remove(); // 追加してすぐ削除した画像
$('#upload-zone').find('.add_images[value="' + file.filename + '"]').remove(); // 追加後, バリデーションエラーが発生した後に削除した画像
}
});
pond.on('initfile', function() {
$('#maker_image_error').hide();
});
pond.on('error', function(error, file) {
var message = '{{ 'admin.common.upload_error'|trans }}';
if (error.main !== undefined) {
message = `${error.main}: ${error.sub}`;
}
$('#maker_image_error')
.show()
.find('.form-error-message').text(message);

// エラーメッセージが表示されてからプレビューエリアのエラーメッセージを非表示にする
setTimeout(function() {
$('.filepond--file-status').hide();
}, 300);
});

// バリデーションエラーが出た場合に画像を保持するための hidden を追加しておく
var proto_image = '{{ form_widget(form.images.vars.prototype) }}';
{% for image in form.images %}
$('#upload-zone').append(
$(proto_image.replace(/__name__/g, '{{ loop.index0 }}'))
.val('{{ image.vars.value }}')
.addClass('images')
);
{% endfor %}
{% for add_image in form.add_images %}
$('#upload-zone').append(
$('{{ form_widget(add_image) }}')
.val('{{ add_image.vars.value }}')
.addClass('add_images')
);
{% endfor %}
{% for delete_image in form.delete_images %}
$('#upload-zone').append(
$('{{ form_widget(delete_image) }}').addClass('del_images')
);
{% endfor %}

var confirmFormChange = function(form, target, modal) {
var returnLink = form.find('input[type="hidden"][name*="return_link"]'),
saveBtn = modal.find('a[data-action="save"]'),
cancelBtn = modal.find('a[data-action="cancel"]');
modal.on('hidden.bs.modal', function() {
returnLink.val('');
});
saveBtn.on('click', function() {
returnLink.val($(this).data('return-link'));
$(this).addClass('disabled');
form.submit();
});
target.on('click', function() {
modal.find('.modal-body .screen-name').text($(this).attr('title'));
modal.modal('show');
saveBtn.data('return-link', $(this).attr('href'));
cancelBtn.attr('href', $(this).attr('href'));
return false;
});
};
confirmFormChange($('#form1'), $('a[data-action="confirm"]'), $('#confirmFormChangeModal'))
});

</script>
{% endblock javascript %}

{% block main %}
<form role="form" class="form-horizontal" name="form1" id="form1" method="post" action="?">
{{ form_widget(form._token) }}
<div class="c-contentsArea__cols">
<div class="c-contentsArea__primaryCol">
<div class="c-primaryCol">
<div class="card rounded border-0 mb-4">
<div class="card-header">
<div class="row">
<div class="col-8">
<span class="card-title">{{ 'admin.content.maker.maker_registration'|trans }}</span></div>
<div class="col-4 text-end">
<a data-bs-toggle="collapse" href="#makerForm"
aria-expanded="true" aria-controls="makerForm"><i class="fa fa-lg fa-angle-up"></i></a></div>
</div>
</div>
<div class="ec-cardCollapse collapse show" id="makerForm" style="">
<div class="card-body">
<div class="row">
<div class="col-3">
<span>{{ 'admin.content.maker.maker_name'|trans }}</span>
<span class="badge bg-primary ms-1">
{{ 'admin.common.required'|trans }}
</span>
</div>
<div class="col mb-2">
{{ form_widget(form.name) }}
{{ form_errors(form.name) }}
</div>
</div>
<div class="row">
<div class="col-3">
<span>{{ 'admin.content.maker.maker_production'|trans }}</span>
</div>
<div class="col mb-2">
{{ form_widget(form.production) }}
{{ form_errors(form.production) }}
</div>
</div>
<div class="row">
<div class="col-3">
<div class="d-inline-block" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ 'tooltip.maker.image'|trans }}">
<span>{{ 'admin.maker.image'|trans }}</span>
<i class="fa fa-question-circle fa-lg ms-1"></i>
<br>{{ 'admin.maker.image_size'|trans }}
</div>
</div>
<div class="col mb-2">
<p id="message"></p>
<div id="upload-zone" class="rounded">
{{ form_widget(form.maker_image, { attr : { style : 'display:none;' } }) }}
{{ form_errors(form.maker_image) }}
</div><!-- /#upload-zone -->
<span class="invalid-feedback" id="maker_image_error" style="display: none">
<span class="d-block">
<span class="form-error-icon badge bg-danger text-uppercase">{{ 'Error'|trans({}, 'validators') }}</span>
<span class="form-error-message"></span>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="c-conversionArea">
<div class="c-conversionArea__container">
<div class="row justify-content-between align-items-center">
<div class="col-6">
<div id="ex-conversion-action" class="row align-items-center justify-content-end">
<div class="col-auto">
<button class="btn btn-ec-conversion px-5" type="submit">{{ 'admin.common.registration'|trans }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

・app\Customize\Entity\Master\Maker.php
namespace Customize\Entity\Master;
use Customize\Entity\MakerImage;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

if (!class_exists(Maker::class, false)) {
/**
* Maker
*
* @ORM\Table(name="mtb_maker")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
* @ORM\HasLifecycleCallbacks()
* @ORM\Entity(repositoryClass="Customize\Repository\Master\MakerRepository")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE")
*/
class Maker extends \Eccube\Entity\Master\AbstractMasterEntity
{
/**
* @var string|null
*
* @ORM\Column(name="production", type="string", length=255, nullable=true)
*/
private $production;

/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Customize\Entity\MakerImage", mappedBy="Maker", cascade={"remove"})
* @ORM\OrderBy({
* "sort_no"="ASC"
* })
*/
private $MakerImage;


/**
* Constructor
*/
public function __construct()
{
$this->MakerImage = new \Doctrine\Common\Collections\ArrayCollection();
}

public function __clone()
{
$this->id = null;
}

/**
* Set production
*
* @param string $production
*
* @return Maker
*/
public function setProduction($production)
{
$this->production = $production;

return $this;
}

/**
* Get production
*
* @return string
*/
public function getProduction()
{
return $this->production;
}

/**
* Add makerImage.
*
* @param \Customize\Entity\MakerImage $makerImage
*
* @return Maker
*/
public function addMakerImage(MakerImage $makerImage)
{
$this->MakerImage[] = $makerImage;

return $this;
}

/**
* Remove makerImage.
*
* @param \Customize\Entity\MakerImage $makerImage
*
* @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
*/
public function removeMakerImage(MakerImage $makerImage)
{
return $this->MakerImage->removeElement($makerImage);
}

/**
* Get makerImage.
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getMakerImage()
{
return $this->MakerImage;
}

}

}
k.nakayama
投稿日時: 2024/9/24 8:09
対応状況: −−−
常連
登録日: 2019/10/11
居住地:
投稿: 69
Re: 画像のアップロードに失敗してしまう
ec-cubeのログやhttpdのログにエラー内容が出力されていないでしょうか?

※ログをスレッドに記載する場合は公開しない方が良い情報が含まれていないかご確認ください。


----------------
----------------
ゴールドランク インテグレートパートナー U-Mebius

r_yamada
投稿日時: 2024/9/24 13:41
対応状況: 解決済
常連
登録日: 2024/9/2
居住地:
投稿: 39
Re: 画像のアップロードに失敗してしまう
k.nakayama 様
ご返信ありがとうございます。
こちらec-cubeのログを確認したところ、useが足りていないことが原因と判明し、解決できました。
ありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は98,688名です
総投稿数は112,043件です

投稿数ランキング

1
seasoft
7369
2
468
3217
3
AMUAMU
2712
4
nanasess
2325
5
umebius
2085
6
h_tanaka
1912
7
yuh
1899
8
mcontact
1596
9
red
1575
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
805
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
balisys
502


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.