Загрузка изображения профиля через PHP API

У меня возникли проблемы с загрузкой изображения профиля для пользователя. Я продолжаю получать ошибку 404, которая, как говорят мне документы API, указывает на то, что профиль не может быть найден. Однако над кодом, который я покажу через секунду, у меня есть код для получения профиля, и он существует для конкретного идентификатора пользователя, который я использую. Кроме того:

  • Это с PHP SDK
  • Учетная запись, которую я использовал для аутентификации, имеет доступ к редактированию профилей пользователей.
  • Тестовое изображение, которое я использую, существует, и я могу его прочитать.

Вот мой код. Это немного небрежно, но я исправлю это, как только сделаю это для этого конкретного тестового пользователя:

$file = "testimage.jpeg";
$image_data = file_get_contents($file);

// Build our data
$uid = uniqid();
$data = "--" . $uid . "\r\n".
    "Content-Disposition: form-data; name=\"profileImage\"; filename=\"profileImage.jpeg\"\r\n".
    "Content-Type: image/jpeg\r\n".
    "\r\n".
    $image_data . "\r\n".
    "--" . $uid . "--";

$success = false;
$tryAgain = true;
$numAttempts = 1;
$url = "/d2l/api/lp/1.0/profile/user/".$userId."/image";
$uri = $opContext->createAuthenticatedUri($url, "POST");
curl_setopt($ch, CURLOPT_URL, $uri);
while ($tryAgain && $numAttempts < MAX_NUM_ATTEMPTS) {
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Disposition: multipart/form-data; boundary='.$uid,
        'Content-Length: ' . strlen($data))
    );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $response = curl_exec($ch);
    $httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    $responseCode = $opContext->handleResult($response, $httpCode, $contentType);
    if ($responseCode == D2LUserContext::RESULT_OKAY) {
        $success = true;
        $tryAgain = false;
    }
    elseif ($responseCode == D2LUserContext::RESULT_INVALID_TIMESTAMP) {
        // Try again since time skew should now be fixed.
        $tryAgain = true;
    }
    else {      // Something bad happened
        echo "here:\r\n".
            $httpCode.
            "\r\n\r\n".
            $responseCode;
        exit;
    }
    $numAttempts++;
}

Я в недоумении, чего мне не хватает. Мы будем очень признательны за любые советы. Спасибо

Изменить: я только что заметил этот раздел в документах API:

Примечание

Чтобы использовать это действие, служба должна предоставить конкретному приложению разрешение на выполнение этого действия (то есть предоставить разрешение конкретному идентификатору приложения и ключу для выполнения этого действия).

Я узнаю, действительно ли у нашего идентификатора/ключа приложения есть разрешение. Я думал, что да, но, возможно, мне дали неверную информацию. Я поинтересуюсь об этом.


person Jeff Stiles    schedule 06.09.2013    source источник


Ответы (1)


Вот функция, которую я использую, которая работает. Я использую PHP Api для получения объекта пользовательского контекста, а все остальное делаю через curl.

$opContext — из PHP API

$user_id - из d2l

$filename - имя файла изображения на сервере

$filepath - путь к файлу на сервере (у меня преподаватели и студенты находятся в разных местах)

$filetype - для MIME-типа

static function set_user_image($opContext,$user_id,$filename,$filepath,$filetype){
    $fp = fopen($filepath.$filename, 'r');
    $contents = fread($fp, filesize($filepath.$filename));
    fclose($fp);
    $random_hash = "xxBOUNDARYxx";
    $request ="--".$random_hash."\r\nContent-Type: application/json\r\n\r\n{\"Text\":\"Some comment\", \"HTML\":null}\r\n\r\n--".
                   $random_hash."\r\nContent-Disposition: form-data; name=\"profileimage\"; filename="."\"$filename\""."\r\nContent-Type: image/$filetype\r\n\r\n".
                   $contents."\r\n\r\n--".$random_hash;

    $length=strlen($request);
    $url = $opContext->createAuthenticatedUri("/d2l/api/lp/1.1/profile/user/$user_id/image","POST");

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url); 
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLINFO_HEADER_OUT, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("HTTP/1.1", "Content-Type: multipart/form-data; boundary=xxBOUNDARYxx","Content-Length:".$length));
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST,true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
    $response = curl_exec($ch);             
}   
person Johnnygizmo    schedule 06.09.2013
comment
Спасибо большое. Это сработало для меня. Я все еще просматриваю его, чтобы сравнить и попытаться увидеть, что именно не так с моим кодом (просто для моего собственного понимания будущей работы с этим), но да, это сработало как шарм. Огромное спасибо. - person Jeff Stiles; 07.09.2013
comment
Здорово! Я рад, что это сработало для вас. Я обнаружил, что написание моей собственной библиотеки-оболочки для D2L API помогло во многих случаях. - person Johnnygizmo; 08.09.2013
comment
Согласен - чтобы выполнить свою внутреннюю работу и тестирование, одной из первых вещей, которые я сделал, было написать (довольно грубый) набор оболочек вокруг D2L Python SDK, и это очень помогло, особенно с привередливыми операциями, такими как бинарные загрузки данных. - person Viktor Haag; 09.09.2013