Skip to content

Commit

Permalink
NEW add geometrics extrafield (Dolibarr#28239)
Browse files Browse the repository at this point in the history
* add extrafield point

* wip

* wip

* wip

* input

* input

* output values

* update values

* update values

* update values

* update values

* update values

* wip

* add geomapeditor

* add geomapeditor

* add linestring and polygon

* add linestring and polygon

* add linestring and polygon

* add linestring and polygon

* wip

* wip

* can store and retrieve linestring

* can store and retrieve linestring

* coordinates are inverted

* coordinates are inverted

* add multipoints

* use text instead binary

* auto center map

* wip

wip

* doc

* fix

* wip

* wip

* translation dynamic

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
  • Loading branch information
frederic34 and eldy authored Apr 24, 2024
1 parent 26920d2 commit 7ea6a40
Show file tree
Hide file tree
Showing 51 changed files with 35,346 additions and 13 deletions.
4 changes: 4 additions & 0 deletions dev/translation/dynamic_translation_keys.lst
Original file line number Diff line number Diff line change
Expand Up @@ -3669,6 +3669,10 @@ EditWithEditor
ElementId
ElementType
ErrorABatchShouldNotContainsSpaces
ExtrafieldLinestringGeo
ExtrafieldMultiPointGeo
ExtrafieldPointGeo
ExtrafieldPolygonGeo
ImageGeneration
ModelTemplate
ModuleWebPortalDesc
Expand Down
4 changes: 2 additions & 2 deletions htdocs/core/actions_extrafields.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@

// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
$visibility = GETPOST('list', 'alpha');
if ($type == 'separate') {
if (in_array($type, ['separate', 'point', 'linestrg', 'polygon'])) {
$visibility = 3;
}

Expand Down Expand Up @@ -360,7 +360,7 @@

// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
$visibility = GETPOST('list', 'alpha');
if ($type == 'separate') {
if (in_array($type, ['separate', 'point', 'linestrg', 'polygon'])) {
$visibility = 3;
}

Expand Down
45 changes: 43 additions & 2 deletions htdocs/core/class/commonobject.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -6323,9 +6323,22 @@ public function fetch_optionals($rowid = null, $optionsArray = null)
if (is_array($optionsArray) && count($optionsArray) > 0) {
$sql = "SELECT rowid";
foreach ($optionsArray as $name => $label) {
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] != 'separate') {
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || (!in_array($extrafields->attributes[$this->table_element]['type'][$name], ['separate', 'point', 'multipts', 'linestrg','polygon']))) {
$sql .= ", ".$name;
}
// use geo sql fonction to read as text
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] == 'point') {
$sql .= ", ST_AsWKT(".$name.") as ".$name;
}
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] == 'multipts') {
$sql .= ", ST_AsWKT(".$name.") as ".$name;
}
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] == 'linestrg') {
$sql .= ", ST_AsWKT(".$name.") as ".$name;
}
if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] == 'polygon') {
$sql .= ", ST_AsWKT(".$name.") as ".$name;
}
}
$sql .= " FROM ".$this->db->prefix().$table_element."_extrafields";
$sql .= " WHERE fk_object = ".((int) $rowid);
Expand Down Expand Up @@ -6671,13 +6684,41 @@ public function insertExtraFields($trigger = '', $userused = null)
foreach ($new_array_options as $key => $value) {
$attributeKey = substr($key, 8); // Remove 'options_' prefix
// Add field of attribute
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') { // Only for other type than separator)
if (!in_array($extrafields->attributes[$this->table_element]['type'][$attributeKey], ['separate', 'point', 'multipts', 'linestrg', 'polygon'])) { // Only for other type than separator)
if ($new_array_options[$key] != '' || $new_array_options[$key] == '0') {
$sql .= ",'".$this->db->escape($new_array_options[$key])."'";
} else {
$sql .= ",null";
}
}
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'point') { // for point type
if (!empty($new_array_options[$key])) {
$sql .= ",ST_PointFromText('".$this->db->escape($new_array_options[$key])."')";
} else {
$sql .= ",null";
}
}
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'multipts') { // for point type
if (!empty($new_array_options[$key])) {
$sql .= ",ST_MultiPointFromText('".$this->db->escape($new_array_options[$key])."')";
} else {
$sql .= ",null";
}
}
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'linestrg') { // for linestring type
if (!empty($new_array_options[$key])) {
$sql .= ",ST_LineFromText('".$this->db->escape($new_array_options[$key])."')";
} else {
$sql .= ",null";
}
}
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'polygon') { // for polygon type
if (!empty($new_array_options[$key])) {
$sql .= ",ST_PolyFromText('".$this->db->escape($new_array_options[$key])."')";
} else {
$sql .= ",null";
}
}
}
// We must insert a default value for fields for other entities that are mandatory to avoid not null error
if (!empty($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities']) && is_array($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'])) {
Expand Down
81 changes: 75 additions & 6 deletions htdocs/core/class/extrafields.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Copyright (C) 2015-2023 Charlene BENKE <charlene@patas-monkey.com>
* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2017 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2018-2022 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2022 Antonin MARCHAL <antonin@letempledujeu.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
Expand Down Expand Up @@ -47,7 +47,7 @@ class ExtraFields
/**
* @var array<string,array{label:array<string,string>,type:array<string,string>,size:array<string,string>,default:array<string,string>,computed:array<string,string>,unique:array<string,int>,required:array<string,int>,param:array<string,mixed>,perms:array<string,mixed[]>,list:array<string,int|string>,pos:array<string,int>,totalizable:array<string,int>,help:array<string,string>,printable:array<string,int>,enabled:array<string,int>,langfile:array<string,string>,css:array<string,string>,csslist:array<string,string>,hidden:array<string,int>,mandatoryfieldsofotherentities:array<string,string>,loaded?:int,count:int}> New array to store extrafields definition Note: count set as present to avoid static analysis notices
*/
public $attributes;
public $attributes = array();

/**
* @var array<string,bool> Array with boolean of status of groups
Expand Down Expand Up @@ -96,6 +96,10 @@ class ExtraFields
'checkbox' => 'ExtrafieldCheckBox',
'chkbxlst' => 'ExtrafieldCheckBoxFromList',
'link' => 'ExtrafieldLink',
'point' => 'ExtrafieldPointGeo',
'multipts' => 'ExtrafieldMultiPointGeo',
'linestrg' => 'ExtrafieldLinestringGeo',
'polygon' => 'ExtrafieldPolygonGeo',
'separate' => 'ExtrafieldSeparator',
);

Expand All @@ -107,9 +111,6 @@ class ExtraFields
public function __construct($db)
{
$this->db = $db;
$this->error = '';
$this->errors = array();
$this->attributes = array();
}

/**
Expand Down Expand Up @@ -312,6 +313,18 @@ private function create($attrname, $type = 'varchar', $length = '255', $elementt
} elseif ($type == 'link') {
$typedb = 'int';
$lengthdb = '11';
} elseif ($type == 'point') {
$typedb = 'point';
$lengthdb = '';
} elseif ($type == 'multipts') {
$typedb = 'multipoint';
$lengthdb = '';
} elseif ($type == 'linestrg') {
$typedb = 'linestring';
$lengthdb = '';
} elseif ($type == 'polygon') {
$typedb = 'polygon';
$lengthdb = '';
} elseif ($type == 'html') {
$typedb = 'text';
$lengthdb = $length;
Expand Down Expand Up @@ -670,6 +683,18 @@ public function update($attrname, $label, $type, $length, $elementtype, $unique
} elseif ($type == 'link') {
$typedb = 'int';
$lengthdb = '11';
} elseif ($type == 'point') {
$typedb = 'point';
$lengthdb = '';
} elseif ($type == 'multipts') {
$typedb = 'multipoint';
$lengthdb = '';
} elseif ($type == 'linestrg') {
$typedb = 'linestring';
$lengthdb = '';
} elseif ($type == 'polygon') {
$typedb = 'polygon';
$lengthdb = '';
} elseif ($type == 'password') {
$typedb = 'varchar';
$lengthdb = '128';
Expand Down Expand Up @@ -1686,6 +1711,24 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $

//$out = $form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, '', 0, 0, '');
$out = $form->selectForForms($tmparray[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, '', 0, 0, '', $element.':options_'.$key);
} elseif (in_array($type, ['point', 'multipts', 'linestrg', 'polygon'])) {
require_once DOL_DOCUMENT_ROOT.'/includes/geoPHP/geoPHP.inc.php';
$geojson = '{}';
$centroidjson = getDolGlobalString('MAIN_INFO_SOCIETE_GEO_COORDINATES', '{}');
if (!empty($value)) {
$geom = geoPHP::load($value, 'wkt');
$geojson = $geom->out('json');
$centroid = $geom->getCentroid();
$centroidjson = $centroid->out('json');
}
if (!preg_match('/search_/', $keyprefix)) {
require_once DOL_DOCUMENT_ROOT.'/core/class/geomapeditor.class.php';
$geomapeditor = new GeoMapEditor();
$out .= $geomapeditor->getHtml($keyprefix.$key.$keysuffix, $geojson, $centroidjson, $type);
} else {
// If keyprefix is search_ or search_options_, we must just use a simple text field
$out = ''; // @phan-suppress-current-line PhanPluginRedundantAssignment
}
} elseif ($type == 'password') {
// If prefix is 'search_', field is used as a filter, we use a common text field.
$out = '<input style="display:none" type="text" name="fakeusernameremembered">'; // Hidden field to reduce impact of evil Google Chrome autopopulate bug.
Expand Down Expand Up @@ -2050,6 +2093,22 @@ public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjec
return 'Error bad setup of extrafield';
}
}
} elseif ($type == 'point') {
require_once DOL_DOCUMENT_ROOT.'/includes/geoPHP/geoPHP.inc.php';
if (!empty($value)) {
$geom = geoPHP::load($value, 'wkt');
$value = $geom->x().' '.$geom->y();
} else {
$value = '';
}
} elseif (in_array($type, ['multipts','linestrg', 'polygon'])) {
require_once DOL_DOCUMENT_ROOT.'/includes/geoPHP/geoPHP.inc.php';
if (!empty($value)) {
$geom = geoPHP::load($value, 'wkt');
$value = get_class($geom) . ' : '. $geom->numPoints() . ' Points';
} else {
$value = '';
}
} elseif ($type == 'text') {
$value = dol_htmlentitiesbr($value);
} elseif ($type == 'html') {
Expand Down Expand Up @@ -2233,7 +2292,7 @@ public function setOptionalsFromPost($extralabels, &$object, $onlykey = '', $tod
continue;
}

if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && (! in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'checkbox', 'chkbxlst')))) {
if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && (! in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'checkbox', 'chkbxlst', 'point', 'multipts', 'linestrg', 'polygon')))) {
//when unticking boolean field, it's not set in POST
continue;
}
Expand Down Expand Up @@ -2319,6 +2378,16 @@ public function setOptionalsFromPost($extralabels, &$object, $onlykey = '', $tod
$value_key = price2num(GETPOST("options_".$key, 'alpha')).':'.GETPOST("options_".$key."currency_id", 'alpha');
} elseif (in_array($key_type, array('html'))) {
$value_key = GETPOST("options_".$key, 'restricthtml');
} elseif (in_array($key_type, ['point', 'multipts', 'linestrg', 'polygon'])) {
// construct point
require_once DOL_DOCUMENT_ROOT.'/includes/geoPHP/geoPHP.inc.php';
$geojson = GETPOST("options_".$key, 'restricthtml');
if ($geojson != '{}') {
$geom = geoPHP::load($geojson, 'json');
$value_key = $geom->out('wkt');
} else {
$value_key = '';
}
} elseif (in_array($key_type, array('text'))) {
$label_security_check = 'alphanohtml';
// by default 'alphanohtml' (better security); hidden conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML allows basic html
Expand Down
Loading

0 comments on commit 7ea6a40

Please sign in to comment.