UpdateProfile upload picture

I want users to upload their own avatar icon. How do I do that? I can update [[+photo]] but it does nto save the file when using <input type=“file” I guess I need a custom hook that allows for that?

Or is there a hook already that I can use? e.g. using fileupload snippet?

can anyone give me a tip?

Hi @servingpixels ,
you need custom preHook snippet (loadUserPhoto in example below), roughly idea is the follows - you need something like the next(there is deletion functionality, please remove unnecessary lines):

<? php
// Get user profile
$ profile = $ modx-> user-> getOne ('Profile');
// Get the value of the photo field
$ pathToPhoto = $ profile-> get ('photo');
// Set the photo field to the current value
$ hook-> setValue ('photo', $ pathToPhoto);

// Request to delete a picture (the global POST array has a delete-photo-btn key with a non-NULL value)
if (isset ($ _ POST ['delete-photo-btn'])) {
  // If the photo field is not empty, then ..
  if ($ pathToPhoto) {
    // Generate the full path to the file (photo)
    $ fullPathToPhoto = $ modx-> config ['base_path']. $ pathToPhoto;
    // If there is a file (photo), then delete it
    if (file_exists ($ fullPathToPhoto))
      unlink ($ fullPathToPhoto);
    // Set the photo field to empty
    $ hook-> setValue ('photo', '');
  }
}

// Update request (the global POST array has a login-updprof-btn key with a non-NULL value)
if (isset ($ _ POST ['login-updprof-btn'])) {
  // Allowed extensions (jpg, png, jpeg)
  $ validExt = array ('jpg', 'png', 'jpeg');
  // Directory for storing user photos
  $ pathToPhoto = $ modx-> config ['base_path']. 'assets / photouser /';
  // User file name
  $ nameFile = $ _FILES ['photo'] ['name'];
  // Get the extension of the file uploaded by the user in lowercase
  $ extFile = mb_strtolower (pathinfo ($ nameFile, PATHINFO_EXTENSION));
  // Temporary name with which the received file was saved on the server
  $ tmpFile = $ _FILES ['photo'] ['tmp_name'];
  // If the file was uploaded via HTTP POST and no errors occurred during the upload process, then ...
  if ((is_uploaded_file ($ tmpFile)) &&! ($ _ FILES ['photo'] ['error'])) {
    // Checks if the file extension matches a valid one. If all is well, then ...
    if (in_array ($ extFile, $ validExt)) {
      // Form a name for the file (photo)
      $ nameFilePhoto = 'user'. $ modx-> user-> get ('id'). '.' ... $ extFile;
      // Get the full file name (photo)
      $ fullNameFilePhoto = $ pathToPhoto. $ nameFilePhoto;
      // Move the temporary file to a new location $ fullNameFilePhoto. If everything went well, then ...
      if (move_uploaded_file ($ tmpFile, $ fullNameFilePhoto)) {
        // if the phpthumb.class.php file was not included, then enable it
        require_once MODX_CORE_PATH.'model / phpthumb / phpthumb.class.php ';
        // Create a new instance of the phpThumb class
        $ phpThumb = new phpThumb ();
        // Specify the original image
        $ phpThumb-> setSourceFilename ($ fullNameFilePhoto);
        // Set the width of the image
        $ phpThumb-> setParameter ('w', 100);
        // Set the height of the image
        $ phpThumb-> setParameter ('h', 100);
        // Set the trim type
        $ phpThumb-> setParameter ('zc', '1');
        // Set the image quality
        $ phpThumb-> setParameter ('q', '80');
        // Generate a thumbnail image. If the action was successful, then ...
        if ($ phpThumb-> GenerateThumbnail ()) {
          // Save the image to $ fullNameFilePhoto. If this action succeeds, then ..
          if ($ phpThumb-> RenderToFile ($ fullNameFilePhoto)) {
            // Set the path to the file in the photo field
            $ hook-> setValue ('photo', $ modx-> getOption ('assets_url'). 'photouser /'. $ nameFilePhoto);
          }
          else {
            $ modx-> log (modX :: LOG_LEVEL_ERROR, 'Error while saving image to file'. $ fullNameFilePhoto);
          }
        }
        else {
          // Write the received error to the MODX log
          $ modx-> log (modX :: LOG_LEVEL_ERROR, print_r ($ phpThumb-> debugmessages, 1));
        }
      }
      else {
        // Write to the log that an error occurred while moving the file to a new location
        $ modx-> log (modX :: LOG_LEVEL_ERROR, 'Error moving temporary file'. $ tmpFile. 'to new location'. $ fullNameFilePhoto);
      }
    }
    else {
      // Log a message stating that the file extension does not match the allowed one
      $ modx-> log (modX :: LOG_LEVEL_ERROR, 'The image has an invalid extension');
    }
  }
  else {
    // Write to the log that an error occurred while uploading the file
    $ modx-> log (modX :: LOG_LEVEL_ERROR, 'Error loading file. Error code:'. $ _ FILES ['photo'] ['error']);
  }
}
return true; 

and UpdateProfile snippet call will be:

[[!UpdateProfile? &validate=`fullname:required` &preHooks=`loadUserPhoto`]]

and html form like the next:

<form action="[[~[[*id]]]]" method="post" class="form-horizontal" enctype="multipart/form-data">
<div class="form-group">
  <label for="photo" class="col-sm-4 control-label" style="padding-top: 0px; padding-bottom: 6px;">Avatar</label>
<div id="crop" class="img-rounded center-block" style="height: 100px; width: 100px; overflow: hidden;">
  <img  id="img-photo" src="[[+photo:default=`/assets/photouser/default.jpg`]]">
</div>
<p class="lead text-center">[[+fullname]]</p>
<hr>
  <div class="col-sm-8" style="padding-top: 0px; padding-bottom: 6px;">
    <input type="file" id="photo" name="photo" value="[[+photo]]">
  </div>
</div>
</form>
1 Like

Thanks so much, I thought it would need a custom hook. going to give it a try and post results. Should add this to the documentation… i

Nps, you’re welcome!
As for documentation - I was going to update it shortly as well.

trying to use your code but somehow can not get it to work I am getting a weird issue.

When I use move_uploaded_file in conjunction or inside an if statement in the snippet the snippet wont save. if I use move_uploaded_file not inside an if statement it saves… very very strange

example

<?php
$profile = $modx->user->getOne('Profile');
$pathToFile = $profile->get('photo');
$hook->setValue('photo',$pathToFile);

if(isset($_POST['login-updprof-btn'])) {

    $validExt=array('jpg','png','jpeg');
    $pathToFile = $modx->config['base_path'].'assets/content/users/';
    $nameFile = $_FILES['photo']['name'];
    $extFile = mb_strtolower(pathinfo($nameFile, PATHINFO_EXTENSION));
    $tmpFile = $_FILES['photo']['tmp_name'];
    if((is_uploaded_file($tmpFile)) &&! ($_FILES['photo']['error'])){
        if (in_array($extFile,$validExt)) {
            $fullNameFile = $pathToFile.$nameFile;
        //    move_uploaded_file1 ($tmpFile,$fullNameFile);
            $tmpzname='user'.$modx->user->get('id');
            $nameFile=hash('ripemd160',$tmpzname).'.'.$extFile;
            $fullNameFile = $pathToFile.$nameFile;
   
        }
            else{
            $modx->log(modX::LOG_LEVEL_ERROR,'The image has an invalid extension');
        }
    }
      else {
        $modx->log(modX::LOG_LEVEL_ERROR,'Error loading file. Error code:'.$_FILES['photo']['error']);
    }
}
return true;

the above saves

<?php
$profile = $modx->user->getOne('Profile');
$pathToFile = $profile->get('photo');
$hook->setValue('photo',$pathToFile);

