Jump to content

Recommended Posts

Posted

We've home-rolled a front-end profile management page and we've expanded profiles with lots of custom fields. It's working great!

Now, I need to allow site members to upload their own profile photo to the default 'avatar' field.

Of course, I know how to add a file upload field to the form and work with the file in my target script.

But I'm a bit unclear as to how to bridge the gap to populating the avatar field value.

Can someone provide a code snippet?

Posted

There's a nice class WireUpload that makes uploading files very easy.

Here a slightly modified example of a site:

$upload_path = 'YOUR_TEMP_UPLOAD_PATH';
$u = new WireUpload('avatar'); //avatar is the name of the input-file field
$u->setMaxFiles(1);
$u->setMaxFileSize(5*1024*1024);
$u->setOverwrite(false);
$u->setDestinationPath($upload_path);
$u->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
$files = $u->execute(); //Actually not sure if this returns an array if you only allow to upload one file, maybe its the filename (string)

if ($u->getErrors()) {	 
  foreach($files as $filename) @unlink($upload_path . $filename);
  foreach($u->getErrors() as $e) echo $e;
} else {
  //Save the foto to the avatar field
  $page->of(false);
  $page->avatar = $upload_path . $files[0];
  $page->save();
  $page->of(true);
  @unlink($upload_path . $files[0]);
}

As you can see, it's very straightforward to add the image to the avatar field (Pw rocks!)

  • Like 2
Posted

Thanks for your reply, Wanze.

When I implement this approach, I'm getting this error:

Error    Uncaught exception 'WireException' with message 'Method WireUpload::of does not exist or is not callable in this context'

... Does it matter that I'm bootstrapping PW in my script?

Posted

Here's my actual code:

    $username = $_POST['username'];    
    $u = wire("users")->get($username);
    $upload_path = '/tmp/';
    $f = new WireUpload('avatar'); //avatar is the name of the input-file field
    $f->setMaxFiles(1);
    $f->setMaxFileSize(5*1024*1024);
    $f->setOverwrite(false);
    $f->setDestinationPath($upload_path);
    $f->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
    $files = $f->execute(); //Actually not sure if this returns an array if you only allow to upload one file, maybe its the filename (string)
    
    if ($f->getErrors()) {    
      foreach($files as $filename) @unlink($upload_path . $filename);
      foreach($f->getErrors() as $e) echo $e;
    } else {
      //Save the foto to the avatar field
      $f->of(false);
      $u->avatar = $upload_path . $files[0];
      $u->save();
      $f->of(true);
      @unlink($upload_path . $files[0]);
    }
Posted

Then you still mix up the variables of the user and the WireUpload class.

The error message clearly says that no method "of" exists in WireUpload. This error appears because you

are trying to execute WireUpload::of()

$f->of(false); //Wrong! $u->of(false)
$u->avatar = $upload_path . $files[0];
$u->save();
$f->of(true); //Wrong! $u->of(true);

Also make sure that your user was found:

if (!$u->id) {
  //.. no User found!
}
Posted

Here is the current state of my code:

    $upload_path = '/tmp/';
    $f = new WireUpload('avatar'); //avatar is the name of the input-file field
    $f->setMaxFiles(1);
    $f->setMaxFileSize(5*1024*1024);
    $f->setOverwrite(false);
    $f->setDestinationPath($upload_path);
    $f->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
    $files = $f->execute();
    
    if ($f->getErrors()) {    
      foreach($files as $filename) @unlink($upload_path . $filename);
      foreach($f->getErrors() as $e) echo $e;
    } else {
      //Save the foto to the avatar field
      $u->of(false);
      $u->avatar = $upload_path . $files[0];
      $u->save();
      $u->of(true);
      @unlink($upload_path . $files[0]);
    }
 
and this is the error I'm receiving:
 
Error    Uncaught exception 'WireException' with message 'Method WireUpload::setMaxFileSize does not exist or is not callable in this context' i
Posted

But that's another error now :)

Are you on Pw 2.2.9?

Grab the latest dev version or just the Upload.php class from there, I think the "setMaxFileSize" method was added later.

  • Like 1
Posted

I just updated the PW installation to the latest dev branch.

Here is my code:

    $upload_path = '/tmp/';
    $f = new WireUpload('avatar'); //avatar is the name of the input-file field
    $f->setMaxFiles(1);
    $f->setMaxFileSize(5*1024*1024);
    $f->setOverwrite(false);
    $f->setDestinationPath($upload_path);
    $f->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
    $files = $f->execute(); 
    
    if ($f->getErrors()) {    
      foreach($files as $filename) @unlink($upload_path . $filename);
      foreach($f->getErrors() as $e) echo $e;
    } else {
      //Save the foto to the avatar field
      $u->of(false);
      $u->avatar = $upload_path . $files[0];
      $u->save();
      $u->of(true);
      @unlink($upload_path . $files[0]);
    }

And this is the error:

Error: Uncaught exception 'WireException' with message 'Can't save page 41: /processwire/access/users/futurshoc/: Call $page->setOutputFormatting(false) before getting/setting values that will be modified and saved. [ministerpic]' in /home/inthoozm/public_html/dev/pvcc/wire/core/Pages.php:514

Posted

Ok, it looks like I had a SECOND $u->save(); later in my code and that's what was throwing this last error.

Once I moved that to *before* the image upload code, it does appear things are working now.

Thanks for your feedback and help, Wanze.

  • 2 weeks later...
Posted

Greetings,

Following this discussion... I have successfully built PW pages from front-end form submissions, but seem to be having trouble with having a file upload field as part of the overall form.

FuturShoc: if possible, can you post the code you used for the entire Member Profile template?  I think it would help to see the file-upload portion of the form in the context of the whole form.

Thank you very much!

Matthew

Posted

Matthew, the main "gotcha" with adding files to newly created pages is that the page needs to exist in the DB before files can be added to it. So if you are creating a new page, you'll just want to have a $page->save(); somewhere before you add the file to it, and another $page->save(); sometime after you add the file to it. 

  • Like 1

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
×
×
  • Create New...