Софтуерно Инженерство
Loading...
ivanp avatar ivanp 0 Точки

Събмитване на AJAX заявка за смяна на снимка не ми пълни базата от данни

Имам форма, която е писана по документацията на Symfony и работи добре, но рефрешва страницата при събмит затова реших да направя AJAX заявка да сменям снимката без да обновявам цялата страница. Проблемът е че съм написал заявката, прехвърлям данните, но незнайно защо името на новата снимка не се появява в базата или в папката където ги съхранявам. Това ми е кодът в момента(контролерът):

/**
 * @Route("/upload", name="uploadpic")
 * @param Request $request
 * @return JsonResponse|\Symfony\Component\HttpFoundation\Response
 */
public function uploadAction(Request $request){
    if(!$request->isXmlHttpRequest()){
        return new JsonResponse(
            array(
                'message' => 'Error',
                'status' => 'Not received'
            ), 400);
    }
    
    $user = $this->get('security.token_storage')->getToken()->getUser();
    $formed = $this->createForm(UserPic::class, $user);
    $formed->handleRequest($request);
    if(isset($request->request)) {
    
        $postPicture = $request->files->get('picture_data');
        $file = $user->getUserPic();
        $fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();

        $file->move(
            $this->getParameter('users_directory'),
            $fileName
        );

        $user->setUserPic($fileName);


        $em = $this->getDoctrine()->getManager();
        $em->persist($user);
        $em->flush();
        return $this->render('default/index.html.twig',
            ['formed' => $formed->createView()]);
    

    }
    
}

Пробвах и с $postPicture = $request->request->get('picture_data'); вместо $postPicture = $request->request->get('picture_data'); , защото принципно така работи като пращам текст от textarea с AJAX към базата.

Пробвах и  $fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension(); вместо  $fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();, защото така е писано в документацията, но и така не работи.

Кодът ми на AJAX request-а:

$("#submit_pic").on('click', function(event){
    event.preventDefault();
    event.stopPropagation();
    $.ajax({
        type: "POST",
        url: "/profile",
        data: {
            picture_data: new FormData($("#pic_data")[0])
        },
        processData: false,
        contentType: false,
        success: function () {
            console.log();
        },
        error: function () {
            console.log("Error here");
        }
    });
});

Пробвах с променяне на picture_data: $("#pic_data").serialize() с picture_data: new FormData($("#pic_data")[0]), защото четох един пост в stackoverflow че не работело така. Не разбирам защо не сетва нов image като AJAX-а дори не изплюва грешка.

Тагове:
0
PHP MVC Frameworks
dimaldim92 avatar dimaldim92 149 Точки

Route-а в контролера ти е /upload , а ajax заявката ти поства на /profile ...?

 

Пробвай да не изпращаш формата като object към PHP скритпа:

data: new FormData($("#pic_data")[0])

В контролера може да дъмпнеш да видиш дали се е изпратило:

$request->files->get('името на инпута') или var_dump($request->files->all()); да се ориентираш.

Или дай скайп направо да го оправиме :)

0
28/12/2018 15:34:15
ivanp avatar ivanp 0 Точки

Промених пътя да е "/upload", признавам че е недоглеждане от моя страна, но сега ми гъми с 500 internal server error. Дали не предавам данните правилно? Пробвах и със .serilize и с new FormData и все същата грешка...

0
dimaldim92 avatar dimaldim92 149 Точки

Редактирах си поста.

0
ivanp avatar ivanp 0 Точки

Това ми е темплейта ако искате да погледнете, но там всичко е наред май. Грешката идва от AJAX-а, мисля че не стига изобщо до контролера: 

