Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
chregu committed Oct 18, 2017
0 parents commit 325da80
Show file tree
Hide file tree
Showing 4 changed files with 411 additions and 0 deletions.
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Kirby Rokka

## WARNING

This is more a proof of concept, than something production ready. Use it at your own risk and extend it to make it very useful.

## Requirements

- [**Kirby**](https://getkirby.com/) 2.5+ (??)
- [Rokka API key](https://rokka.io/en/signup/) (trial available).

## Installation

### [Kirby CLI](https://github.com/getkirby/cli)

FIXME: Not done yet ;)

```
kirby plugin:install rokka/kirby
```

### Git Submodule


```
$ git submodule add https://github.com/rokka-io/rokka-kirby-plugin.git site/plugins/rokka
```

### Copy and Paste

FIXME. Not done yet

1. [Download](https://github.com/rokka/kirby-rokka/archive/master.zip) the contents of this repository as ZIP-file.
2. Rename the extracted folder to `rokka` and copy it into the `site/plugins/` directory in your Kirby project.

### Composer install

```
cd site/plugins/rokka
composer install
```

## Usage

In your `site/config.php` activate the plugin and set the [ROKKA API key](https://rokka.io/en/signup/) .

```php
c::set('plugin.rokka.organisation', 'YOUR_ORG_NAME_HERE'); // default is false
c::set('plugin.rokka.apikey', 'YOUR_API_KEY_HERE');
```

The plugin adds a `$myFile->rokka()` function to [$file objects](https://getkirby.com/docs/cheatsheet#file).

FIXME: currently ->rokka() returns an img tag.. maybe have it just an URL is better

```php
// get any image/file object
$myFile = $page->file('image.jpg');

// get url (on your webserver) for optimized thumb
$url = $myFile->rokka($stackname, $extension);

// echo the url as image
// https://getkirby.com/docs/toolkit/api#brick
$img = brick('img')
->attr('src', $url)
->attr('alt', $myFile->filename());
echo $img;
```

### kirbytext

```
(rokka: foo.png stack:stackname extension:jpg)
```

## Disclaimer

This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/rokka/kirby-rokka/issues/new).

## License

[MIT](https://opensource.org/licenses/MIT)

It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia, animal abuse, violence or any other form of hate speech.
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "rokka",
"version": "0.0.1",
"description": "Kirby Rokka Plugin",
"license": "MIT",
"author": "The rokka devs (https://rokka.io)",
"type": "kirby-plugin"
}
295 changes: 295 additions & 0 deletions rokka.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
<?php
use Rokka\Client\Factory;

require(kirby()->roots()->index() . "/vendor/autoload.php");

$kirby->set('widget', 'rokka-create-stacks', __DIR__ . '/widgets');
$kirby->set('route', array(
'pattern' => 'rokka-create-stacks',
'action' => function() {
Rokka::createStacks();
}
));
Rokka::$previousImageKirbyTag = Kirbytext::$tags['image'];
kirbytext::$tags['image'] = array(
'attr' => array(
'stack',
'format',
'width',
'height',
'alt',
'text',
'title',
'class',
'imgclass',
'linkclass',
'caption',
'link',
'target',
'popup',
'rel'
),
'html' => function (Kirbytag $tag) {

//Fallback to original kirby image kirby tag, if rokka is not enabled
if (!c::get('plugin.rokka.enabled')) {
return Rokka::$previousImageKirbyTag['html']($tag);
}

/** @var File $file */
$file = $tag->file($tag->attr()['image']);
if ($file == null) {
if (url::isAbsolute($tag->attr()['image'])){
//use kirby image tag impl, if we have an absolute url
return Rokka::$previousImageKirbyTag['html']($tag);
} else {
// don't return any image tag, if the file doesn't exist
return "";
}
}

$stacks = c::get('plugin.rokka.stacks');
$extension = $file->extension();
$ext = null;
if ($extension == 'svg' || $extension == 'gif') {
$stack = $stacks['raw'];
$ext = $extension;
} else if ($width = $tag->attr('width')) {
$options = "resize-width-$width";
if ($height = $tag->attr('height')) {
$options .= "-height-$height";
}
if (isset($stacks['resize'])) {
$stack = $stacks['resize']."/$options";
} else {
$stack = "dynamic/$options--options-autoformat-true";
}
} else if (isset($stacks['noop'])) {
$stack = $stacks['noop'];
} else {
$stack = "dynamic/options-autoformat-true";
}

$stack = $tag->attr('stack', $stack);
if (!$ext) {
$ext = $tag->attr('format', 'jpg');
}
if ($file == false) {
$file = null;
}

//FIXME: We should use Rokka::$previousImageKirbyTag['html']($tag) and Rokka::getImgSrc($file, $stack, $ext) here to have things like links for images
// but I didn't find an easy way to change the attributes of a $tag object. Will investigate further
return Rokka::getImgTag($file, $stack, $ext, $tag->attr());
}
);

$kirby->set('file::method', 'rokkaGetHash', 'Rokka::getRokkaHash');

$kirby->set('file::method', 'rokkaCropUrl', function($file, $width, $height = 10000, $format = 'jpg') {
return Rokka::getStackUrl('crop', $file, $width, $height, $format, "dynamic/resize-width-$width-height-$height-mode-fill--crop-width-$width-height-$height--options-autoformat-true-jpg.transparency.autoformat-true");
});

$kirby->set('file::method', 'rokkaResizeUrl', function ($file, $width, $height = 10000, $format = 'jpg') {
return Rokka::getStackUrl('resize', $file, $width, $height, $format, "dynamic/resize-width-$width-height-$height--options-autoformat-true-jpg.transparency.autoformat-true");
});

$kirby->set('file::method', 'rokka',
function ($file, $stack, $extension = null) {
return Rokka::getImgTag($file, $stack, $extension);
});

kirby()->hook(['panel.file.upload', 'panel.file.replace'], function(Kirby\Panel\Models\File $file) {
Rokka::panelUpload($file);
});

class Rokka {

public static $previousImageKirbyTag = null;

public static function panelUpload(Kirby\Panel\Models\File $file) {
$file->update([Rokka::getRokkaHashKey() => ""]);
}

public static function srcAttributes($url) {
$attrs = 'src="'.$url.'"';
$urlx2 = \Rokka\Client\UriHelper::addOptionsToUriString($url, 'options-dpr-2');
if ($urlx2 != $url) {
$attrs .= ' srcset="' . $urlx2 .' 2x"';
}
return $attrs;
}

public static function backgroundImageStyle($url) {
$style = "background-image:url('$url');";
$urlx2 = \Rokka\Client\UriHelper::addOptionsToUriString($url, 'options-dpr-2');
if ($urlx2 != $url) {
$style .= " background-image: -webkit-image-set(url('$url') 1x, url('$urlx2') 2x);";
}
return $style;
}

public static function getHashOrUpload(\File $file) {
if (!c::get('plugin.rokka.enabled')) {
return null;
}
if (!$hash = $file->rokkaGetHash()) {
$hash = Rokka::imageUpload($file);
}
return $hash;
}

public static function imageUpload(\File $file) {
if (!c::get('plugin.rokka.enabled')) {
return "";
}
if (!($file->extension() == 'svg' || strpos(F::mime($file->root()), "image/") === 0)) {
return "";
}
$imageClient = self::getRokkaClient();
$answer = $imageClient->uploadSourceImage(
$file->content(),
$file->safeName(),
'',
['meta_user' => ['kirby_location_on_upload' => dirname(parse_url($file->url(), PHP_URL_PATH))]]
);
$hash = $answer->getSourceImages()[0]->hash;
$file->update([Rokka::getRokkaHashKey() => $hash]);
return $hash;
}

public static function getImgTag(File $file = null, string $stack = null, string $extension = null, array $attr = null) {
$attr['src'] = self::getImgSrc($file, $stack, $extension, $attr);
unset($attr['image']);
return html::img($attr['src'],$attr);
}

public static function getImgSrc(File $file = null, string $stack = null, string $extension = null) {
if ($file == null) {
return "";
}

if (!$hash = self::getHashOrUpload($file)) {
return "";
}

return self::composeRokkaUrl($file, $stack, $hash, $extension);
}

public static function getRokkaHash($file) {
$var = self::getRokkaHashKey();
return $file->$var()->value();
}

public static function getRokkaHashKey() {
return "Rokkahash_". str_replace("-","_",c::get('plugin.rokka.organization'));
}

public static function createStacks() {
$logged_in_user = site()->user();
if (!$logged_in_user || !$logged_in_user->hasRole('admin')) {
go('/');
}
$stacks = c::get('plugin.rokka.stacks');
$stacksoptions = c::get('plugin.rokka.stacks.options');

$imageClient = self::getRokkaClient();
print '<h1>Create stacks on rokka</h1>';
foreach ($stacks as $key => $rokkaStackName) {
@list($name, $options) = explode("-",$key,2);
print '<h2>Create stack named: '. $rokkaStackName .'</h2>';
switch ($name) {
case "crop":
list($width,$height) = explode("x", $options);
$resize = new \Rokka\Client\Core\StackOperation('resize', ['width' => $width, 'height' => $height, 'mode' => 'fill']);
$crop = new \Rokka\Client\Core\StackOperation('crop', ['width' => $width, 'height' => $height]);
$operations = [$resize, $crop];
break;
case "noop":
case "raw":
$operations = [];
break;
case "resize":
if ($options) {
list($width,$height) = explode("x", $options);
$resize = new \Rokka\Client\Core\StackOperation('resize', ['height' => $height, 'width' => $width]);
} else {
$resize = new \Rokka\Client\Core\StackOperation('resize', ['width' => 9999]);
}
$operations = [$resize];
break;
}
if ($name == "raw") {
$stackoptions = ['source_file' => true];
} else {
$stackoptions = ['autoformat' => true, 'jpg.transparency.autoformat' => 'true'];
}
if (isset($stacksoptions[$key])) {
$stackoptions = array_merge ($stackoptions, $stacksoptions[$key]);
}
try {
$resp = $imageClient->createStack("$rokkaStackName", $operations, '', $stackoptions, true);
} catch (\Exception $e) {
var_dump($e->getResponse()->getBody()->getContents());die;
}

print '<p>Done</p>';
print '<p>Operations: ';
print json_encode($resp->getStackOperations());
print '</p>';
print '<p>Options: ';
print json_encode($resp->getStackOptions());
print '</p>';
}
}

/**
* @param File $file
* @param string $stack
* @param string $hash
* @param string $format
* @return string
*/
public static function composeRokkaUrl(File $file, string $stack, string $hash, string $format = 'jpg'): string {
if ($format === null) {
$format = 'jpg';
}

return 'https://' . c::get('plugin.rokka.organization') . ".rokka.io/$stack/$hash/" . self::rokkaSafeSeoName($file) . ".$format";
}

public static function getStackUrl(string $operation, File $file, $width, $height, $format, $dynamicStack) {
if (!$hash = Rokka::getHashOrUpload($file)) {
return $file->$operation($width, $height)->url();
}
$stacks = c::get('plugin.rokka.stacks');
$extension = $file->extension();
if ($extension == 'svg' || $extension == 'gif' ) {
$stack = $stacks['raw'];
$format = $extension;
} else if (isset($stacks["${operation}-${width}x${height}"])) {
$stack = $stacks["${operation}-${width}x${height}"];
} else {
$stack = $dynamicStack;
}
return Rokka::composeRokkaUrl($file, $stack, $hash, $format);
}

/**
* @return \Rokka\Client\Image
*/
protected static function getRokkaClient(): \Rokka\Client\Image {
$organization = c::get('plugin.rokka.organization');
$apiKey = c::get('plugin.rokka.apikey');
$imageClient = Factory::getImageClient($organization, $apiKey, '');
return $imageClient;
}

/**
* @param File $file
* @return string
*/
protected static function rokkaSafeSeoName(File $file): string {
return str_replace(".", "-", f::safeName($file->name()));
}
}
Loading

0 comments on commit 325da80

Please sign in to comment.