Jump to content

Uploading a new photo to a member profile avatar field?


FuturShoc
 Share

Recommended Posts

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?

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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]);
    }
Link to comment
Share on other sites

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!
}
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 weeks later...

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

Hi Ryan,

Thanks for posting...

I am trying to put together a full working example of a front-end form with "regular" fields and file uploads.  So as not to hijack this discussion, I started a new one with full working examples.

Here's the other discussion: http://processwire.com/talk/topic/3105-adding-file-upload-field-to-form-via-api/

Thanks,

Matthew

Link to comment
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
 Share

×
×
  • Create New...