Skip to content

Commit

Permalink
Fixes #15: added ability to re-crop image
Browse files Browse the repository at this point in the history
  • Loading branch information
prodex authored and samdark committed Apr 26, 2017
1 parent ef86cc9 commit ce771d1
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 22 deletions.
27 changes: 27 additions & 0 deletions controllers/ProjectController.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,31 @@ public function actionAutocompleteTags($term)
$tags = Tag::find()->where(['like', 'name', $term])->limit(10)->all();
return $this->asJson(ArrayHelper::getColumn($tags, 'name'));
}

/**
* @param int $imageId
*
* @return $this
* @throws ForbiddenHttpException
* @throws NotFoundHttpException
*/
public function actionImageOriginal($imageId)
{
/** @var Image $image */
$image = Image::find()
->with('project')
->where(['id' => $imageId])
->limit(1)
->one();

if (!$image) {
throw new NotFoundHttpException('Image not found.');
}

if (!UserPermissions::canManageProject($image->project)) {
throw new ForbiddenHttpException("You don't have access to this image.");
}

return Yii::$app->response->sendFile($image->getOriginalPath(), $image->getOriginalFilename());
}
}
2 changes: 2 additions & 0 deletions models/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ public function generateThumbnail($crop = null)
->thumbnail(new Box($size[0], $size[1]), ImageInterface::THUMBNAIL_INSET)
->save($this->ensureThumbnailPath());
}

$this->touch('updated_at');
}

public function generateFull()
Expand Down
77 changes: 64 additions & 13 deletions models/ImageUploadForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
use yii\web\UploadedFile;

/**
* @property Image $image
* @property bool|array $imageCropDataAsArray
*/
class ImageUploadForm extends Model
{
const MAX_UPLOAD_SIZE = 20000000; // 20 MB

private $_projectID;
/**
* @var Image
*/
private $_image;

/**
* @var array
*/
Expand All @@ -28,24 +34,36 @@ class ImageUploadForm extends Model
* @var string
*/
public $imageCropData;
/**
* @var int
*/
public $imageId;

public function rules()
{
return [
[
['file'],
'image',
'skipOnEmpty' => false,
'skipOnEmpty' => true,
'extensions' => 'png',
'maxSize' => self::MAX_UPLOAD_SIZE
],

['imageCropData', 'required'],
['imageCropData', function ($attribute) {
if (!$this->imageCropDataAsArray) {
$this->addError($attribute, 'Empty crop date for thumb.');
}
}],

['imageId', 'default', 'value' => null],
['imageId', 'integer'],
['imageId', function () {
if (!$this->image) {
$this->addError('image', 'Image not found.');
}
}],
];
}

Expand All @@ -55,20 +73,32 @@ public function __construct($projectID, array $config = [])
parent::__construct($config);
}