//if(isset($_POST['login-updprof-btn'])) {
 
    $validExt=array('jpg','png','jpeg');
    $pathToFile = $modx->config['base_path'].'assets/content/users/';
    $nameFile = $_FILES['photo']['name'];
    $extFile = mb_strtolower(pathinfo($nameFile, PATHINFO_EXTENSION));
    $tmpFile = $_FILES['photo']['tmp_name'];
   // if((is_uploaded_file($tmpFile)) &&! ($_FILES['photo']['error'])){
        if (in_array($extFile,$validExt)) {
            $fullNameFile = $pathToFile.$nameFile;
            move_uploaded_file ($tmpFile,$fullNameFile);
            $tmpzname='user'.$modx->user->get('id');
            $nameFile=hash('ripemd160',$tmpzname).'.'.$extFile;
            $fullNameFile = $pathToFile.$nameFile;
        }
          //  else{
            $modx->log(modX::LOG_LEVEL_ERROR,'The image has an invalid extension');
        //}
    //}
    //  else {
        $modx->log(modX::LOG_LEVEL_ERROR,'Error loading file. Error code:'.$_FILES['photo']['error']);
    //}
//} 

return true;

the above also saves

<?php
$profile = $modx->user->getOne('Profile');
$pathToFile = $profile->get('photo');
$hook->setValue('photo',$pathToFile);

if(isset($_POST['login-updprof-btn'])) {

    $validExt=array('jpg','png','jpeg');
    $pathToFile = $modx->config['base_path'].'assets/content/users/';
    $nameFile = $_FILES['photo']['name'];
    $extFile = mb_strtolower(pathinfo($nameFile, PATHINFO_EXTENSION));
    $tmpFile = $_FILES['photo']['tmp_name'];
    if((is_uploaded_file($tmpFile)) &&! ($_FILES['photo']['error'])){
        if (in_array($extFile,$validExt)) {
            $fullNameFile = $pathToFile.$nameFile;
            move_uploaded_file ($tmpFile,$fullNameFile);
            $tmpzname='user'.$modx->user->get('id');
            $nameFile=hash('ripemd160',$tmpzname).'.'.$extFile;
            $fullNameFile = $pathToFile.$nameFile;
        }
            else{
            $modx->log(modX::LOG_LEVEL_ERROR,'The image has an invalid extension');
        }
    }
      else {
        $modx->log(modX::LOG_LEVEL_ERROR,'Error loading file. Error code:'.$_FILES['photo']['error']);
    }
}
return true;

the above does not save :frowning:

used copy instead of move_uploaded_file and it worked. still really don’y know why if I have move_uploaded_file inside the snippet code it does not even let me save the snippet

came up with this incase anyone wants to do something similar based on above code with some changes

thatnks again @antar

<?php
// get user details
$profile = $modx->user->getOne('Profile');
//if post
if(isset($_POST['login-updprof-btn'])) {
    //set extentions
    $validExt=array('jpg','png','jpeg');
    //set path for file
    $pathToFile = $modx->config['base_path'].'site_content/content/users/';
    // set path for cmp because of media resource
    $pathToFileProfile = 'users/';
    // get file name
    $nameFile = $_FILES['photo']['name'];
    // lowercase and exxtention
    $extFile = mb_strtolower(pathinfo($nameFile, PATHINFO_EXTENSION));
    // the tmp file
    $tmpFile = $_FILES['photo']['tmp_name'];
    // upload is ok then
    if((is_uploaded_file($tmpFile)) &&! ($_FILES['photo']['error'])){
        // check extention types
        if (in_array($extFile,$validExt)) {
            // make a file name
            $tmpzname='user'.$modx->user->get('id');
            // add a hash annd extention
            $nameFile=hash('adler32',$tmpzname).'.'.$extFile;
            //full name with path
            $fullNameFile = $pathToFile.$nameFile;
            // copy the tmp to new one move_uploaded_file1 and rename1 did not work this will overwrite the old pic as they all have same name
            copy($tmpFile, $fullNameFile);
            // name and path for profile as its differnt because of media resource
            $fullNameFileProfile = $pathToFileProfile.$nameFile;
            // delete old pic in profile
            $hook->setValue('photo','');
            //set new pic path
            $hook->setValue('photo',$fullNameFileProfile);
        }
        else{
            $modx->log(modX::LOG_LEVEL_ERROR,'The image has an invalid extension');
        }
    }
      else {
        $modx->log(modX::LOG_LEVEL_ERROR,'Error loading file. Error code:'.$_FILES['photo']['error']);
    }
} 
return true;

Sounds like your server has mod_security installed with a rule that blocks the request when it contains move_uploaded_file.

@markh
thanks mark thats what I suspected. using copy worked so its fine.

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.