0

first, what I'd like to achieve is the following:

I need to pass an image from an external source into the underlying database of structr. therefore I need to convert that image to base64. But as I'm not aware of a way to get serverside javascript/rhino to receive an image via url and convert it into base64, I came up with a workaround:

so I wrote two schema methods, one (script A) in serverside javascript and the other (script B) in php.

script A kind of imports data from an external REST API, builds the external image url and needs to pass it to script B which will use cURL to get the image, convert it to base64 and hand it back to script A.

So that's where I'm stuck right now. Help Article on Custom Schema Methods doesn't really help, because neither covers it PHP syntax nor does it state if it's even possible to return something from a custom schema method.

evaluate_script() or replace() are other possibilities, but I'm still not sure how to use it within the given context.

Maybe there's another way handling that issue, I'm open for suggestions.

SCRIPT A: Serverside Javascript Method:
var url = 'image_url",
instance = Structr.get('this'),
base64String = Instance.PHPMethod(url); 
//then write base64String to structr database

SCRIPT B: PHP Method:
php{
<?php 
$url = retrieve.url from SCRIPT A ????;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$data = curl_exec($curl);
curl_close($curl); 
$b64 = base64_encode($data); 
echo $b64;
?>
}

Thanks in advance.

reallyATypo
  • 103
  • 5

2 Answers2

3

EDIT: For structr 3.5+ the newer answer from @Axel Morgner is better. If you are using a version >= 3.5, rather use that code than this.


I'll assume your PHP Script is a global schema method and is called getImageAsBase64PHP. Then the solution would work like this:

php{
    <?php 
        $url = $Structr->get('imageUrl');

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        $data = curl_exec($curl);
        curl_close($curl); 
        $b64 = base64_encode($data);

        $Structr->call('store', 'downloadedImageBaseData', $b64);
    ?>
}

This method could be called like so:

{
    // call the global schema method (this is admin-only! if this needs to be initiated by a regular user, use doPrivileged())
    // the parameter "imageUrl" will be used in the PHP script
    $.call('getImageAsBase64PHP', {
        imageUrl: 'https://structr.com/new/content-img/screenshots/screenshot-schema-blog.png'
    });

    // the base64 encoded string provided by the other method
    let baseData = $.retrieve('downloadedImageBaseData');

    // create a new file with name "test.png" and the base64Data string as content
    $.create('Image', 'name', 'test.png', 'base64Data', baseData.toString());
}

In the current version this is the best I can do as this is a use-case we had not yet encountered. In one of the next versions there will be a way easier method to achieve this.

vigorouscoding
  • 426
  • 4
  • 9
1

With the two commits https://github.com/structr/structr/commit/0390805c834d50fe4b6d8c7b3d86e90242e8df77 and https://github.com/structr/structr/commit/88e8cb6cd24bfca33ecc674f60d625108cb8eec8 (which will both be included in the upcoming release 3.5), we added support for binary data to the HTTP GET() function and direct binary processing to base64encode but also for set_content() and append_content() so the image data can directly be written to a file:

Server-side JavaScript:

${{
    let data = $.GET('https://some.host.domain/img.png', 'application/octet-stream');
    let img = $.getOrCreate('File', 'name', 'img.png', 'contentType', 'image/png');
    $.setContent(img, data);
}}

Or even shorter in StructrScript:

${set_content(get_or_create('File', 'name', 'img.png', 'contentType', 'image/png'), GET('https://some.host.domain/img.png', 'application/octet-stream'))}
Axel Morgner
  • 2,292
  • 16
  • 15