1

I'm having a surprising amount of trouble ingesting an image file into a Fedora Commons repository with PHP (and cURL). Furthermore, I can't find any working examples of this being done online. Are there any complete examples or tutorials out there?

1
  • I'm not sure if this is the right place for such a question. Does anyone think stackoverflow would be a better place?
    – Shawn
    Mar 5, 2013 at 16:29

1 Answer 1

0

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

?>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .