Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
    
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 '13 at 16:29

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

?>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.