Skip to content

Commit

Permalink
Watermark (#29)
Browse files Browse the repository at this point in the history
* work in progress, fixes #17

* Applied fixes from StyleCI

* watermarking works, ready to tag and publish
  • Loading branch information
luceos committed Nov 14, 2016
2 parents 702ec59 + 7831132 commit 713b6c5
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 19 deletions.
30 changes: 25 additions & 5 deletions js/admin/dist/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ System.register("flagrow/upload/addUploadPane", ["flarum/extend", "flarum/compon
});;
"use strict";

System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "flarum/components/Button", "flarum/utils/saveSettings", "flarum/components/Alert", "flarum/components/Select", "flarum/components/Switch"], function (_export, _context) {
System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "flarum/components/Button", "flarum/utils/saveSettings", "flarum/components/Alert", "flarum/components/Select", "flarum/components/Switch", "flarum/components/UploadImageButton"], function (_export, _context) {
"use strict";

var Component, Button, saveSettings, Alert, Select, Switch, UploadPage;
var Component, Button, saveSettings, Alert, Select, Switch, UploadImageButton, UploadPage;
return {
setters: [function (_flarumComponent) {
Component = _flarumComponent.default;
Expand All @@ -57,6 +57,8 @@ System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "fl
Select = _flarumComponentsSelect.default;
}, function (_flarumComponentsSwitch) {
Switch = _flarumComponentsSwitch.default;
}, function (_flarumComponentsUploadImageButton) {
UploadImageButton = _flarumComponentsUploadImageButton.default;
}],
execute: function () {
UploadPage = function (_Component) {
Expand All @@ -70,13 +72,18 @@ System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "fl
babelHelpers.createClass(UploadPage, [{
key: "init",
value: function init() {
var _this2 = this;
var _watermarkPositions,
_this2 = this;

// whether we are saving the settings or not right now
this.loading = false;

// the fields we need to watch and to save
this.fields = ['availableUploadMethods', 'mimeTypesAllowed', 'uploadMethod', 'resizeMaxWidth', 'cdnUrl', 'maxFileSize', 'overrideAvatarUpload',
this.fields = ['availableUploadMethods', 'mimeTypesAllowed', 'uploadMethod',
// image
'resizeMaxWidth', 'cdnUrl', 'maxFileSize', 'overrideAvatarUpload',
// watermark
'addsWatermarks', 'watermark', 'watermarkPosition',
// Imgur
'imgurClientId',
// AWS
Expand All @@ -85,6 +92,11 @@ System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "fl
// the checkboxes we need to watch and to save.
this.checkboxes = ['mustResize', 'overrideAvatarUpload'];

// watermark positions
this.watermarkPositions = (_watermarkPositions = {
'top-right': 'top-left'
}, babelHelpers.defineProperty(_watermarkPositions, "top-right", 'top-right'), babelHelpers.defineProperty(_watermarkPositions, 'bottom-left', 'bottom-left'), babelHelpers.defineProperty(_watermarkPositions, 'bottom-right', 'bottom-right'), babelHelpers.defineProperty(_watermarkPositions, 'center', 'center'), babelHelpers.defineProperty(_watermarkPositions, 'left', 'left'), babelHelpers.defineProperty(_watermarkPositions, 'top', 'top'), babelHelpers.defineProperty(_watermarkPositions, 'right', 'right'), babelHelpers.defineProperty(_watermarkPositions, 'bottom', 'bottom'), _watermarkPositions);

// options for the dropdown menu
this.uploadMethodOptions = {};

Expand Down Expand Up @@ -130,7 +142,15 @@ System.register("flagrow/upload/components/UploadPage", ["flarum/Component", "fl
value: this.values.resizeMaxWidth() || 100,
oninput: m.withAttr('value', this.values.resizeMaxWidth),
disabled: !this.values.mustResize()
})]), m('fieldset', {
})]), m('fieldset', {className: 'UploadPage-watermark'}, [m('legend', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.title')), m('div', {className: 'helpText'}, app.translator.trans('flagrow-upload.admin.help_texts.watermark')), Switch.component({
state: this.values.addsWatermarks() || false,
children: app.translator.trans('flagrow-upload.admin.labels.watermark.toggle'),
onchange: this.values.addsWatermarks
}), m('label', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.position')), m('div', {}, [Select.component({
options: this.watermarkPositions,
onchange: this.values.watermarkPosition,
value: this.values.watermarkPosition() || 'bottom-right'
})]), m('label', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.file')), m(UploadImageButton, {name: "flagrow/watermark"})]), m('fieldset', {
className: 'UploadPage-local',
style: { display: this.values.uploadMethod() === 'local' ? "block" : "none" }
}, [m('legend', {}, app.translator.trans('flagrow-upload.admin.labels.local.title')), m('label', {}, app.translator.trans('flagrow-upload.admin.labels.local.cdn_url')), m('input', {
Expand Down
38 changes: 38 additions & 0 deletions js/admin/src/components/UploadPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import saveSettings from "flarum/utils/saveSettings";
import Alert from "flarum/components/Alert";
import Select from "flarum/components/Select";
import Switch from "flarum/components/Switch";
import UploadImageButton from "flarum/components/UploadImageButton";

export default class UploadPage extends Component {

Expand All @@ -16,10 +17,15 @@ export default class UploadPage extends Component {
'availableUploadMethods',
'mimeTypesAllowed',
'uploadMethod',
// image
'resizeMaxWidth',
'cdnUrl',
'maxFileSize',
'overrideAvatarUpload',
// watermark
'addsWatermarks',
'watermark',
'watermarkPosition',
// Imgur
'imgurClientId',
// AWS
Expand All @@ -35,6 +41,19 @@ export default class UploadPage extends Component {
'overrideAvatarUpload'
];

// watermark positions
this.watermarkPositions = {
'top-right': 'top-left',
'top-right': 'top-right',
'bottom-left': 'bottom-left',
'bottom-right': 'bottom-right',
'center': 'center',
'left': 'left',
'top': 'top',
'right': 'right',
'bottom': 'bottom'
};

// options for the dropdown menu
this.uploadMethodOptions = {};

Expand Down Expand Up @@ -111,6 +130,25 @@ export default class UploadPage extends Component {
disabled: !this.values.mustResize()
}),
]),
m('fieldset', {className: 'UploadPage-watermark'}, [
m('legend', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.title')),
m('div', {className: 'helpText'}, app.translator.trans('flagrow-upload.admin.help_texts.watermark')),
Switch.component({
state: this.values.addsWatermarks() || false,
children: app.translator.trans('flagrow-upload.admin.labels.watermark.toggle'),
onchange: this.values.addsWatermarks
}),
m('label', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.position')),
m('div', {}, [
Select.component({
options: this.watermarkPositions,
onchange: this.values.watermarkPosition,
value: this.values.watermarkPosition() || 'bottom-right'
}),
]),
m('label', {}, app.translator.trans('flagrow-upload.admin.labels.watermark.file')),
<UploadImageButton name="flagrow/watermark"/>
]),
m('fieldset', {
className: 'UploadPage-local',
style: {display: (this.values.uploadMethod() === 'local' ? "block" : "none")}
Expand Down
11 changes: 10 additions & 1 deletion locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ flagrow-upload:
mime_types_allowed: Specify the mime types you like to allow in your application using a regular expression
resize:
title: Image resize
toggle: Toggle the resize
toggle: Resize images
max_width: Maximum image width
max_height: Maximum image height
watermark:
title: Watermark images
toggle: Watermark images
position: Watermark position
file: Upload your watermark image
local:
title: Local storage settings
cdn_url: Content Delivery URL (prefixes files)
Expand All @@ -50,3 +55,7 @@ flagrow-upload:
they get uploaded. You can choose a maximum width
and height, in pixels. The resizing process keeps the
aspect ratio of the images.
watermark: >
Choose whether images will have a watermark added during
upload. Watermarks are added to non-gifs based on your
preferences below.
58 changes: 58 additions & 0 deletions src/Api/Controllers/WatermarkUploadController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/*
* This file is part of flagrow/upload.
*
* Copyright (c) Flagrow.
*
* http://flagrow.github.io
*
* For the full copyright and license information, please view the license.md
* file that was distributed with this source code.
*/


namespace Flagrow\Upload\Api\Controllers;

use Flarum\Api\Controller\UploadFaviconController;
use Flarum\Core\Group;
use Illuminate\Support\Str;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use League\Flysystem\MountManager;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;

class WatermarkUploadController extends UploadFaviconController
{
public function data(ServerRequestInterface $request, Document $document)
{
$this->assertAdmin($request->getAttribute('actor'));


$file = array_get($request->getUploadedFiles(), 'flagrow/watermark');

$tmpFile = tempnam($this->app->storagePath() . '/tmp', 'flagrow.watermark');

$file->moveTo($tmpFile);

$mount = new MountManager([
'source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))),
'target' => new Filesystem(new Local($this->app->storagePath())),
]);

if (($path = $this->settings->get('flagrow.upload.watermark')) && $mount->has($file = "target://$path")) {
$mount->delete($file);
}

$uploadName = 'watermark-' . Str::lower(Str::quickRandom(8));

$mount->move('source://' . pathinfo($tmpFile, PATHINFO_BASENAME), "target://$uploadName");

$this->settings->set('flagrow.upload.watermark', $uploadName);

return [
'groups' => Group::whereVisibleTo($request->getAttribute('actor'))->get()
];
}
}
13 changes: 11 additions & 2 deletions src/Commands/UploadHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use Flarum\Core\Exception\ValidationException;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Foundation\Application;
use Flarum\Util\Str;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Str as IllStr;
use League\Flysystem\Adapter\Local;
Expand Down Expand Up @@ -109,7 +108,7 @@ public function handle(Upload $command)
}

$file = (new File())->forceFill([
'base_name' => Str::slug($uploadedFile->getClientOriginalName()),
'base_name' => $this->getBasename($uploadedFile),
'size' => $uploadedFile->getSize(),
'type' => $uploadedFile->getMimeType(),
'actor_id' => $command->actor->id,
Expand Down Expand Up @@ -180,4 +179,14 @@ public function getDefaultMarkdownStringAttribute(File $file)

return $label . $url;
}

protected function getBasename(UploadedFile $uploadedFile)
{
return sprintf("%s.%s",
basename($uploadedFile->getClientOriginalName(), ".{$uploadedFile->getClientOriginalExtension()}"),
$uploadedFile->guessExtension() ?
$uploadedFile->guessExtension() :
$uploadedFile->getClientOriginalExtension()
);
}
}
5 changes: 5 additions & 0 deletions src/Helpers/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class Settings
'resizeMaxWidth',
'cdnUrl',

// Watermarks
'addsWatermarks',
'watermarkPosition',
'watermark',

// Override avatar upload
'overrideAvatarUpload',

Expand Down
2 changes: 2 additions & 0 deletions src/Listeners/AddUploadsApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace Flagrow\Upload\Listeners;

use Flagrow\Upload\Api\Controllers\UploadController;
use Flagrow\Upload\Api\Controllers\WatermarkUploadController;
use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Event\ConfigureApiRoutes;
use Flarum\Event\PrepareApiAttributes;
Expand All @@ -41,6 +42,7 @@ public function subscribe(Dispatcher $events)
public function configureApiRoutes(ConfigureApiRoutes $event)
{
$event->post('/flagrow/upload', 'flagrow.upload', UploadController::class);
$event->post('/flagrow/watermark', 'flagrow.watermark', WatermarkUploadController::class);
}

/**
Expand Down
46 changes: 35 additions & 11 deletions src/Processors/ImageProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Flagrow\Upload\Contracts\Processable;
use Flagrow\Upload\File;
use Flagrow\Upload\Helpers\Settings;
use Intervention\Image\Image;
use Intervention\Image\ImageManager;
use Symfony\Component\HttpFoundation\File\UploadedFile;

Expand All @@ -42,19 +43,42 @@ public function __construct(Settings $settings)
*/
public function process(File &$file, UploadedFile &$upload)
{
if ($this->settings->get('mustResize') && $upload->getMimeType() != 'image/gif') {
if ($upload->getMimeType() != 'image/gif') {
$image = (new ImageManager())->make($upload->getRealPath());

if ($this->settings->get('mustResize')) {
$this->resize($image);
}

if ($this->settings->get('addsWatermarks')) {
$this->watermark($image);
}

@file_put_contents(
$upload->getRealPath(),
(new ImageManager())
->make($upload->getRealPath())
->resize(
$this->settings->get('resizeMaxWidth', Settings::DEFAULT_MAX_IMAGE_WIDTH),
null,
function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->encode($upload->getMimeType()));
$image->encode($upload->getMimeType())
);
}
}

protected function resize(Image $manager)
{
$manager->resize(
$this->settings->get('resizeMaxWidth', Settings::DEFAULT_MAX_IMAGE_WIDTH),
null,
function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
}

protected function watermark(Image $image)
{
if ($this->settings->get('watermark')) {
$image->insert(
storage_path($this->settings->get('watermark')),
$this->settings->get('watermarkPosition', 'bottom-right')
);
}
}
}

0 comments on commit 713b6c5

Please sign in to comment.