Skip to content

Commit

Permalink
1141 image par défaut dans les formulaires bazar (#1143)
Browse files Browse the repository at this point in the history
* add default image select in image component

* extract from forumlar & save default image in jpg file

* use default image if need in bazar item

* remove default image & refresh it

* fix(imageField): declare new properties to avoid deprecated errors

* create style class for remove button default image + rename PHP method (camelCase) + check max size of default image

* Update tools/bazar/presentation/javascripts/form-edit-template/fields/image.js

Co-authored-by: Jérémy Dufraisse <jeremy.dufraisse-info@orange.fr>

* Update tools/bazar/fields/ImageField.php

Co-authored-by: Jérémy Dufraisse <jeremy.dufraisse-info@orange.fr>

---------

Co-authored-by: Florian Schmitt <mrflos@gmail.com>
Co-authored-by: Jérémy Dufraisse <jeremy.dufraisse-info@orange.fr>
  • Loading branch information
3 people committed May 10, 2024
1 parent 75f0af4 commit 2c0a809
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 41 deletions.
27 changes: 16 additions & 11 deletions includes/services/DbService.php
Expand Up @@ -65,6 +65,14 @@ public function getQueryLog()
return $this->queryLog;
}

public function addQueryLog($query, $time)
{
$this->queryLog[] = array(
'query' => $query,
'time' => $time
);
}

public function prefixTable($tableName)
{
return ' ' . $this->params->get('table_prefix') . $tableName . ' ';
Expand All @@ -87,18 +95,15 @@ public function query($query)
$start = $this->getMicroTime();
}

if (!$result = mysqli_query($this->link, $query)) {
throw new Exception('Query failed: ' . $query . ' (' . mysqli_error($this->link) . ')');
}

if ($this->params->get('debug')) {
$time = $this->getMicroTime() - $start;
$this->queryLog[] = array(
'query' => $query,
'time' => $time
);
try {
if (!$result = mysqli_query($this->link, $query)) {
throw new Exception('Query failed: ' . $query . ' (' . mysqli_error($this->link) . ')');
}
} finally {
if ($this->params->get('debug')) {
$this->addQueryLog($query, $this->getMicroTime() - $start);
}
}

return $result;
}

Expand Down
10 changes: 9 additions & 1 deletion tools/bazar/fields/ImageField.php
Expand Up @@ -17,12 +17,14 @@ class ImageField extends FileField
protected $imageHeight;
protected $imageWidth;
protected $imageClass;
protected $imageDefault;

protected const FIELD_THUMBNAIL_HEIGHT = 3;
protected const FIELD_THUMBNAIL_WIDTH = 4;
protected const FIELD_IMAGE_HEIGHT = 5;
protected const FIELD_IMAGE_WIDTH = 6;
protected const FIELD_IMAGE_CLASS = 7;
protected const FIELD_IMAGE_DEFAULT = 13;

