Jump to content
Rachid Finge

Uploading through WireUpload works, but adding to FieldTypeFile generates HTTP 500

Recommended Posts

I'm building a smartphone app that allows users to record a voice clip and send it to our server, which runs ProcessWire. Files are sent over HTTPS Post, currently without any sort of authentication.

I've succeeded using the WireUpload class to fetch the uploaded file from the $_FILES super global. Where I get in trouble is when I try to add the audio file to the audio page, where there's an Input field called 'audiofile'. Whenever I try to use any file related method, an Internal Server Error occurs.

Here's my code, which runs in the page's template.

<?php

Header("Content-Type: text/plain");

$upload_path = $config->paths->assets . "files/audio/";

$u = new WireUpload('files');

$u->setMaxFiles(1);
$u->setOverwrite(false);
$u->setValidExtensions(array('mp3', 'mp4', 'm4a'));
$u->setDestinationPath($upload_path);

// I can confirm through my FTP client that the file sent through POST actually shows up in the $upload_path location.
$fileresult = $u->execute();

// This is the File input field in my template. Doing print_r($audiofield) confirms this is an existing object.
$audiofield = $fields->get("audiofile");

// Trying this for the heck of it, but all that results is HTTP 500.
$audiofield->deleteAll();

foreach($fileresult as $filename) {
	// I've seen various examples on what to do now. Here's one that causes a 500 error.
	$page->'audiofile' = $upload_path . $filename;
	
	// This seems the most logical thing to do, but also causes HTTP 500.
	$audiofield->add($upload_path . $filename);
	
	// Unlinking succeeds (given that I comment out the lines that cause the HTTP 500 errors)
	unlink($upload_path . $filename);
}
   
// We never get to this phase.         
$page->save();

?>

Things of note:

  • Server runs PHP 5.4.4-14+deb7u8 on Debian with Apache/2.2.22. 
  • File uploading through the admin on the audio page works without issues, also when uploading multiple files at once or sequentially.
  • I've confirmed the owner of $upload_path to be www-data and its permissions to be 755.

What's the final step I'm missing to add the audio file to the input field on my page?

Edited by Rachid Finge

Share this post


Link to post
Share on other sites

Just a quick glance, but I think what you are looking for is:

$page->audiofile->add($upload_path . $filename);

Share this post


Link to post
Share on other sites

Thanks adrian!

This seems to have some effect, as the response time of the PHP page increases somewhat.

However, the HTTP 500 error still persists and no change is made to the page.

How can I start debugging the 500 error? Can't find a log that offers more details.

Share this post


Link to post
Share on other sites

The log will be in /site/assets/logs/errors.txt, or in the setup tab in the admin on newer dev-branch installations.

Share this post


Link to post
Share on other sites

500 comes from Apache, so take a look at Apache error logs.

Share this post


Link to post
Share on other sites

Thanks so much guys, the issue has been resolved! :)

The error log showed the following relevant entry:

Error: 	Exception: Can't save page 1083: /en/audio/: Call $page->setOutputFormatting(false) before getting/setting values that will be modified and saved.  [audiofile] (in /(...)/events/wire/core/Pages.php line 817)

Ok, so I added $page->setOutputFormatting(false) before calling save and that fixes everything. I don't know why, I must add, but I'm sure I'll figure out in time what that method does.

Learning from all of this, there are still two questions I'd like to ask:

  1. The right way to save a file to a FileInputField was using the 'add' method with the temporary file as the only argument. I never came across this in the documentation. Is this undocumented or do I need better glasses? :)
  2. Should the omission of calling setOutputFormatting really trigger a rather harsh error on the web server?

Share this post


Link to post
Share on other sites

I think there's no real specialized documentation about saving files from the api, but it's the same api as for pages and images. They all inherit their functions from WireArray / WireData which are kinda key components of most processwire fieldtypes. 

