我在使用 PHP(和 cURL)将图像文件导入 Fedora Commons 存储库时遇到了很多麻烦。此外,我在网上找不到任何可以做到这一点的工作示例。有没有完整的示例或教程?
答案1
我终于搞明白了。我最终提出了两个不同的请求:一个是在 Fedora 中创建一个新的空对象,另一个是将数据流附加到该对象。以下是代码(我将所有这些都放在名为 Fedora 的类中,但这不是必需的,可能不符合您的需求):
<?php
class Fedora {
// Use cURL with the provided functions and return the result if the HTTP Code recieved matches the expected HTTP Code
private function curlThis($curlOptions, $expectedHttpCode) {
$returnValue = false;
try {
$curlHandle = curl_init();
if ($curlHandle === false) {
throw new Exception(
"`curl_init()` returned `false`"
);
}
$settingOptionsSucceeded = curl_setopt_array($curlHandle, $curlOptions);
if ($settingOptionsSucceeded === false) {
throw new Exception(
sprintf(
"`curl_setopt_array(...)` returned false. Error: %s. Info: %s",
curl_error($curlHandle),
print_r(curl_getinfo($curlHandle), true)
),
curl_errno($curlHandle)
);
}
$curlReturn = curl_exec($curlHandle);
if ($curlReturn === false) {
throw new Exception(
sprintf(
"`curl_exec(...)` returned false. Error: %s. Info: %s",
curl_error($curlHandle),
print_r(curl_getinfo($curlHandle), true)
),
curl_errno($curlHandle)
);
}
$httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
if ($httpCode === false) {
throw new Exception(
sprintf(
"`curl_getinfo(...)` returned false. Error: %s.",
curl_error($curlHandle)
),
curl_errno($curlHandle)
);
}
if ($httpCode !== $expectedHttpCode) {
throw new Exception(
sprintf(
"`curl_getinfo(...)` returned an unexpected http code (expected %s, but got %s). Error: %s. Complete info: %s",
$expectedHttpCode,
$httpCode,
curl_error($curlHandle),
print_r(curl_getinfo($curlHandle), true)
),
curl_errno($curlHandle)
);
}
$returnValue = $curlReturn;
} catch (Exception $e) {
trigger_error(
sprintf(
"(%d) %s",
$e->getCode(),
$e->getMessage()
),
E_USER_ERROR
);
}
return $returnValue;
}
// Create a new empty object in Fedora Commons and return its pid
private function createNewEmptyObject($prefix, $id) {
$returnValue = false;
// Build URL
$protocol = variable_get("fedora_protocol"); // 'http'
$host = variable_get("fedora_host");
$port = variable_get("fedora_port"); // '8082'
$context = variable_get("fedora_context"); // 'fedora'
$pid = $prefix . ":" . $id;
$url = sprintf(
"%s://%s:%d/%s/objects/%s",
$protocol,
$host,
$port,
$context,
$pid
);
// Build cURL options
$userPassword = variable_get("fedora_username") . ":" . variable_get("fedora_password"); // username:password
$verifyPeer = false; // false for ignoring self signed certificates
$headers = array("Accept: text/xml", "Content-Type: text/xml");
$curlOptions = array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_USERPWD => $userPassword,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_SSL_VERIFYPEER => $verifyPeer,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true
);
// Try `cURL`ing
$result = $this->curlThis($curlOptions, 201);
if ($result === $pid) {
$returnValue = $result;
}
return $returnValue;
}
private function attachDatastream ($pid, $file, $datastreamID) {
$returnValue = false;
// Build URL
$protocol = variable_get("fedora_protocol"); // "http"
$host = variable_get("fedora_host");
$port = variable_get("fedora_port"); // 8082
$context = variable_get("fedora_context"); // fedora
$url = sprintf(
"%s://%s:%d/%s/objects/%s/datastreams/%s?controlGroup=M", // M stands for 'Managed Content'
$protocol,
$host,
$port,
$context,
$pid,
$datastreamID
);
// Build cURL options
$userPassword = variable_get("fedora_username") . ":" . variable_get("fedora_password"); // username:password
$verifyPeer = false; // false for ignoring self signed certificates
$headers = array("Accept: text/xml", "Content-Type: " . $file->filemime);
$fileContents = file_get_contents("sites/default/files/images/" . $file->filename);
$curlOptions = array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_USERPWD => $userPassword,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_SSL_VERIFYPEER => $verifyPeer,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fileContents
);
// Try `cURL`ing
$result = $this->curlThis($curlOptions, 201);
if ($result === $pid) {
$returnValue = $result;
}
return $returnValue;
}
public function ingest($namespace, $identifier, $file) {
$pid = $this->createNewEmptyObject($namespace, $identifier);
if ($pid) {
$result = $this->attachDatastream($pid, $file, "IMAGE");
if ($result) {
error_log("Successfully ingested a file!");
} else {
error_log("FAILED ATTACHING DATASTREAM TO NEW OBJECT");
}
} else {
error_log("FAILED CREATING NEW EMPTY OBJECT");
}
}
}
$fedora = new Fedora();
/*
* $file is an object obtained by uploading a file into a drupal file system (at /drupal/sites/default/files/images/singe.jpg). It has the following attributes:
* $file->filemime === "image/jpeg"
* $file->filename === "singe.jpg"
*/
$fedora->ingest('namespace', 'identifier', $file);
?>