How can I ingest an image into Fedora Commons using PHP?

拟墨画扇 提交于 2019-12-19 11:18:24

问题


I am trying to ingest an image into a Fedora Commons repository using PHP. Here is the code I'm using:

$queryArgs = array(
  "label" => "label goes here", 
  "format" => "info:fedora/fedora-system:METSFedoraExt-1.1", 
  "namespace" => $prefix, 
  "ownerID" => $fedoraUsername, 
  "logMessage" => "log message goes here"
);

$url = sprintf(
  "%s://%s:%d/%s/objects/%s?%s",
  "http",
  $host,
  $port,
  "fedora",
  $prefix . ":" . $identifier,
  http_build_query($queryArgs)
);
$headers = array("Accept: text/xml", "Content-Type: image/jpg");
$userPassword = $fedoraUsername . ":" . $fedoraPassword;
$verifyPeer = false;
$fileContents = file_get_contents("http://localhost/path/to/image.jpg");

$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
);

$curlHandle = curl_init();
curl_setopt_array($curlHandle, $curlOptions);
curl_exec($curlHandle);
error_log(print_r(curl_getinfo($curlHandle), true));

At the end I print out whatever curl_getinfo has to say, notably [http_code] => 415.

HTTP Error 415 Unsupported media type

What am I doing wrong here?


回答1:


I finally figured it out. I ended up making two different requests: one to create a new empty object in Fedora, the other to attach a datastream to that object. Here is the code (I put all this in a class named Fedora, but this is not necessary and might not fit your needs):

<?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);

?>


来源:https://stackoverflow.com/questions/15276157/how-can-i-ingest-an-image-into-fedora-commons-using-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!