public function __construct(array $values, ContainerInterface $services)
{
Expand All @@ -34,6 +36,7 @@ public function __construct(array $values, ContainerInterface $services)
$this->imageHeight = $values[self::FIELD_IMAGE_HEIGHT];
$this->imageWidth = $values[self::FIELD_IMAGE_WIDTH];
$this->imageClass = $values[self::FIELD_IMAGE_CLASS];
$this->imageDefault = $values[self::FIELD_IMAGE_DEFAULT];

// We can have no default for images
$this->default = null;
Expand Down Expand Up @@ -162,7 +165,12 @@ public function formatValuesBeforeSave($entry)
protected function renderStatic($entry)
{
$value = $this->getValue($entry);

if (!isset($value) || $value == '') {
$default_image_filename = "defaultimage{$entry['id_typeannonce']}_{$this->name}.jpg";
if (file_exists($this->getBasePath(). $default_image_filename)) {
$value=$default_image_filename;
}
}
if (isset($value) && $value != '' && file_exists($this->getBasePath(). $value)) {
return $this->getWiki()->render('@attach/display-image.twig', [
'baseUrl' => $this->getWiki()->GetBaseUrl().'/',
Expand Down
1 change: 1 addition & 0 deletions tools/bazar/lang/bazarjs_en.inc.php
Expand Up @@ -133,6 +133,7 @@
// 'BAZ_FORM_EDIT_IMAGE_WIDTH' => 'Largeur Vignette',
// 'BAZ_FORM_EDIT_IMAGE_WIDTH_RESIZE' => 'Largeur redimension',
// 'BAZ_FORM_EDIT_IMAGE_HEIGHT_RESIZE' => 'Hauteur redimension',
'BAZ_FORM_EDIT_IMAGE_DEFAULT' => 'Default image',
'BAZ_FORM_EDIT_METADATA_THEME_LABEL' => 'Theme name',
'BAZ_FORM_EDIT_METADATA_SQUELETON_LABEL' => 'Squeleton',
'BAZ_FORM_EDIT_METADATA_STYLE_LABEL' => 'Style',
Expand Down
1 change: 1 addition & 0 deletions tools/bazar/lang/bazarjs_fr.inc.php
Expand Up @@ -133,6 +133,7 @@
'BAZ_FORM_EDIT_IMAGE_WIDTH' => 'Largeur vignette',
'BAZ_FORM_EDIT_IMAGE_WIDTH_RESIZE' => 'Largeur redimension',
'BAZ_FORM_EDIT_IMAGE_HEIGHT_RESIZE' => 'Hauteur redimension',
'BAZ_FORM_EDIT_IMAGE_DEFAULT' => 'Image par défaut',
'BAZ_FORM_EDIT_METADATA_THEME_LABEL' => 'Nom du thème',
'BAZ_FORM_EDIT_METADATA_SQUELETON_LABEL' => 'Squelette',
'BAZ_FORM_EDIT_METADATA_STYLE_LABEL' => 'Style',
Expand Down
Expand Up @@ -15,9 +15,16 @@ export default {
resize_height: { label: _t('BAZ_FORM_EDIT_IMAGE_HEIGHT_RESIZE'), value: '600' },
resize_width: { label: _t('BAZ_FORM_EDIT_IMAGE_WIDTH_RESIZE'), value: '800' },
align: {
label: _t('BAZ_FORM_EDIT_IMAGE_ALIGN_LABEL'),
value: 'right',
options: { left: _t('LEFT'), right: _t('RIGHT') }
label: _t("BAZ_FORM_EDIT_IMAGE_ALIGN_LABEL"),
value: "right",
options: { left: _t("LEFT"), right: _t("RIGHT") },
},
default_image: {
label: _t("BAZ_FORM_EDIT_IMAGE_DEFAULT"),
class: "default-file",
value: "",
type: "file",
accept: "image/*",
},
maxsize: { label: _t('BAZ_FORM_EDIT_FILE_MAXSIZE_LABEL'), value: '' },
read: readConf,
Expand All @@ -29,12 +36,13 @@ export default {
attributesMapping: {
...defaultMapping,
...{
1: 'name',
3: 'thumb_height',
4: 'thumb_width',
5: 'resize_height',
6: 'resize_width',
7: 'align',
1: "name",
3: "thumb_height",
4: "thumb_width",
5: "resize_height",
6: "resize_width",
7: "align",
13: "default_image",
14: 'maxsize'
}
},
Expand Down
Expand Up @@ -69,3 +69,20 @@ export function adjustJqueryBuilderUI($field) {
$field.find('a[type=copy].formbuilder-icon-copy').attr('title', _t('DUPLICATE'))
$field.find('a[type=edit].formbuilder-icon-pencil').attr('title', _t('BAZ_FORM_EDIT_HIDE'))
}

export function convertToBytes(base64content) {
const byteCharacters = base64content;
const sliceSize = 512;
var byteNumbers;
var slice;
const byteArrays = new [].constructor();
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new [].constructor(slice.length);
for (var idx = 0; idx < slice.length; idx++) {
byteNumbers[idx] = slice.charCodeAt(idx);
}
byteArrays.push(new Uint8Array(byteNumbers));
}
return byteArrays;
}
Expand Up @@ -31,13 +31,15 @@ import {
mapFieldsConf,
addAdvancedAttributesSection,
adjustDefaultAcls,
adjustJqueryBuilderUI
adjustJqueryBuilderUI,
convertToBytes
} from './form-builder-helper.js'
import { initListOrFormIdAttribute } from './attributes/list-form-id-attribute.js'
import I18nOption from './i18n.js'

const $formBuilderTextInput = $('#form-builder-text')
window.formBuilder = undefined
window.defaultImage = {}

// Use window to make it available outside of module, so extension can adds their own fields
window.formBuilderFields = {
Expand Down Expand Up @@ -120,7 +122,51 @@ function initializeFormbuilder() {
}
})
}, 0)
}
},
onOpenFieldEdit() {
// Default image is in base64 in buffer variable => convert it to File in input element
$('input.default-file').each((idx, file_elem) => {
const current_ids = file_elem.attributes.id.value.split('-')
const image_name = current_ids[current_ids.length - 2] + '-' + current_ids[current_ids.length - 1]
if (window.defaultImage[image_name]) {
const image_content = window.defaultImage[image_name].split('|')
if (image_content.length === 2) {
const dataTransfer = new DataTransfer()
dataTransfer.items.add(new File(convertToBytes(image_content[1]), image_content[0]))
file_elem.files = dataTransfer.files
}
}
if (file_elem.parentElement.childElementCount == 1) {
const new_button = document.createElement("i")
new_button.className = "fas fa-remove btn-img-remove"
new_button.onclick = function() {
file_elem.files = new DataTransfer().files
window.defaultImage[image_name] = ''
}
file_elem.parentElement.append(new_button)
}
})
// When change image, save it to base64 to buffer variable
$('input.default-file').change((event) => {

const current_ids = event.target.attributes.id.value.split('-')
const image_name = current_ids[current_ids.length - 2] + '-' + current_ids[current_ids.length - 1]
const file = event.target.files[0]
if (typeof imageMaxSize == 'undefined') {
var imageMaxSize = 1024 * 1024;
}
if(file.size > imageMaxSize) {
alert(_t('IMAGEFIELD_TOO_LARGE_IMAGE', { imageMaxSize }))
event.target.value = "";
return false
}
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function () {
window.defaultImage[image_name] = file.name + '|' + reader.result
}
})
},
})