/**
* @return bool
*/
public function upload()
{
if ($this->validate()) {
if ($this->file !== null) {
$model = new Image();
$model->project_id = $this->_projectID;
if ($model->save()) {
$this->file->saveAs($model->ensureOriginalPath());
$model->generateFull();
$model->generateThumbnail($this->imageCropDataAsArray ?: null);
}
}
if (!$this->validate()) {
return false;
}

if ($this->file !== null) {
$image = new Image();
$image->project_id = $this->_projectID;

return true;
if ($image->save()) {
$this->file->saveAs($image->ensureOriginalPath());
$image->generateFull();
$image->generateThumbnail($this->imageCropDataAsArray ? : null);

return true;
}
} elseif ($this->image) {
$image = $this->image;
$image->generateThumbnail($this->imageCropDataAsArray ? : null);
if ($image->save()) {
return true;
}
}

return false;
Expand All @@ -94,4 +124,25 @@ public function getImageCropDataAsArray()

return $this->_imageCropDataAsArray;
}

/**
* @return Image
*/
public function getImage()
{
if ($this->imageId !== null && $this->_image === null) {
/** @var Image $image */
$image = Image::find()
->andWhere([
'id' => $this->imageId,
'project_id' => $this->_projectID
])
->limit(1)
->one();

$this->_image = $image ? : false;
}

return $this->_image;
}
}
2 changes: 2 additions & 0 deletions views/project/view.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<div class="image">
<a href="<?= $image->getUrl() ?>"><img class="img-responsive" src="<?= $image->getThumbnailRelativeUrl() ?>" alt=""></a>
<?php if ($canManageProject): ?>
<span class="recrop glyphicon glyphicon-scissors js-project-image-recrop" data-id="<?= $image->id ?>" data-url="<?= Url::to(['project/image-original', 'imageId' => $image->id]) ?>"></span>
<span class="delete glyphicon glyphicon-remove" data-id="<?= $image->id ?>" data-url="<?= Url::to(['project/delete-image']) ?>" data-confirm="<?= Yii::t('project', 'Are you sure you want to delete this image?') ?>"></span>
<?php endif ?>
</div>
Expand All @@ -91,6 +92,7 @@
<?= $form->errorSummary($imageUploadForm) ?>

<?= Html::activeHiddenInput($imageUploadForm, 'imageCropData') ?>
<?= Html::activeHiddenInput($imageUploadForm, 'imageId') ?>
<?= $form->field($imageUploadForm, 'file')->fileInput(['accept' => 'image/png']) ?>

<div id="image-cropper-block" class="form-group" style="display: none;">
Expand Down
14 changes: 14 additions & 0 deletions web/css/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ a.desc:after {
color: #f00;
}

.project-view .image .recrop {
position: absolute;
top: 0;
left: 0px;
font-size: 150%;
background: #fff;
border-radius: 10rem;
cursor: pointer;
}

.project-view .image .recrop:hover {
color: green;
}

.projects-flow {
display: flex;
flex-flow: row wrap;
Expand Down
45 changes: 36 additions & 9 deletions web/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function initProjectImageUpload(widthMin, heightMin) {
var imageBlock = imageCropperBlock.find('.image-block');
var inputImageCropData = $('#project-image-upload [name="ImageUploadForm[imageCropData]"]');
var inputFile = $('#project-image-upload [name="ImageUploadForm[file]"]');
var inputImageId = $('#project-image-upload [name="ImageUploadForm[imageId]"]');

imageBlock.cropper({
viewMode: 1,
Expand Down Expand Up @@ -71,16 +72,26 @@ function initProjectImageUpload(widthMin, heightMin) {
}
});

inputFile.on('change', function() {
function clear() {
imageCropperBlock.hide(0);
inputImageCropData.val('');

var files = this.files;
inputImageId.val('');

if (!imageBlock.data('cropper')) {
return;
return false;
}

return true;
}

inputFile.on('change', function (e) {
e.stopPropagation();

if (!clear()) {
return false;
}

var files = this.files;
if (files && files.length > 0) {
var file = files[0];

Expand All @@ -94,13 +105,29 @@ function initProjectImageUpload(widthMin, heightMin) {
}
});

$('.js-project-image-reset').on('click', function () {
imageCropperBlock.hide(0);
inputImageCropData.val('');
$('.js-project-image-recrop').on('click', function (e) {
e.stopPropagation();

if (!clear()) {
return false;
}

inputFile.val('');

if (!imageCropperBlock.data('cropper')) {
return;
var imageId = $(this).data('id');
var imageUrl = $(this).data('url');

inputImageId.val(imageId);
imageBlock.cropper('reset').cropper('replace', imageUrl);

imageCropperBlock.show(0);
});

$('.js-project-image-reset').on('click', function (e) {
e.stopPropagation();

if (!clear()) {
return false;
}

imageCropperBlock.cropper('reset')
Expand Down

0 comments on commit ce771d1

Please sign in to comment.