zlatiborac's avatar

Redactor upload and token

In L4 I was using Imperavi Redactor and it was simple to setup, and easy to use. With L5 I have big troubles setting the upload part of Redactor, mainly because of token verification. Below is the JS init part of Redactor and with 'imageUpload' I was able to get rid of the Token mismatch error.

<script type="text/javascript">
        $(function () {
            $('#content').redactor({
                minHeight: 300,
                maxHeight: 800,
                buttons: ['html', 'bold', 'italic', 'image', 'link'],
                imageUpload: 'uploadNewsImages?_token=' + '{{csrf_token()}}'
            });
        });
    </script>

But uploadNewsImages does not behave like in normal form upload situation. When i try this from Controller

dd($request->all());

I get Status Code:200 OK but in Network-Response bar of Developer I get this gibberish

<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/; doc.documentElement.firstChild.appendChild(refStyle); function toggle(a) { var s = a.nextSibling || {}; if ('sf-dump-compact' == s.className) { a.lastChild.innerHTML = '&#9660;'; s.className = 'sf-dump-expanded'; } else if ('sf-dump-expanded' == s.className) { a.lastChild.innerHTML = '&#9654;'; s.className = 'sf-dump-compact'; } else { return false; } return true; }; return function (root) { root = doc.getElementById(root); function a(e, f) { root.addEventListener(e, function (e) { if ('A' == e.target.tagName) { f(e.target, e); } else if ('A' == e.target.parentNode.tagName) { f(e.target.parentNode, e); } }); }; root.addEventListener('mouseover', function (e) { if ('' != refStyle.innerHTML) { refStyle.innerHTML = ''; } }); a('mouseover', function (a) { if (a = idRx.exec(a.className)) { refStyle.innerHTML = 'pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}'; } }); a('click', function (a, e) { if (/\bsf-dump-toggle\b/.test(a.className)) { e.preventDefault(); if (!toggle(a)) { var r = doc.getElementById(a.getAttribute('href').substr(1)), s = r.previousSibling, f = r.parentNode, t = a.parentNode; t.replaceChild(r, a); f.replaceChild(a, s); t.insertBefore(s, r); f = f.firstChild.nodeValue.match(indentRx); t = t.firstChild.nodeValue.match(indentRx); if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } if ('sf-dump-compact' == r.className) { toggle(s); } } } }); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), elt = root.getElementsByTagName('A'), len = elt.length, i = 0, t = []; while (i < len) t.push(elt[i++]); elt = root.getElementsByTagName('SAMP'); len = elt.length; i = 0; while (i < len) t.push(elt[i++]); root = t; len = t.length; i = t = 0; while (i < len) { elt = root[i]; if ("SAMP" == elt.tagName) { elt.className = "sf-dump-expanded"; a = elt.previousSibling || {}; if ('A' != a.tagName) { a = doc.createElement('A'); a.className = 'sf-dump-ref'; elt.parentNode.insertBefore(a, elt); } else { a.innerHTML += ' '; } a.innerHTML += '<span>&#9660;</span>'; a.className += ' sf-dump-toggle'; if ('sf-dump' != elt.parentNode.className) { toggle(a); } } else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { t = a.nextSibling; elt.appendChild(a); t.parentNode.insertBefore(a, t); if (/^[@#]/.test(elt.innerHTML)) { elt.innerHTML += ' <span>&#9654;</span>'; } else { elt.innerHTML = '<span>&#9654;</span>'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '&#8230;'; elt.className = 'sf-dump-ref'; } } } } ++i; } }; })(document); </script> <style> pre.sf-dump { display: block; white-space: pre; padding: 5px; } pre.sf-dump span { display: inline; } pre.sf-dump .sf-dump-compact { display: none; } pre.sf-dump abbr { text-decoration: none; border: none; cursor: help; } pre.sf-dump a { text-decoration: none; cursor: pointer; border: 0; outline: none; }pre.sf-dump{background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000}pre.sf-dump .sf-dump-num{color:#a71d5d}pre.sf-dump .sf-dump-const{color:#795da3}pre.sf-dump .sf-dump-str{color:#df5000}pre.sf-dump .sf-dump-cchr{color:#222}pre.sf-dump .sf-dump-note{color:#a71d5d}pre.sf-dump .sf-dump-ref{color:#a0a0a0}pre.sf-dump .sf-dump-public{color:#795da3}pre.sf-dump .sf-dump-protected{color:#795da3}pre.sf-dump .sf-dump-private{color:#795da3}pre.sf-dump .sf-dump-meta{color:#b729d9}pre.sf-dump .sf-dump-key{color:#df5000}pre.sf-dump .sf-dump-index{color:#a71d5d}</style><pre class=sf-dump id=sf-dump-527640286 data-indent-pad="  "><span class=sf-dump-note>array:2</span> [<samp>
  "<span class=sf-dump-key>_token</span>" => "<span class=sf-dump-str title="40 characters">Iw26B0HLCcd8GGqDWb10AxWoT7N4PXWH0mrDFGNC</span>"
  "<span class=sf-dump-key>file</span>" => <abbr title="Symfony\Component\HttpFoundation\File\UploadedFile" class=sf-dump-note>UploadedFile</abbr> {<a class=sf-dump-ref>#27</a><samp>
    -<span class=sf-dump-private title="Private property defined in class:&#10;`Symfony\Component\HttpFoundation\File\UploadedFile`">test</span>: <span class=sf-dump-const>false</span>
    -<span class=sf-dump-private title="Private property defined in class:&#10;`Symfony\Component\HttpFoundation\File\UploadedFile`">originalName</span>: "<span class=sf-dump-str title="6 characters">d2.jpg</span>"
    -<span class=sf-dump-private title="Private property defined in class:&#10;`Symfony\Component\HttpFoundation\File\UploadedFile`">mimeType</span>: "<span class=sf-dump-str title="10 characters">image/jpeg</span>"
    -<span class=sf-dump-private title="Private property defined in class:&#10;`Symfony\Component\HttpFoundation\File\UploadedFile`">size</span>: <span class=sf-dump-num>76014</span>
    -<span class=sf-dump-private title="Private property defined in class:&#10;`Symfony\Component\HttpFoundation\File\UploadedFile`">error</span>: <span class=sf-dump-num>0</span>
  </samp>}
</samp>]
</pre><script>Sfdump("sf-dump-527640286")</script>

So any idea where or what am I doing wrong, since this all was well in L4

0 likes
3 replies
zlatiborac's avatar

Just to add, if I try return instead of dd() I receive this response

_token: "Iw26B0HLCcd8GGqDWb10AxWoT7N4PXWH0mrDFGNC"
file: {}

Token is correct, but file{} is empty.

squigg's avatar

I don't have any experience with redactor, but noticed the following:

The call to dd is correctly showing the HTML "pretty printing" of the fields within the Request object. That's the "nonsense" you refer to. Look down the bottom and note the reference to an UploadedFile class with various private fields set such as originalName and mimeType.

Through your return call you are just returning (I believe) json-able data - as the UploadedFile class cannot be cast to json it is just coming back as empty perhaps?

Try a proper debugger to see what's actually going on with your code, as it appears UploadedFile is being correctly set so it must be something else going wrong.

1 like
zlatiborac's avatar
zlatiborac
OP
Best Answer
Level 2

Thx squigg, and you were almost right. While browsing a bit harder through Headers I noticed this in Request Payload

------WebKitFormBoundarypKMwTQauFBZ5UgSV
Content-Disposition: form-data; name="file"; filename="d2.jpg"
Content-Type: image/jpeg

Filename is the correct one I tried to upload but name="file" was the crucial one (and the only one I didn't tried: image, uploaded_file, uplaodedFile....). One I changed code to

$imageFile = $request->file('file');
return $imageFile->getClientOriginalName();

Everything was just fine. I wish I payed more attention to Headers :(

Please or to participate in this conversation.