Create Item with File via API and PHP cURL

Hey guys,

I’m still trying to build a form on an external website that makes entries in our Omeka S via the API. So far this also works wonderfully. But since I changed from application/json to multipart/form-data I don’t understand it anymore. Unfortunately I have never done that before.

I have found many tutorials that work with cURL on the CLI with Omeka. I could not transform this myself. PHP tutorials with cURL are mostly limited to file upload. We have both here, data and files.

Here is my code, I first tried to choose a static path. The upload function of the form and the saving on the server I have already completed separately. I now wanted to try to upload any image via the api.

$api_url = “XXX/api/items?key_identity=XXX&key_credential=XXX”;

$headers = array(

    'Content-Type: multipart/form-data'

);

$title = $_POST["title"];

$file_url = "@localhost/upload/image.jpg";

$filename = "image.jpg";

$filesize = 531949;

$postfields = 'file[0]="' . $file_url . '",

data={

"o:is_public": false,

"o:media":[

    {

        "o:ingester":"upload",

        "file_index":"0",

        "o:item":{

            

        },

        "dcterms:title":[

            {

            "property_id":1,

            "property_label":"Title",

            "@value":"My media upload title",

            "type":"literal"

            }

        ]

    }

],

"dcterms:title": [

    {

        "type": "literal",

        "property_id": 1,

        "property_label": "Title",

        "is_public": true,

        "@value": "' . $title . '"

    }

],

"o-module-mapping:marker": [

    {

        "o-module-mapping:lat": ' . $_POST["latitute"] . ',

        "o-module-mapping:lng": ' . $_POST["langitute"] . ',

        "o-module-mapping:label": "' . $title . '"

    }

]

}';

$curl = curl_init();

curl_setopt_array($curl, array(

    CURLOPT_URL => $api_url,

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_ENCODING => '',

    CURLOPT_CUSTOMREQUEST => 'POST',

    CURLOPT_INFILESIZE => $filesize,

    CURLOPT_POSTFIELDS => $postfields,

    CURLOPT_HTTPHEADER => $headers

));

$response = curl_exec($curl);

curl_close($curl);

echo $response;

I think I don’t really know how to handle the $postfields.
I hope someone can help me.

Thank you so much <3
deniz

I’m not 100% familiar with the PHP interface to curl, but I believe you probably want to do the “postfields” as an array, not one big string. I’m not sure that’s your problem necessarily, but maybe. I believe curl will automatically do a multipart/form-data submission when postfields is an array.

Also, you’re presumably running this on a pretty recent version of PHP, and I think the old “prepend with at sign” method of uploading a file is no longer current; you’d now use curl_file_create or CURLFile. You might want to look at the examples there for an idea of what to do.

yes exactly, I have also tested both a bit. I will rewrite the complete json into an array. The automatic compiler only threw errors. Also with curlFile I have already played around. I just didn’t want to post this here, because this notation is very different from the examples api calls I found here in the forum.

i will try this again on monday and maybe post something about it. thanks so far!

You don’t need to rewrite the JSON into an array (though it might be a good idea to do that and then just json_encode it rather than writing JSON by hand).

What you want to do is have an array where one entry is file[0] and points to the curl file object you create, and the other is data and points to the JSON string, and that array is your POST data you pass to curl.

thank you very much! that sounds super logical. I think I was able to fit it in that way as well. My array looks very good to me.

Array ( [file[0]] => CURLFile Object ( [name] => image.jpg [mime] => image/jpeg [postname] => image.jpg ) [data] => { “o:is_public”: false, “o:media”:[ { “o:ingester”:“upload”, “file_index”:“0”, “o:item”:{ }, “dcterms:title”:[ { “property_id”:1, “property_label”:“Title”, “@value”:“My media upload title”, “type”:“literal” } ] } ], “dcterms:title”: [ { “type”: “literal”, “property_id”: 1, “property_label”: “Title”, “is_public”: true, “@value”: “test” } ], “o-module-mapping:marker”: [ { “o-module-mapping:lat”: 17.947380678685217, “o-module-mapping:lng”: 3.8671875000000004, “o-module-mapping:label”: “test” } ] } )

but i don’t even get an error message from the api. The $response returns false, nothing more. Here is the actual code.

