XF 2.2 Uploading an Avatar via API using CSV file and PHP script

BubbaLovesCheese

Active member
Hi,

I'm working on a PHP script that uses a .csv file with userid and avatar file path in it to upload Avatar files from a local directory.

I'm having some issues with the correct format of the directory path, and I don't know how to deal with the different file extension (jpg, jpeg, png, etc)

The csv looks like this: (And it can be adjusted easily)

Code:
userid, avatar path
1244,/uploads/avatars/1628.jpg
1245,/uploads/avatars/1629.jpeg
1246,/uploads/avatars/1631.png
1247,/uploads/avatars/1633.bmp

And this is my php script.

PHP:
<?php

//  1.  file path         $filePath
//  2.  XF-Api-Key        $apiKey    It is a Super user key
//  3.  XenForo base URL  $url       The primary URL. Do not include a trailing "/"
//  4.  csv file should be : userid, avatar file path

$filePath = "avatar-doc.csv";                      //csv file path
$apiKey   = 'blZNOfSz-lad5Bhey4iWczSejtceKLX9';    //XF-Api-Key
$boardUrl   = 'https://test-forum-2.mysite.com';   //XenForo base URL 

//Check if csv file is readable
if (($handle = fopen($filePath, "r")) !== FALSE)
{
  //Read file line by line till end
  while (($data = fgetcsv($handle)) !== FALSE)
  {
      {
          //Upload the avatar for each user

          //set header
          $headers = array(
           'Content-type: application/x-www-form-urlencoded',
           'XF-Api-Key: '.$apiKey
          );

          //set post body
          $post = [
            'userid' => $data[0],         // userid
            'avatar' => $data[1],         // avatar path
            'api_bypass_permissions' => 1 // bypass the context user's permissions
      
          ];

          $post = http_build_query($post);

          //set url
          $url = $boardUrl.'/api/users/$data[0]/avatar';
      
          //post request for creating user
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          $json = curl_exec($ch);

          // convert json response to array
          $response = json_decode($json, 'true');

          if(isset($response['success']) AND $response['success'] == 1)
          {
            //message for success
            echo "Successfully created Avatar for " . $data[0] . "\n";
          }
          else
          {
            //message for failure due to some reason
            echo "There was an ERROR adding Avatar for " . $data[0] . "\n";
          }
        }
    }
}

Maybe it might help to put the avatars in the same directory as the PHP script. However, there are 149,000 users to go through.

Any suggestions would be much appreciated.
 

BubbaLovesCheese

Active member
So I have my php and csv files in the root directory of my server, and the avatars are in the /avatars directory.

This is my PHP code to upload Avatars using the API:

PHP:
<?php

//  1.  file path         $filePath
//  2.  XF-Api-Key        $apiKey    It must be Super user key
//  3.  XenForo base URL  $url       The primary URL. Do not include a trailing "/"
//  4.  csv file should be : userid, avatar file path

$filePath = "avatar-doc.csv";                      //file path
$apiKey   = 'Bhey4zSejt-blZNOfad5ceKSiWczlLX9';    //XF-Api-Key
$boardUrl   = 'https://test-forum-2.mysite.com';   //XenForo base URL - Without the trailing "/"

//Check if csv file is readable
if (($handle = fopen($filePath, "r")) !== FALSE)
{
  //Read file line by line till end
  while (($data = fgetcsv($handle)) !== FALSE)
  {
      {
          //Upload the avatar for each user

          //set header
          $headers = array(
           'Content-type: application/x-www-form-urlencoded',
           'XF-Api-Key: '.$apiKey
          );

          //set post body
          $post = [
            'userid' => $data[0],         // userid
            'avatar' => $data[1],         // avatar path
            'api_bypass_permissions' => 1 // bypass the context user's permissions
      
          ];

          $post = http_build_query($post);

          //set url
          $url = $boardUrl. "/api/users/" . $data[0] . "/avatar";
      
          //post request for creating user
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          $json = curl_exec($ch);

          // convert json response to array
          $response = json_decode($json, 'true');

          if(isset($response['success']) AND $response['success'] == 1)
          {
            //message for success
            echo "Successfully created Avatar for " . $data[0] . "\n";
          }
          else
          {
            //message for failure due to some reason
            echo "There was an ERROR adding Avatar for " . $data[0] . "\n";
          }
        }
    }
}

And this is my csv file:

Code:
852,/avatars/2521.jpg
79518,/avatars/109779.gif
121826,/avatars/167575.png

And this is the response I get after I execute the file:

Code:
Successfully created Avatar for 852
Successfully created Avatar for 79518
Successfully created Avatar for 121826

However, no avatars have been created. Can anyone see what I'm doing wrong?

Thanks.....
 

Lukas W.

Well-known member
Couple of things wrong with that request:

1. Context user is passed as header, not as Post argument.
2. Same for the bypass permission flag
3. The avatar that you send needs to be a file, not a path
 

BubbaLovesCheese

Active member
Hi!
  1. Thank you.
  2. Thank you.
  3. Yes, that is my issues. So what does that mean 'it needs to be a file'? How do I do that? Do I just use the file name in the csv doc, like 852,2521.jpg and run the php script from the same directory as the avatar files?
  4. Also the content type should have been multipart/form-data for files, not application/x-www-form-urlencoded
  5. And finally, why am I getting 'success' returned?
Thanks!
 
Last edited:

BubbaLovesCheese

Active member
Okay, I think I'm getting somewhere, but still not working.

my csv file:

Code:
852,2521.jpg
79518,109779.gif
121826,167575.png

My API code:


PHP:
<?php

//  1.  file path         $filePath
//  2.  XF-Api-Key        $apiKey    It must be Super user key
//  3.  XenForo base URL  $url       The primary URL. Do not include a trailing "/"
//  4.  csv file should be : userid, avatar file path

$filePath = "avatar-doc.csv";                      //file path
$apiKey   = 'BiWczeyblZNOfSzSejt-ceKhlad54LX9';    //XF-Api-Key
$boardUrl   = 'https://test-forum-2.mysite.com';   //XenForo base URL - Without the trailing "/"

//Check if csv file is readable
if (($handle = fopen($filePath, "r")) !== FALSE)
{
  //Read file line by line till end
  while (($data = fgetcsv($handle)) !== FALSE)
  {
      {
          //Upload the avatar for each user

          //set header
          $headers = array(
           'Content-type: multipart/form-data',
           'api_bypass_permissions: 1',         // bypass the context user's permissions
           'XF-Api-Key: '.$apiKey
          );

          $file = $data[1];
          $mime = mime_content_type($file);
          $info = pathinfo($file);
          $name = $info['basename'];
          $file = new CURLFile($file, $mime, $name);

          //set post body
          $post['avatar'] = $file;

          //$post = http_build_query($post);

          //set url
          $url = $boardUrl. "/api/users/" . $data[0] . "/avatar";
     
          //post request for creating user
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          $json = curl_exec($ch);

          // convert json response to array
          $response = json_decode($json, 'true');

          if(isset($response['success']) AND $response['success'] == 1)
          {
            //message for success
            echo "Successfully created Avatar for " . $data[0] . "\n";
          }
          else
          {
            //message for failure due to some reason
            echo "There was an ERROR adding Avatar for " . $data[0] . "\n";
          }
        }
    }
}

I think it's the way I'm building/sending my file info.
 
Top