const defaultFieldsName = mapFieldsConf((conf) => conf.defaultIdentifier)
Expand Down Expand Up @@ -153,6 +199,14 @@ function initializeFormbuilder() {
// Update the text field converting form builder content into wiki syntax
if ($('#form-builder-container').is(':visible')) {
const formData = formBuilder.actions.getData()
// save base64 default image from buffer variable
Object.keys(window.defaultImage).forEach((image_name) => {
if (window.defaultImage[image_name] && window.defaultImage[image_name] != '') {
const image_names = image_name.split('-')
const field_idx = Number(image_names[image_names.length - 1]) - 1
formData[field_idx].default_image = window.defaultImage[image_name]
}
})
const wikiText = formatJsonDataIntoWikiText(formData)
if (wikiText) $formBuilderTextInput.val(wikiText)
}
Expand Down Expand Up @@ -251,6 +305,13 @@ function getFieldsIds() {
function initializeBuilderFromTextInput() {
const jsonData = parseWikiTextIntoJsonData($formBuilderTextInput.val())
try {
window.defaultImage = {}
// extract base64 default image to buffer variable
jsonData.forEach((field, index) => {
if (field.type === 'image') {
window.defaultImage['fld-' + (index + 1)] = field.default_image.trim()
}
})
formBuilder.actions.setData(JSON.stringify(jsonData))
} catch (error) {
console.error(error)
Expand Down
11 changes: 10 additions & 1 deletion tools/bazar/presentation/styles/form-edit-template.css
Expand Up @@ -235,4 +235,13 @@ xmp { overflow: auto; }
.form-group.autocomplete_other-wrap {
display: none;
}


.btn-img-remove {
display: block;
position: relative;
top: -26px;
width: 20px;
margin-left: auto;
margin-right: 0;
cursor: pointer;
}
33 changes: 33 additions & 0 deletions tools/bazar/services/BazarListService.php
Expand Up @@ -2,6 +2,7 @@

namespace YesWiki\Bazar\Service;

use Attach;
use YesWiki\Bazar\Controller\EntryController;
use YesWiki\Wiki;
use YesWiki\Bazar\Field\BazarField;
Expand Down Expand Up @@ -41,6 +42,37 @@ public function getForms($options): array
return $this->formManager->getAll();
}
}

private function replaceDefaultImage($options, $forms, $entries): array {
if (! class_exists('attach')) {
include ('tools/attach/libs/attach.lib.php');
}
$attach = new attach($this->wiki);
$basePath = $attach->GetUploadPath();
$basePath = $basePath . (substr($basePath, - 1) != "/" ? "/" : "");

foreach($options['idtypeannonce'] as $idtypeannonce) {
$template = $forms[(int)$idtypeannonce]['template'];
$image_names = array_map(function($item) {return $item[1];},
array_filter($template,
function($item) { return $item[0] == 'image'; }
)
);
foreach($image_names as $image_name) {
$default_image_filename = "defaultimage{$idtypeannonce}_{$image_name}.jpg";
if (file_exists($basePath.$default_image_filename)) {
$image_key = 'image'.$image_name;
foreach($entries as $key=>$entry) {
if (array_key_exists($image_key, $entry) && ($entry[$image_key] == null)) {
$entry[$image_key] = $default_image_filename;
}
$entries[$key] = $entry;
}
}
}
}
return $entries;
}

public function getEntries($options, $forms = null): array
{
Expand Down Expand Up @@ -71,6 +103,7 @@ public function getEntries($options, $forms = null): array
true // use Guard
);
}
$entries = $this->replaceDefaultImage($options, $forms, $entries);

// filter entries on datefilter parameter
if (!empty($options['datefilter'])) {
Expand Down

0 comments on commit 2c0a809

Please sign in to comment.