$api_url = “XXX/api/items?key_identity=XXX&key_credential=XXX”;

$headers = array(

    'Content-Type: multipart/form-data'

);

$title = $_POST["title"];

$file_url = "localhost/upload/image.jpg";

$filename = "image.jpg";

$filesize = 531949;

$myfile = new CURLFile($filename, 'image/jpeg', $filename);

$data = '{

"o:is_public": false,

"o:media":[

    {

        "o:ingester":"upload",

        "file_index":"0",

        "o:item":{

            

        },

        "dcterms:title":[

            {

            "property_id":1,

            "property_label":"Title",

            "@value":"My media upload title",

            "type":"literal"

            }

        ]

    }

],

"dcterms:title": [

    {

        "type": "literal",

        "property_id": 1,

        "property_label": "Title",

        "is_public": true,

        "@value": "' . $title . '"

    }

],

"o-module-mapping:marker": [

    {

        "o-module-mapping:lat": ' . $_POST["latitute"] . ',

        "o-module-mapping:lng": ' . $_POST["langitute"] . ',

        "o-module-mapping:label": "' . $title . '"

    }

]

}';

$postfields = array(

    'file[0]' => $myfile,

    'data' => $data

);

print_r($postfields);

$curl = curl_init();

curl_setopt_array($curl, array(

    CURLOPT_URL => $api_url,

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_ENCODING => '',

    CURLOPT_CUSTOMREQUEST => 'POST',

    CURLOPT_INFILESIZE => $filesize,

    CURLOPT_POSTFIELDS => $postfields,

    CURLOPT_HTTPHEADER => $headers

));

$response = curl_exec($curl);

curl_close($curl);

echo $response;

false being returned from curl_exec just means curl encountered an error. I believe you have to call curl_error to get the actual content of the error after one happens.

If I had to guess, it would just be that you’ve given the incorrect local path to the file you’re trying to upload.

Really cool, it works wonderfully! You have helped me so much, thank you so much john!

I don’t know if it was the path, but as it looked curlFile expects data from a form. I don’t know exactly if they are different, but it worked with those.

Here is my code that works. What do you think? Should I post the finished project here again? That would be an HTML form markup with the appropriate PHP for a remote api entry into an omeka s with multiple fileupload.

$api_url = “XXX/api/items?key_identity=XXX&key_credential=XXX”;

$headers = array(

    'Content-Type: multipart/form-data'

);

$item_title = $_POST["title"];

$file_url = $_FILES["item-files"]["tmp_name"][0];

$filename = "myfile.jpg";

$filesize = $_FILES["item-files"]["size"][0];

$file_type = $_FILES["item-files"]["type"][0];

$myfile = new CURLFile($file_url, $file_type, $filename);

$data = '{

"o:is_public": false,

"o:media":[

    {

        "o:ingester":"upload",

        "file_index":"0",

        "o:item":{

            

        },

        "dcterms:title":[

            {

            "property_id":1,

            "property_label":"Title",

            "@value":"My media upload title",

            "type":"literal"

            }

        ]

    }

],

"dcterms:title": [

    {

        "type": "literal",

        "property_id": 1,

        "property_label": "Title",

        "is_public": true,

        "@value": "' . $item_title . '"

    }

],

"o-module-mapping:marker": [

    {

        "o-module-mapping:lat": ' . $_POST["latitute"] . ',

        "o-module-mapping:lng": ' . $_POST["langitute"] . ',

        "o-module-mapping:label": "' . $item_title . '"

    }

]

}';

$postfields = array(

    'file[0]' => $myfile,

    'data' => $data

);

$curl = curl_init();

curl_setopt_array($curl, array(

    CURLOPT_URL => $api_url,

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_ENCODING => '',

    CURLOPT_CUSTOMREQUEST => 'POST',

    CURLOPT_INFILESIZE => $filesize,

    CURLOPT_POSTFIELDS => $postfields,

    CURLOPT_HTTPHEADER => $headers

));

$response = curl_exec($curl);

if ($response === false) {

    $response = curl_error($curl);

    echo stripslashes('Curl Error: ' . $response);

}

curl_close($curl);

echo $response;

This topic was automatically closed 250 days after the last reply. New replies are no longer allowed.