{% if app.user.userPic is null %}
    <div class="" id="imageUpload">

        <p>
            <label for="pic_data">
                <img src="{{ asset('/pictures/anonimous.jpg') }}" class="rounded-circle" id="userPic"/>
            </label>
            <br/>
        </p>
        <form method="POST" enctype="multipart/form-data" action="{{ path('uploadpic') }}">
            <p>
                <input type="file" id="pic_data" name="app_bundle_user_pic[userPic]" required>
            </p>
            <button type="submit" id="submit_pic" name="app_bundle_user_pic[Change]" class="btn btn-success btn-sm">
                Change
            </button>
        </form>

    </div>
{% else %}
    <div class="" id="imageUpload">
        <p>
            <label for="pic_data">
                <img src="{{ asset('/uploads/images/'~app.user.userPic) }}" class="rounded-circle" id="userPic"/>
            </label>
            <br/>
        </p>
        <form method="POST" enctype="multipart/form-data" action="{{ path('uploadpic') }}">
        <p>
        <input type="file" id="pic_data" name="app_bundle_user_pic[userPic]" required>
        </p>
        <button type="submit" id="submit_pic" name="app_bundle_user_pic[Change]" class="btn btn-success btn-sm">
            Change
        </button>
        </form>
    </div>
{% endif %}
0
dimaldim92 avatar dimaldim92 149 Точки

Може да видиш защо ти дава 500, ако си с хром F12, network taba, отваряш /upload и отиваш на response. 

0
ivanp avatar ivanp 0 Точки

var_dump-а на 

$request->files->all()

не ми връща нищо като информация, имам сложен exit след него обаче и като спра скрипта тук: 

var_dump($request->files->all());
exit();
$file = $user->getUserPic();
$fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();

$file->move(
    $this->getParameter('users_directory'),
    $fileName
);

ми връща 'success' (този success си го слoжих като console.log , при success на ajax-а). Иначе пак си гърми с 500 ако го оставя така, пробвах и с 

dump($request->files->all());

пак нищо не излиза... 

П.С. data я промених на : 

data: new FormData($("#pic_data")[0]) както ме посъветва и достъпвам в контролера по име: 
$postPicture = $request->files->get('app_bundle_user_pic[userPic]');
0
28/12/2018 16:00:39
dimaldim92 avatar dimaldim92 149 Точки

Пак казвам, че с хрома може да видиш респонса и защо точно ти дава еррор 500.

0
ivanp avatar ivanp 0 Точки

При

 

$fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension();

 

ми дава 


Call to a member function guessExtension() on string (500 Internal Server Error)

а при 

 

$fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();

 

връща

 

Call to a member function guessExtension() on null (500 Internal Server Error)

Мисля че не намира снимката

0
28/12/2018 16:31:22
dimaldim92 avatar dimaldim92 149 Точки

guessExtension() трябва да е на файла, който ъплоадваш. Т.е. $postPicture->guessExtension();

 

generateUniqueFileName() ... нещо не мога да открия по документацията почти нищо. Възможно е да е deprecated. Ползвай uniqid();

0
ivanp avatar ivanp 0 Точки
$file = $request->files->get('app_bundle_user_pic[userPic]');
$fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension(); 

дава същата грешка:

 Call to a member function guessExtension() on null (500 Internal Server Error)

generateUniqueFileName() e изнесено на функция, която прави същото което ти казваш да прави:

private function generateUniqueFileName()
{
    return md5(uniqid());
}

П.С. Тук ли да оставя скайп, че не намирам опция за л.с.(съжалявам за нууб въпроса)

0
28/12/2018 16:40:25
dimaldim92 avatar dimaldim92 149 Точки

Намери ме: live:1c00b8bcb2e2bdc9

0
RoYaL avatar RoYaL SoftUni Team Trainer 6846 Точки

getUserPic() вероятно си е стринг, защото сигурно е колона в базата т.е. така е зададено в ентитито User. Да не би да трябва да ползваш само $postPicture? И може да погледнеш и дали content type-а ти е multipart/form data, защото иначе файлове не могат да се пращат.

P..S.: За да не стават такива грешки като "нямам такъв метод" е хубаво да ползвате РНР като всеки един друг по-типизиран език, а именно, да си следите типовете и да ги позвате само като такива. Да няма ситуации, в които една променлива може да бъде стринг, а в друга ситуация да е file, например. :)

1
dimaldim92 avatar dimaldim92 149 Точки

Ами не, то си ти казва, че не намира такава функция. По-скоро ползвай uniqid() 

0