OutputFormating is exactly what it tells you to be. It changes the way output is presented to you. If it's off you'll get raw database data. E.g. for a page field this would be the id. If it's on you'll get not only the id but the whole page object of this page. Regarding this "harsh" error. Yeah it has to be this way, as you cannot save anything with outputformatting on. Not being able to save is pretty important stuff for a cms, which requires a hefty error.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By EyeDentify
      Hello dear PW gurus.

      I have stumbled over a strange error that i all of sudden got when trying to upload an image to a images field on a page.
      There where images allready stored in the field that i wanted to keep, but during the upload the error apear and after that all images are gone from the field and i can´t upload any, i just get the error every time.
      I am running ProcessWire 3.0.153 dev.
      Update:
      After looking in the assets folder i find the folder for the page and the image files seems to be there including the ones i tried to upload when the error occured.
      But they don´t show up in the images field in the page editor.
       
      The error reported:
       
      SQLSTATE[01000]: Warning: 1265 Data truncated for column 'ratio' at row 1 And here is a screenshot of the event:

      The TracyDebugger Error reporting:

      I hope you fine folks could point me in a direction.
      But it seems our old pal set_time_limit() is back.

      Regards, EyeDentify
    • By dimitrios
      Hello,
      this module can publish content of a Processwire page on a Facebook page, triggered by saving the Processwire page.
      To set it up, configure the module with a Facebook app ID, secret and a Page ID. Following is additional configuration on Facebook for developers:
      Minimum Required Facebook App configuration:
      on Settings -> Basics, provide the App Domains, provide the Site URL, on Settings -> Advanced, set the API version (has been tested up to v3.3), add Product: Facebook Login, on Facebook Login -> Settings, set Client OAuth Login: Yes, set Web OAuth Login: Yes, set Enforce HTTPS: Yes, add "https://www.example.com/processwire/page/" to field Valid OAuth Redirect URIs. This module is configurable as follows:
      Templates: posts can take place only for pages with the defined templates. On/Off switch: specify a checkbox field that will not allow the post if checked. Specify a message and/or an image for the post.
      Usage
      edit the desired PW page and save; it will post right after the initial Facebook log in and permission granting. After that, an access token is kept.
       
      Download
      PW module directory: http://modules.processwire.com/modules/auto-fb-post/ Github: https://github.com/kastrind/AutoFbPost   Note: Facebook SDK for PHP is utilized.


    • By iipa
      Hello forum!
      I have a site, where I want to remember two settings defined by user:
      1) Theme (light or dark)
      2) Language (Finnish or English)
      Because user makes changes to these settings on client side, I am a bit lost with how can I save them in ProcessWire $session variable? I would like to use $session for more reliable saving, and since it is only two variables I will use, I doubt it will become too resource-needy.
      I have tried using jQuery's post() -method referring to a file in Templates folder (theme.php), but I get 403 Forbidden Error. I don't like the idea of trying to post to same file user currently is in, which is why I thought having a separate file would be good in this.
      Contents of theme.php:
      <?php namespace ProcessWire; header('Access-Control-Allow-Origin: https://domain.com'); $theme = $input->post['theme']; if(!empty($theme)) $session->theme = $theme; ?> Long story short: Does anybody have any pro tips I could use with setting and getting $session variables?
    • By louisstephens
      So I am using ajax to upload an image, but I am getting the error "Method WireUpload:: save does not exist or is not callable". I am not quite sure how to go about fixing this (at the moment).
      elseif($config->ajax && $input->urlSegment1 == "upload-preview") { $u = $config->paths->assets . "files/pdfs/"; $title = $sanitizer->text($_POST['title']); $p = new Page(); $p->template = "preview"; $p->parent = $pages->get("/previews/"); $p->name = $title; $p->title = $title; $p->save(); $p->setOutputFormatting(false); $u = new WireUpload('preview_image'); $u->setMaxFiles(1); $u->setOverwrite(false); $u->setDestinationPath($p->preview_image->path()); $u->setValidExtensions(array('jpg', 'jpeg', 'gif', 'png', 'pdf')); foreach($u->execute() as $filename) { $p->preview_image->add($filename); } $u->save(); } I compared my code to something I did previously (though previously I just posted to the current template file, not through ajax) which works, but this doesnt seem to be working. I have the _init.php file prepending as well. Does anyone have any ideas of what might be happening?
    • By pwFoo
      With JS fetch() it is a bit tricky to get for example $_POST populated (params need to be FormData / forms), but would it possible to get PW $input (get, post, urlSegments, queryString) working for fetch requests?
      Is there a fix / hook / workaround to solve it PW side?
×
×
  • Create New...