Add image file to battery, update cleanup task for orphaned images
This commit is contained in:
parent
74b696099c
commit
884cd7b7f1
9 changed files with 152 additions and 29 deletions
|
|
@ -9,6 +9,11 @@ battery_rows:
|
|||
controller: App\Controller\BatteryController::rows
|
||||
methods: [POST]
|
||||
|
||||
battery_upload_image:
|
||||
path: /batteries/upload
|
||||
controller: App\Controller\BatteryController::uploadImage
|
||||
methods: [POST]
|
||||
|
||||
battery_create:
|
||||
path: /batteries/create
|
||||
controller: App\Controller\BatteryController::addForm
|
||||
|
|
|
|||
BIN
public/assets/images/battery.gif
Normal file
BIN
public/assets/images/battery.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
|
|
@ -10,6 +10,7 @@ use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
|
|||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use App\Entity\Rider;
|
||||
use App\Entity\Battery;
|
||||
use App\Service\FileUploader;
|
||||
|
||||
use DirectoryIterator;
|
||||
|
|
@ -41,12 +42,26 @@ class UploadCleanupCommand extends Command
|
|||
|
||||
// get all image filenames
|
||||
$em = $this->object_manager;
|
||||
$rows = $em->getRepository(Rider::class)->findAll();
|
||||
|
||||
$riders = $em->getRepository(Rider::class)->findAll();
|
||||
$whitelist = ['.gitkeep'];
|
||||
|
||||
if (!empty($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$image = $row->getImageFile();
|
||||
if (!empty($riders)) {
|
||||
foreach ($riders as $obj) {
|
||||
$image = $obj->getImageFile();
|
||||
|
||||
if (!empty($image)) {
|
||||
$whitelist[] = $image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$batteries = $em->getRepository(Battery::class)->findAll();
|
||||
$whitelist = ['.gitkeep'];
|
||||
|
||||
if (!empty($batteries)) {
|
||||
foreach ($batteries as $obj) {
|
||||
$image = $obj->getImageFile();
|
||||
|
||||
if (!empty($image)) {
|
||||
$whitelist[] = $image;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use App\Entity\BatteryModel;
|
|||
use App\Entity\BatterySize;
|
||||
use App\Entity\Vehicle;
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Service\FileUploader;
|
||||
|
||||
use Doctrine\ORM\Query;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
|
@ -123,6 +124,7 @@ class BatteryController extends BaseController
|
|||
$row['width'] = $orow[0]->getWidth();
|
||||
$row['height'] = $orow[0]->getHeight();
|
||||
$row['total_height'] = $orow[0]->getTotalHeight();
|
||||
$row['image_file'] = $orow[0]->getImageFile();
|
||||
|
||||
// add row metadata
|
||||
$row['meta'] = [
|
||||
|
|
@ -183,7 +185,8 @@ class BatteryController extends BaseController
|
|||
->setWidth($req->request->get('width'))
|
||||
->setHeight($req->request->get('height'))
|
||||
->setTotalHeight($req->request->get('total_height'))
|
||||
->setSellingPrice($req->request->get('sell_price'));
|
||||
->setSellingPrice($req->request->get('sell_price'))
|
||||
->setImageFile($req->request->get('image_file'));
|
||||
|
||||
// initialize error list
|
||||
$error_array = [];
|
||||
|
|
@ -304,6 +307,7 @@ class BatteryController extends BaseController
|
|||
->setHeight($req->request->get('height'))
|
||||
->setTotalHeight($req->request->get('total_height'))
|
||||
->setSellingPrice($req->request->get('sell_price'))
|
||||
->setImageFile($req->request->get('image_file'))
|
||||
->clearVehicles();
|
||||
|
||||
// initialize error list
|
||||
|
|
@ -398,6 +402,21 @@ class BatteryController extends BaseController
|
|||
$response->send();
|
||||
}
|
||||
|
||||
public function uploadImage(Request $req, FileUploader $uploader)
|
||||
{
|
||||
// retrieve temporary info for file
|
||||
$file = $req->files->get('image_file');
|
||||
|
||||
// upload the file
|
||||
$filename = $uploader->upload($file);
|
||||
|
||||
// return response
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'filename' => $filename
|
||||
]);
|
||||
}
|
||||
|
||||
// check if datatable filter is present and append to query
|
||||
protected function setQueryFilters($datatable, &$query) {
|
||||
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ class RiderController extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
public function updateForm(FileUploader $uploader, $id)
|
||||
public function updateForm($id)
|
||||
{
|
||||
$this->denyAccessUnlessGranted('rider.update', null, 'No access.');
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,11 @@ class Battery
|
|||
*/
|
||||
protected $sell_price;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $image_file;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->vehicles = new ArrayCollection();
|
||||
|
|
@ -299,4 +304,15 @@ class Battery
|
|||
{
|
||||
return $this->cust_vehicles;
|
||||
}
|
||||
|
||||
public function setImageFile($image_file)
|
||||
{
|
||||
$this->image_file = $image_file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImageFile()
|
||||
{
|
||||
return $this->image_file;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
<h3 class="m-portlet__head-text">
|
||||
{% if mode == 'update' %}
|
||||
Edit Battery
|
||||
<small>{{ obj.getProductCode() }}</small>
|
||||
<small>{{ obj.getProductCode }}</small>
|
||||
{% else %}
|
||||
New Battery
|
||||
{% endif %}
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right" method="post" action="{{ mode == 'update' ? url('battery_update_submit', {'id': obj.getId()}) : url('battery_create_submit') }}">
|
||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right" method="post" action="{{ mode == 'update' ? url('battery_update_submit', {'id': obj.getID }) : url('battery_create_submit') }}">
|
||||
<div class="m-portlet__body">
|
||||
<div class="m-form__section m-form__section--first">
|
||||
<div class="m-form__heading">
|
||||
|
|
@ -45,14 +45,14 @@
|
|||
<label data-field="prod_code">
|
||||
Product Code
|
||||
</label>
|
||||
<input type="text" name="prod_code" class="form-control m-input" value="{{ obj.getProductCode() }}">
|
||||
<input type="text" name="prod_code" class="form-control m-input" value="{{ obj.getProductCode }}">
|
||||
<div class="form-control-feedback hide" data-field="prod_code"></div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<label data-field="sell_price">
|
||||
Selling Price
|
||||
</label>
|
||||
<input type="text" name="sell_price" class="form-control m-input" value="{{ obj.getSellingPrice() }}">
|
||||
<input type="text" name="sell_price" class="form-control m-input" value="{{ obj.getSellingPrice }}">
|
||||
<div class="form-control-feedback hide" data-field="sell_price"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
<select class="form-control m-input" id="manufacturer" name="manufacturer">
|
||||
<option value=""></option>
|
||||
{% for manufacturer in bmfgs %}
|
||||
<option value="{{ manufacturer.getID() }}"{{ obj.getManufacturer() and manufacturer.getID() == obj.getManufacturer().getID() ? ' selected' }}>{{ manufacturer.getName() }}</option>
|
||||
<option value="{{ manufacturer.getID }}"{{ obj.getManufacturer and manufacturer.getID == obj.getManufacturer.getID ? ' selected' }}>{{ manufacturer.getName }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="manufacturer"></div>
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
<select class="form-control m-input" id="model" name="model">
|
||||
<option value=""></option>
|
||||
{% for model in models %}
|
||||
<option value="{{ model.getID() }}"{{ obj.getModel() and obj.getModel().getID() ? ' selected' }}>{{ model.getName() }}</option>
|
||||
<option value="{{ model.getID }}"{{ obj.getModel and obj.getModel.getID ? ' selected' }}>{{ model.getName }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="model"></div>
|
||||
|
|
@ -88,12 +88,43 @@
|
|||
<select class="form-control m-input" id="size" name="size">
|
||||
<option value=""></option>
|
||||
{% for size in sizes %}
|
||||
<option value="{{ size.getID() }}"{{ obj.getSize() and obj.getSize().getID() ? ' selected' }}>{{ size.getName() }}</option>
|
||||
<option value="{{ size.getID }}"{{ obj.getSize and obj.getSize.getID ? ' selected' }}>{{ size.getName }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="size"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="image_file">
|
||||
{% if mode == 'update' and obj.getImageFile %}
|
||||
Replace Picture
|
||||
{% else %}
|
||||
Picture
|
||||
{% endif %}
|
||||
</label>
|
||||
<div class="m-dropzone dropzone m-dropzone--primary" action="{{ url('battery_upload_image') }}" id="image-file">
|
||||
<div class="m-dropzone__msg dz-message needsclick">
|
||||
<h3 class="m-dropzone__msg-title">
|
||||
Drop files here or click to upload.
|
||||
</h3>
|
||||
<span class="m-dropzone__msg-desc">
|
||||
Upload only valid PNG, GIF, or JPEG images
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if mode == 'update' and obj.getImageFile %}
|
||||
<span class="m-form__help">Leave blank for unchanged</span>
|
||||
{% endif %}
|
||||
<div class="form-control-feedback hide" data-field="image_file"></div>
|
||||
</div>
|
||||
{% if mode == 'update' %}
|
||||
<div class="col-lg-6">
|
||||
<label> </label>
|
||||
<div class="portrait-box" style="background-image: url('{{ obj.getImageFile ? '/uploads/' ~ obj.getImageFile : '/assets/images/battery.gif' }}');"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-form__seperator m-form__seperator--dashed"></div>
|
||||
<div class="m-form__section">
|
||||
|
|
@ -107,7 +138,7 @@
|
|||
<label data-field="warr_private">
|
||||
Personal
|
||||
</label>
|
||||
<input type="number" name="warr_private" class="form-control m-input" value="{{ obj.getWarrantyPrivate() }}">
|
||||
<input type="number" name="warr_private" class="form-control m-input" value="{{ obj.getWarrantyPrivate }}">
|
||||
<div class="form-control-feedback hide" data-field="warr_private"></div>
|
||||
<span class="m-form__help">In months</span>
|
||||
</div>
|
||||
|
|
@ -115,7 +146,7 @@
|
|||
<label data-field="warr_commercial">
|
||||
Commercial
|
||||
</label>
|
||||
<input type="number" name="warr_commercial" class="form-control m-input" value="{{ obj.getWarrantyCommercial() }}">
|
||||
<input type="number" name="warr_commercial" class="form-control m-input" value="{{ obj.getWarrantyCommercial }}">
|
||||
<div class="form-control-feedback hide" data-field="warr_commercial"></div>
|
||||
<span class="m-form__help">In months</span>
|
||||
</div>
|
||||
|
|
@ -133,7 +164,7 @@
|
|||
<label data-field="length">
|
||||
Length
|
||||
</label>
|
||||
<input type="number" name="length" class="form-control m-input" value="{{ obj.getLength() }}">
|
||||
<input type="number" name="length" class="form-control m-input" value="{{ obj.getLength }}">
|
||||
<div class="form-control-feedback hide" data-field="length"></div>
|
||||
<span class="m-form__help">In millimeters (mm)</span>
|
||||
</div>
|
||||
|
|
@ -141,7 +172,7 @@
|
|||
<label data-field="width">
|
||||
Width
|
||||
</label>
|
||||
<input type="number" name="width" class="form-control m-input" value="{{ obj.getWidth() }}">
|
||||
<input type="number" name="width" class="form-control m-input" value="{{ obj.getWidth }}">
|
||||
<div class="form-control-feedback hide" data-field="width"></div>
|
||||
<span class="m-form__help">In millimeters (mm)</span>
|
||||
</div>
|
||||
|
|
@ -149,7 +180,7 @@
|
|||
<label data-field="height">
|
||||
Height
|
||||
</label>
|
||||
<input type="number" name="height" class="form-control m-input" value="{{ obj.getHeight() }}">
|
||||
<input type="number" name="height" class="form-control m-input" value="{{ obj.getHeight }}">
|
||||
<div class="form-control-feedback hide" data-field="height"></div>
|
||||
<span class="m-form__help">In millimeters (mm)</span>
|
||||
</div>
|
||||
|
|
@ -159,7 +190,7 @@
|
|||
<label data-field="total_height">
|
||||
Total Height
|
||||
</label>
|
||||
<input type="number" name="total_height" class="form-control m-input" value="{{ obj.getTotalHeight() }}">
|
||||
<input type="number" name="total_height" class="form-control m-input" value="{{ obj.getTotalHeight }}">
|
||||
<div class="form-control-feedback hide" data-field="total_height"></div>
|
||||
<span class="m-form__help">In millimeters (mm)</span>
|
||||
</div>
|
||||
|
|
@ -167,7 +198,7 @@
|
|||
<label data-field="res_capacity">
|
||||
Reserve Capacity
|
||||
</label>
|
||||
<input type="number" name="res_capacity" class="form-control m-input" value="{{ obj.getReserveCapacity() }}">
|
||||
<input type="number" name="res_capacity" class="form-control m-input" value="{{ obj.getReserveCapacity }}">
|
||||
<div class="form-control-feedback hide" data-field="res_capacity"></div>
|
||||
<span class="m-form__help">In minutes</span>
|
||||
</div>
|
||||
|
|
@ -193,7 +224,7 @@
|
|||
<select name="vmfg_list" class="form-control m-input" id="vmfg">
|
||||
<option value="">Select a manufacturer</option>
|
||||
{% for manufacturer in vmfgs %}
|
||||
<option value="{{ manufacturer.getID() }}">{{ manufacturer.getName() }}</option>
|
||||
<option value="{{ manufacturer.getID }}">{{ manufacturer.getName }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
|
@ -212,6 +243,7 @@
|
|||
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<input type="hidden" name="image_file" value="{{ obj.getImageFile }}">
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
<a href="{{ url('battery_list') }}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
|
|
@ -227,6 +259,31 @@
|
|||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// image upload
|
||||
Dropzone.options.imageFile = {
|
||||
paramName: "image_file", // The name that will be used to transfer the file
|
||||
maxFiles: 1,
|
||||
uploadMultiple: false,
|
||||
maxFilesize: 5, // MB
|
||||
addRemoveLinks: true,
|
||||
acceptedFiles: "image/*",
|
||||
accept: function(file, done) {
|
||||
done();
|
||||
},
|
||||
init: function() {
|
||||
this.on("maxfilesexceeded", function(file) {
|
||||
// limit to one file, overwrite old one
|
||||
this.removeAllFiles();
|
||||
this.addFile(file);
|
||||
});
|
||||
},
|
||||
success: function(file, response) {
|
||||
if (response.success) {
|
||||
$("input[name='image_file']").val(response.filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$(function() {
|
||||
$("#row-form").submit(function(e) {
|
||||
var form = $(this);
|
||||
|
|
@ -310,15 +367,15 @@
|
|||
|
||||
{% for vehicle in obj.getVehicles() %}
|
||||
vrow = {
|
||||
id: "{{ vehicle.getID() }}",
|
||||
mfg_name: "{{ vehicle.getManufacturer().getName() }}",
|
||||
make: "{{ vehicle.getMake() }}",
|
||||
model_year_from: "{{ vehicle.getModelYearFrom() }}",
|
||||
model_year_to: "{{ vehicle.getModelYearTo() }}"
|
||||
id: "{{ vehicle.getID }}",
|
||||
mfg_name: "{{ vehicle.getManufacturer.getName }}",
|
||||
make: "{{ vehicle.getMake }}",
|
||||
model_year_from: "{{ vehicle.getModelYearFrom }}",
|
||||
model_year_to: "{{ vehicle.getModelYearTo }}"
|
||||
};
|
||||
|
||||
vehicleRows.push(vrow);
|
||||
vehicleIds.push("{{ vehicle.getID() }}");
|
||||
vehicleIds.push("{{ vehicle.getID }}");
|
||||
{% endfor %}
|
||||
|
||||
// update vehicle list when changing manufacturer
|
||||
|
|
|
|||
|
|
@ -83,6 +83,17 @@
|
|||
title: 'ID',
|
||||
width: 30
|
||||
},
|
||||
{
|
||||
field: 'image_file',
|
||||
title: '',
|
||||
sortable: false,
|
||||
width: 40,
|
||||
template: function (row, index, datatable) {
|
||||
var html = '<div class="user-portrait-sm" style="background-image: url(\'' + (row.image_file ? "/uploads/" + row.image_file : "/assets/images/battery.gif") + '\');"></div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
/*
|
||||
{
|
||||
field: 'mfg_name',
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="image_file">
|
||||
{% if mode == 'update' %}
|
||||
{% if mode == 'update' and obj.getImageFile %}
|
||||
Replace Picture
|
||||
{% else %}
|
||||
Picture
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if mode == 'update' %}
|
||||
{% if mode == 'update' and obj.getImageFile %}
|
||||
<span class="m-form__help">Leave blank for unchanged</span>
|
||||
{% endif %}
|
||||
<div class="form-control-feedback hide" data-field="image_file"></div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue