Sequenzia/app/models/Inline.php
Parziphal cf9cba40b6 Fully enabled Inline Images.
A little detail: the "Add image" button was moved to a new table row, so it stands out more.
Known bugs/errors:
- When cropping an animated GIF inline (with a secondary JPG inline), although the images are correctly cropped, an empty error is displayed.
2013-12-31 14:22:59 -05:00

132 lines
4.2 KiB
PHP
Executable File

<?php
class Inline extends Rails\ActiveRecord\Base
{
protected function associations()
{
return [
'belongs_to' => [
'user'
],
'has_many' => [
'inline_images' => [function() { $this->order('sequence'); } /*Not yet supported: 'dependent' => 'destroy'*/, 'class_name' => 'InlineImage']
]
];
}
protected function callbacks()
{
return [
'before_destroy' => [
'destroy_inline_images'
]
];
}
protected function destroy_inline_images()
{
foreach ($this->inline_images as $i) {
$i->destroy();
}
}
# Sequence numbers must start at 1 and increase monotonically, to keep the UI simple.
# If we've been given sequences with gaps or duplicates, sanitize them.
public function renumber_sequences()
{
$first = 1;
foreach ($this->inline_images as $image) {
$image->sequence = $first;
$image->save();
$first++;
}
}
public function pretty_name()
{
return 'x';
}
public function crop(array $params = [])
{
# MI: set default params
$params = array_merge([
'top' => 0,
'bottom' => 0,
'left' => 0,
'right' => 0,
], $params);
if ($params['top'] < 0 or $params['top'] > 1 or
$params['bottom'] < 0 or $params['bottom'] > 1 or
$params['left'] < 0 or $params['left'] > 1 or
$params['right'] < 0 or $params['right'] > 1 or
$params['top'] >= $params['bottom'] or
$params['left'] >= $params['right']
) {
$this->errors()->add('parameter', 'error');
return false;
}
$images = $this->inline_images;
foreach ($images as $image) {
# Create a new image with the same properties, crop this image into the new one,
# and delete the old one.
$new_image = new InlineImage([
'description' => $image->description,
'sequence' => $image->sequence,
'inline_id' => $this->id,
'file_ext' => 'jpg'
]);
$size = $this->reduce_and_crop($image->width, $image->height, $params);
try {
# Create one crop for the image, and InlineImage will create the sample and preview from that.
Moebooru\Resizer::resize($image->file_ext, $image->file_path(), $new_image->tempfile_image_path(), $size, 95);
chmod($new_image->tempfile_image_path(), 0775);
} catch (Exception $e) {
if (is_file($new_image->tempfile_image_path())) {
unlink($new_image->tempfile_image_path());
}
$this->errors()->add('crop', "couldn't be genrated (" . $e->getMessage() . ")");
return false;
}
$new_image->got_file();
$new_image->save();
$image->destroy();
}
}
public function api_attributes()
{
return [
'id' => (int)$this->id,
'description' => (string)$this->description,
'user_id' => (int)$this->user_id,
'images' => $this->inline_images->asJson()
];
}
public function asJson(array $params = [])
{
return $this->api_attributes();
}
protected function reduce_and_crop($image_width, $image_height, array $params = [])
{
$cropped_image_width = $image_width * ($params['right'] - $params['left']);
$cropped_image_height = $image_height * ($params['bottom'] - $params['top']);
$size = [];
$size['width'] = $cropped_image_width;
$size['height'] = $cropped_image_height;
$size['crop_top'] = $image_height * $params['top'];
$size['crop_bottom'] = $image_height * $params['bottom'];
$size['crop_left'] = $image_width * $params['left'];
$size['crop_right'] = $image_width * $params['right'];
return $size;
}
}