Skip to content

Commit 5dc92dc

Browse files
author
Pedro Fernandes Steimbruch
committed
Refs #17122 implementing image upload for project with burzum
1 parent 4aef730 commit 5dc92dc

10 files changed

Lines changed: 263 additions & 7 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"mobiledetect/mobiledetectlib": "2.*",
1111
"cakephp/migrations": "~1.0",
1212
"cakephp/plugin-installer": "*",
13-
"burzum/file-storage": "~1.1.0"
13+
"burzum/file-storage": "~1.1.0",
14+
"burzum/cakephp-imagine-plugin": "~2.0"
1415
},
1516
"require-dev": {
1617
"psy/psysh": "@stable",

composer.lock

Lines changed: 108 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/bootstrap.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,10 @@
181181
*/
182182

183183
Plugin::load('Migrations');
184+
Plugin::load('Burzum/Imagine');
184185
Plugin::load('Burzum/FileStorage');
185186
include('file_storage.php');
186-
Plugin::load('Showcase', ['routes' => true, 'bootstrap' => true]);
187+
Plugin::load('Showcase', ['routes' => true]);
187188

188189
// Only try to load DebugKit in development mode
189190
// Debug Kit should not be installed on a production system

config/file_storage.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
$listener = new LocalFileStorageListener();
99
EventManager::instance()->on($listener);
1010

11+
$listener = new ImageProcessingListener();
12+
EventManager::instance()->on($listener);
13+
1114
StorageManager::config('Local', [
1215
'adapterOptions' => [ROOT . DS . 'files', true],
1316
'adapterClass' => '\Gaufrette\Adapter\Local',

plugins/Showcase/src/Controller/ProjectsController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function index()
3434
public function view($id = null)
3535
{
3636
$project = $this->Projects->get($id, [
37-
'contain' => []
37+
'contain' => ['ProjectImages']
3838
]);
3939

4040
$this->set('project', $project);
@@ -72,7 +72,7 @@ public function add()
7272
public function edit($id = null)
7373
{
7474
$project = $this->Projects->get($id, [
75-
'contain' => []
75+
'contain' => ['ProjectImages']
7676
]);
7777
if ($this->request->is(['patch', 'post', 'put'])) {
7878
$project = $this->Projects->patchEntity($project, $this->request->data);

plugins/Showcase/src/Model/Table/ProjectsTable.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace Showcase\Model\Table;
33

4+
use Cake\Event\Event;
5+
use Cake\ORM\Entity;
46
use Cake\ORM\Query;
57
use Cake\ORM\RulesChecker;
68
use Cake\ORM\Table;
@@ -29,6 +31,16 @@ public function initialize(array $config)
2931
$this->primaryKey('id');
3032

3133
$this->addBehavior('Timestamp');
34+
35+
$this->hasMany('ProjectImages', [
36+
'joinType' => 'LEFT',
37+
'className' => 'AppImages',
38+
'foreignKey' => 'foreign_key',
39+
'dependent' => true,
40+
'conditions' => [
41+
'ProjectImages.model' => 'ProjectImages'
42+
]
43+
]);
3244
}
3345

3446
/**
@@ -63,4 +75,24 @@ public function validationDefault(Validator $validator)
6375

6476
return $validator;
6577
}
78+
79+
/**
80+
* beforeSave
81+
*
82+
* @param Event $event event
83+
* @param Entity $entity entity
84+
* @param array $options options
85+
* @return bool
86+
*/
87+
public function beforeSave(Event $event, Entity $entity, $options)
88+
{
89+
if (empty($entity['project_images'][0]['tmp_name'])) {
90+
//we don't want to save the slider_images when no image was updated in the form
91+
unset($entity['project_images']);
92+
}
93+
if (isset($entity['project_images'][0])) {
94+
$entity['project_images'][0]['model'] = 'ProjectImages';
95+
}
96+
return true;
97+
}
6698
}

plugins/Showcase/src/Template/Element/Projects/form.ctp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?= $this->Form->create($project) ?>
1+
<?= $this->Form->create($project, ['type' => 'file']) ?>
22
<?= $this->Form->hidden('id') ?>
33

44
<div class="well">
@@ -9,7 +9,22 @@
99
echo $this->Form->input('website', ['class' => 'form-control']);
1010
echo $this->Form->input('is_highlighted');
1111
echo $this->Form->input('is_showcase');
12+
echo $this->Form->input('project_images.file', [
13+
'type' => 'file',
14+
'label' => __d('Showcase', 'Image'),
15+
'multiple' => true,
16+
'id' => 'image-input'
17+
]);
1218
?>
19+
<div class="row">
20+
<div class="col-sm-12 col-md-8 col-lg-6" id="image-preview">
21+
<?php if (count($project->project_images)): ?>
22+
<?= $this->Image->display($project->project_images[0], null, [
23+
'style' => 'max-width:100%'
24+
]) ?>
25+
<?php endif; ?>
26+
</div>
27+
</div>
1328
</div>
1429
</div>
1530
</div>
@@ -20,3 +35,27 @@
2035
</div>
2136
</div>
2237
<?= $this->Form->end() ?>
38+
39+
<script type="text/javascript">
40+
document.getElementById('image-input').onchange = function (e) {
41+
var file = e.target.files[0],
42+
reader = new FileReader();
43+
44+
if (file) {
45+
reader.readAsDataURL(file);
46+
}
47+
48+
reader.onloadend = function () {
49+
var img = document.createElement('img');
50+
51+
img.src = reader.result;
52+
img.style.maxWidth = "100%";
53+
54+
img.onload = function () {
55+
var preview = document.getElementById('image-preview');
56+
preview.innerHTML = "";
57+
preview.appendChild(img);
58+
}
59+
}
60+
};
61+
</script>

src/Model/Table/AppImagesTable.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
namespace App\Model\Table;
3+
4+
use Cake\Event\Event;
5+
use Cake\Datasource\EntityInterface;
6+
use Cake\Filesystem\File;
7+
use Cake\ORM\Entity;
8+
use Cake\ORM\Table;
9+
use Burzum\FileStorage\Model\Table\ImageStorageTable;
10+
11+
class AppImagesTable extends ImageStorageTable {
12+
13+
/**
14+
* afterSave callback
15+
*
16+
* Does not call the parent to avoid that the regular file storage event listener saves the image already
17+
*
18+
* @param Event $event event
19+
* @param EntityInterface $entity entity
20+
* @param array $options options
21+
* @return bool
22+
*/
23+
public function afterSave(Event $event, EntityInterface $entity, $options)
24+
{
25+
if ($entity->isNew()) {
26+
if (empty($entity->tmp_name)) {
27+
return true;
28+
}
29+
$file = [
30+
'tmp_name' => $entity->tmp_name,
31+
];
32+
$entity->file = $file;
33+
$entity->filename = $entity['name'];
34+
$entity->filesize = $entity['size'];
35+
$file = new File($entity['name']);
36+
$entity->extension = $file->ext();
37+
$imageEvent = new Event('ImageStorage.afterSave', $this, [
38+
'storage' => $this->storageAdapter($entity['adapter']),
39+
'record' => $entity
40+
]);
41+
$this->eventManager()->dispatch($imageEvent);
42+
$this->_cleanupImages($entity);
43+
}
44+
return true;
45+
}
46+
47+
/**
48+
* Cleanup all the old images uploaded, keeping only the latest one after edit
49+
*
50+
* @param EntityInterface $entity entity
51+
* @return void
52+
*/
53+
protected function _cleanupImages($entity)
54+
{
55+
$oldImages = $this->find()
56+
->where([
57+
'id !=' => $entity['id'],
58+
'foreign_key' => $entity['foreign_key'],
59+
'model' => $entity['model'],
60+
]);
61+
$oldImages->each(function ($oldImage) {
62+
if (empty($oldImage['filename'])) {
63+
$this->deleteAll([
64+
'id' => $oldImage['id'],
65+
]);
66+
} else {
67+
$this->delete($oldImage);
68+
}
69+
});
70+
}
71+
72+
}

src/View/AppView.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ public function initialize()
3939
$this->loadHelper('Form', [
4040
'templates' => 'bootstrap_form'
4141
]);
42+
$this->loadHelper('Burzum/FileStorage.Image');
4243
}
4344
}

webroot/images

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../files/images

0 commit comments

Comments
 (0)