dolibarr 18.0.9
customreports.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2020-2023 Laurent Destailleur <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 *
17 * Note: This tool can be included into a list page with :
18 * define('USE_CUSTOM_REPORT_AS_INCLUDE', 1);
19 * include DOL_DOCUMENT_ROOT.'/core/customreports.php';
20 */
21
28if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
29 require '../main.inc.php';
30
31 // Get parameters
32 $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
33 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
34
35 $mode = GETPOST('mode', 'alpha') ? GETPOST('mode', 'alpha') : 'graph';
36 $objecttype = GETPOST('objecttype', 'aZ09');
37 $tabfamily = GETPOST('tabfamily', 'aZ09');
38
39 if (empty($objecttype)) {
40 $objecttype = 'thirdparty';
41 }
42
43 $search_measures = GETPOST('search_measures', 'array');
44
45 //$search_xaxis = GETPOST('search_xaxis', 'array');
46 if (GETPOST('search_xaxis', 'alpha') && GETPOST('search_xaxis', 'alpha') != '-1') {
47 $search_xaxis = array(GETPOST('search_xaxis', 'alpha'));
48 } else {
49 $search_xaxis = array();
50 }
51 //$search_groupby = GETPOST('search_groupby', 'array');
52 if (GETPOST('search_groupby', 'alpha') && GETPOST('search_groupby', 'alpha') != '-1') {
53 $search_groupby = array(GETPOST('search_groupby', 'alpha'));
54 } else {
55 $search_groupby = array();
56 }
57
58 $search_yaxis = GETPOST('search_yaxis', 'array');
59 $search_graph = GETPOST('search_graph', 'restricthtml');
60
61 // Load variable for pagination
62 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
63 $sortfield = GETPOST('sortfield', 'aZ09comma');
64 $sortorder = GETPOST('sortorder', 'aZ09comma');
65 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
66 if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
67 $page = 0;
68 } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
69 $offset = $limit * $page;
70 $pageprev = $page - 1;
71 $pagenext = $page + 1;
72
73 $diroutputmassaction = $conf->user->dir_temp.'/'.$user->id.'/customreport';
74}
75
76require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
77require_once DOL_DOCUMENT_ROOT."/core/lib/company.lib.php";
78require_once DOL_DOCUMENT_ROOT."/core/class/dolgraph.class.php";
79require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
80require_once DOL_DOCUMENT_ROOT."/core/class/html.formother.class.php";
81
82// Load traductions files requiredby by page
83$langs->loadLangs(array("companies", "other", "exports", "sendings"));
84
85$extrafields = new ExtraFields($db);
86
87$hookmanager->initHooks(array('customreport')); // Note that conf->hooks_modules contains array
88
89$title = '';
90$picto = '';
91$head = array();
92$object = null;
93$ObjectClassName = '';
94// Objects available by default
95$arrayoftype = array(
96 'thirdparty' => array('langs'=>'companies', 'label' => 'ThirdParties', 'picto'=>'company', 'ObjectClassName' => 'Societe', 'enabled' => isModEnabled('societe'), 'ClassPath' => "/societe/class/societe.class.php"),
97 'contact' => array('label' => 'Contacts', 'picto'=>'contact', 'ObjectClassName' => 'Contact', 'enabled' => isModEnabled('societe'), 'ClassPath' => "/contact/class/contact.class.php"),
98 'proposal' => array('label' => 'Proposals', 'picto'=>'proposal', 'ObjectClassName' => 'Propal', 'enabled' => isModEnabled('propal'), 'ClassPath' => "/comm/propal/class/propal.class.php"),
99 'order' => array('label' => 'Orders', 'picto'=>'order', 'ObjectClassName' => 'Commande', 'enabled' => isModEnabled('commande'), 'ClassPath' => "/commande/class/commande.class.php"),
100 'invoice' => array('langs'=>'facture', 'label' => 'Invoices', 'picto'=>'bill', 'ObjectClassName' => 'Facture', 'enabled' => isModEnabled('facture'), 'ClassPath' => "/compta/facture/class/facture.class.php"),
101 'invoice_template'=>array('label' => 'PredefinedInvoices', 'picto'=>'bill', 'ObjectClassName' => 'FactureRec', 'enabled' => isModEnabled('facture'), 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'),
102 'contract' => array('label' => 'Contracts', 'picto'=>'contract', 'ObjectClassName' => 'Contrat', 'enabled' => isModEnabled('contrat'), 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'),
103 'contractdet' => array('label' => 'ContractLines', 'picto'=>'contract', 'ObjectClassName' => 'ContratLigne', 'enabled' => isModEnabled('contrat'), 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'),
104 'bom' => array('label' => 'BOM', 'picto'=>'bom', 'ObjectClassName' => 'Bom', 'enabled' => isModEnabled('bom')),
105 'mo' => array('label' => 'MO', 'picto'=>'mrp', 'ObjectClassName' => 'Mo', 'enabled' => isModEnabled('mrp'), 'ClassPath' => "/mrp/class/mo.class.php"),
106 'ticket' => array('label' => 'Ticket', 'picto'=>'ticket', 'ObjectClassName' => 'Ticket', 'enabled' => isModEnabled('ticket')),
107 'member' => array('label' => 'Adherent', 'picto'=>'member', 'ObjectClassName' => 'Adherent', 'enabled' => isModEnabled('adherent'), 'ClassPath' => "/adherents/class/adherent.class.php", 'langs'=>'members'),
108 'cotisation' => array('label' => 'Subscriptions', 'picto'=>'member', 'ObjectClassName' => 'Subscription', 'enabled' => isModEnabled('adherent'), 'ClassPath' => "/adherents/class/subscription.class.php", 'langs'=>'members'),
109);
110
111// Complete $arrayoftype by external modules
112$parameters = array('objecttype'=>$objecttype, 'tabfamily'=>$tabfamily);
113$reshook = $hookmanager->executeHooks('loadDataForCustomReports', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
114if ($reshook < 0) {
115 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
116} elseif (is_array($hookmanager->resArray)) {
117 if (!empty($hookmanager->resArray['title'])) { // Add entries for tabs
118 $title = $hookmanager->resArray['title'];
119 }
120 if (!empty($hookmanager->resArray['picto'])) { // Add entries for tabs
121 $picto = $hookmanager->resArray['picto'];
122 }
123 if (!empty($hookmanager->resArray['head'])) { // Add entries for tabs
124 $head = array_merge($head, $hookmanager->resArray['head']);
125 }
126 if (!empty($hookmanager->resArray['arrayoftype'])) { // Add entries from hook
127 foreach ($hookmanager->resArray['arrayoftype'] as $key => $val) {
128 $arrayoftype[$key] = $val;
129 }
130 }
131}
132
133if ($objecttype) {
134 try {
135 if (!empty($arrayoftype[$objecttype]['ClassPath'])) {
136 dol_include_once($arrayoftype[$objecttype]['ClassPath']);
137 } else {
138 dol_include_once("/".$objecttype."/class/".$objecttype.".class.php");
139 }
140 $ObjectClassName = $arrayoftype[$objecttype]['ObjectClassName'];
141 $object = new $ObjectClassName($db);
142 } catch (Exception $e) {
143 print 'Failed to load class for type '.$objecttype;
144 }
145}
146
147// Security check
148$socid = 0;
149if ($user->socid > 0) { // Protection if external user
150 //$socid = $user->socid;
152}
153
154// Fetch optionals attributes and labels
155$extrafields->fetch_name_optionals_label('all'); // We load all extrafields definitions for all objects
156//$extrafields->fetch_name_optionals_label($object->table_element_line);
157
158$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
159
160$search_component_params = array('');
161$search_component_params_hidden = GETPOST('search_component_params_hidden', 'alphanohtml');
162
163// For the case we enter a criteria manually, the search_component_params_input will be defined and must be used in priority
164if (GETPOST('search_component_params_input', 'alphanohtml')) {
165 $search_component_params_hidden = GETPOST('search_component_params_input', 'alphanohtml');
166}
167
168$MAXUNIQUEVALFORGROUP = 20;
169$MAXMEASURESINBARGRAPH = 20;
170
171$YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
172$MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
173$DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
174$HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
175$MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
176$SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
177
178$arrayofmesures = array();
179$arrayofxaxis = array();
180$arrayofgroupby = array();
181$arrayofyaxis = array();
182$arrayofvaluesforgroupby = array();
183
184$features = $object->element;
185if (!empty($object->element_for_permission)) {
186 $features = $object->element_for_permission;
187}
188
189restrictedArea($user, $features, 0, '');
190
191$error = 0;
192
193
194/*
195 * Actions
196 */
197
198// None
199
200
201
202/*
203 * View
204 */
205
206$form = new Form($db);
207$formother = new FormOther($db);
208
209if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
210 llxHeader('', $langs->transnoentitiesnoconv('CustomReports'), '');
211
212 print dol_get_fiche_head($head, 'customreports', $title, -1, $picto);
213}
214
215$newarrayoftype = array();
216foreach ($arrayoftype as $key => $val) {
217 if (dol_eval($val['enabled'], 1, 1, '1')) {
218 $newarrayoftype[$key] = $arrayoftype[$key];
219 }
220 if (!empty($val['langs'])) {
221 $langs->load($val['langs']);
222 }
223}
224
225$count = 0;
226$arrayofmesures = fillArrayOfMeasures($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofmesures, 0, $count);
227$arrayofmesures = dol_sort_array($arrayofmesures, 'position', 'asc', 0, 0, 1);
228
229$count = 0;
230$arrayofxaxis = fillArrayOfXAxis($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofxaxis, 0, $count);
231$arrayofxaxis = dol_sort_array($arrayofxaxis, 'position', 'asc', 0, 0, 1);
232
233$count = 0;
234$arrayofgroupby = fillArrayOfGroupBy($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofgroupby, 0, $count);
235$arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1);
236
237
238// Check parameters
239if ($action == 'viewgraph') {
240 if (!count($search_measures)) {
241 setEventMessages($langs->trans("AtLeastOneMeasureIsRequired"), null, 'warnings');
242 } elseif ($mode == 'graph' && count($search_xaxis) > 1) {
243 setEventMessages($langs->trans("OnlyOneFieldForXAxisIsPossible"), null, 'warnings');
244 $search_xaxis = array(0 => $search_xaxis[0]);
245 }
246 if (count($search_groupby) >= 2) {
247 setEventMessages($langs->trans("ErrorOnlyOneFieldForGroupByIsPossible"), null, 'warnings');
248 $search_groupby = array(0 => $search_groupby[0]);
249 }
250 if (!count($search_xaxis)) {
251 setEventMessages($langs->trans("AtLeastOneXAxisIsRequired"), null, 'warnings');
252 } elseif ($mode == 'graph' && $search_graph == 'bars' && count($search_measures) > $MAXMEASURESINBARGRAPH) {
253 $langs->load("errors");
254 setEventMessages($langs->trans("GraphInBarsAreLimitedToNMeasures", $MAXMEASURESINBARGRAPH), null, 'warnings');
255 $search_graph = 'lines';
256 }
257}
258
259// Get all possible values of fields when a 'group by' is set, and save this into $arrayofvaluesforgroupby
260// $arrayofvaluesforgroupby will be used to forge lael of each grouped series
261if (is_array($search_groupby) && count($search_groupby)) {
262 foreach ($search_groupby as $gkey => $gval) {
263 $gvalwithoutprefix = preg_replace('/^[a-z]+\./i', '', $gval);
264 $gvalsanitized = preg_replace('/[^a-z0-9\._\-]+/i', '', $gval);
265
266 if (preg_match('/\-year$/', $gvalsanitized)) {
267 $tmpval = preg_replace('/\-year$/', '', $gvalsanitized);
268 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y')";
269 } elseif (preg_match('/\-month$/', $gvalsanitized)) {
270 $tmpval = preg_replace('/\-month$/', '', $gvalsanitized);
271 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m')";
272 } elseif (preg_match('/\-day$/', $gvalsanitized)) {
273 $tmpval = preg_replace('/\-day$/', '', $gvalsanitized);
274 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d')";
275 } else {
276 $fieldtocount = $gvalsanitized;
277 }
278
279 $sql = "SELECT DISTINCT ".$fieldtocount." as val";
280
281 if (strpos($fieldtocount, 'te') === 0) {
282 $tabletouse = $object->table_element;
283 $tablealiastouse = 'te';
284 if (!empty($arrayofgroupby[$gval])) {
285 $tmpval = explode('.', $gval);
286 $tabletouse = $arrayofgroupby[$gval]['table'];
287 $tablealiastouse = $tmpval[0];
288 }
289 //var_dump($tablealiastouse);exit;
290
291 //$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te";
292 $sql .= " FROM ".MAIN_DB_PREFIX.$tabletouse."_extrafields as ".$tablealiastouse;
293 } else {
294 $tabletouse = $object->table_element;
295 $tablealiastouse = 't';
296 if (!empty($arrayofgroupby[$gval])) {
297 $tmpval = explode('.', $gval);
298 $tabletouse = $arrayofgroupby[$gval]['table'];
299 $tablealiastouse = $tmpval[0];
300 }
301 $sql .= " FROM ".MAIN_DB_PREFIX.$tabletouse." as ".$tablealiastouse;
302 }
303
304 // Add a where here keeping only the citeria on $tabletouse
305 // TODO
306 /*$sqlfilters = ... GETPOST('search_component_params_hidden', 'alphanohtml');
307 if ($sqlfilters) {
308 $errormessage = '';
309 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
310 }*/
311
312 $sql .= " LIMIT ".((int) ($MAXUNIQUEVALFORGROUP + 1));
313
314 //print $sql;
315 $resql = $db->query($sql);
316 if (!$resql) {
317 dol_print_error($db);
318 }
319
320 while ($obj = $db->fetch_object($resql)) {
321 if (is_null($obj->val)) {
322 $keytouse = '__NULL__';
323 $valuetranslated = $langs->transnoentitiesnoconv("NotDefined");
324 } elseif ($obj->val === '') {
325 $keytouse = '';
326 $valuetranslated = $langs->transnoentitiesnoconv("Empty");
327 } else {
328 $keytouse = (string) $obj->val;
329 $valuetranslated = $obj->val;
330 }
331
332 $regs = array();
333 if (!empty($object->fields[$gvalwithoutprefix]['arrayofkeyval'])) {
334 $valuetranslated = $object->fields[$gvalwithoutprefix]['arrayofkeyval'][$obj->val];
335 if (is_null($valuetranslated)) {
336 $valuetranslated = $langs->transnoentitiesnoconv("UndefinedKey");
337 }
338 $valuetranslated = $langs->trans($valuetranslated);
339 } elseif (preg_match('/integer:([^:]+):([^:]+)$/', $object->fields[$gvalwithoutprefix]['type'], $regs)) {
340 $classname = $regs[1];
341 $classpath = $regs[2];
342 dol_include_once($classpath);
343 if (class_exists($classname)) {
344 $tmpobject = new $classname($db);
345 $tmpobject->fetch($obj->val);
346 foreach ($tmpobject->fields as $fieldkey => $field) {
347 if ($field['showoncombobox']) {
348 $valuetranslated = $tmpobject->$fieldkey;
349 //if ($valuetranslated == '-') $valuetranslated = $langs->transnoentitiesnoconv("Unknown")
350 break;
351 }
352 }
353 //$valuetranslated = $tmpobject->ref.'eee';
354 }
355 }
356
357 $arrayofvaluesforgroupby['g_'.$gkey][$keytouse] = $valuetranslated;
358 }
359 // Add also the possible NULL value if field is a parent field that is not a strict join
360 $tmpfield = explode('.', $gval);
361 if ($tmpfield[0] != 't' || (is_array($object->fields[$tmpfield[1]]) && empty($object->fields[$tmpfield[1]]['notnull']))) {
362 dol_syslog("The group by field ".$gval." may be null (because field is null or it is a left join), so we add __NULL__ entry in list of possible values");
363 //var_dump($gval); var_dump($object->fields);
364 $arrayofvaluesforgroupby['g_'.$gkey]['__NULL__'] = $langs->transnoentitiesnoconv("NotDefined");
365 }
366
367 asort($arrayofvaluesforgroupby['g_'.$gkey]);
368
369 // Add a protection/error to refuse the request if number of differentr values for the group by is higher than $MAXUNIQUEVALFORGROUP
370 if (count($arrayofvaluesforgroupby['g_'.$gkey]) > $MAXUNIQUEVALFORGROUP) {
371 $langs->load("errors");
372
373 if (strpos($fieldtocount, 'te') === 0) { // This is a field of an extrafield
374 //if (!empty($extrafields->attributes[$object->table_element]['langfile'][$gvalwithoutprefix])) {
375 // $langs->load($extrafields->attributes[$object->table_element]['langfile'][$gvalwithoutprefix]);
376 //}
377 $keyforlabeloffield = $extrafields->attributes[$object->table_element]['label'][$gvalwithoutprefix];
378 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
379 } elseif (strpos($fieldtocount, 't__') === 0) { // This is a field of a foreign key
380 $reg = array();
381 if (preg_match('/^(.*)\.(.*)/', $gvalwithoutprefix, $reg)) {
382 /*
383 $gvalwithoutprefix = preg_replace('/\..*$/', '', $gvalwithoutprefix);
384 $gvalwithoutprefix = preg_replace('/^t__/', '', $gvalwithoutprefix);
385 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
386 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield).'-'.$reg[2];
387 */
388 $labeloffield = $arrayofgroupby[$fieldtocount]['labelnohtml'];
389 } else {
390 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
391 }
392 } else { // This is a common field
393 $reg = array();
394 if (preg_match('/^(.*)\-(year|month|day)/', $gvalwithoutprefix, $reg)) {
395 $gvalwithoutprefix = preg_replace('/\-(year|month|day)/', '', $gvalwithoutprefix);
396 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
397 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield).'-'.$reg[2];
398 } else {
399 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
400 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
401 }
402 }
403 //var_dump($object->fields);
404 setEventMessages($langs->trans("ErrorTooManyDifferentValueForSelectedGroupBy", $MAXUNIQUEVALFORGROUP, $labeloffield), null, 'warnings');
405 $search_groupby = array();
406 }
407
408 $db->free($resql);
409 }
410}
411//var_dump($arrayofvaluesforgroupby);exit;
412
413
414$tmparray = dol_getdate(dol_now());
415$endyear = $tmparray['year'];
416$endmonth = $tmparray['mon'];
417$datelastday = dol_get_last_day($endyear, $endmonth, 1);
418$startyear = $endyear - 2;
419
420$param = '';
421
422print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" autocomplete="off">';
423print '<input type="hidden" name="token" value="'.newToken().'">';
424print '<input type="hidden" name="action" value="viewgraph">';
425print '<input type="hidden" name="tabfamily" value="'.$tabfamily.'">';
426
427$viewmode = '';
428
429$viewmode .= '<div class="divadvancedsearchfield">';
430$arrayofgraphs = array('bars' => 'Bars', 'lines' => 'Lines'); // also 'pies'
431$viewmode .= '<div class="inline-block opacitymedium"><span class="fas fa-chart-area paddingright" title="'.$langs->trans("Graph").'"></span>'.$langs->trans("Graph").'</div> ';
432$viewmode .= $form->selectarray('search_graph', $arrayofgraphs, $search_graph, 0, 0, 0, '', 1, 0, 0, '', 'graphtype width100');
433$viewmode .= '</div>';
434
435$num = 0;
436$massactionbutton = '';
437$nav = '';
438$newcardbutton = '';
439$limit = 0;
440
441print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.'<span class="marginleftonly"></span>'.$newcardbutton, '', $limit, 1, 0, 1, $viewmode);
442
443
444foreach ($newarrayoftype as $tmpkey => $tmpval) {
445 $newarrayoftype[$tmpkey]['label'] = img_picto('', $tmpval['picto'], 'class="pictofixedwidth"').$langs->trans($tmpval['label']);
446}
447
448print '<div class="liste_titre liste_titre_bydiv liste_titre_bydiv_inlineblock centpercent">';
449
450// Select object
451print '<div class="divadvancedsearchfield center floatnone">';
452print '<div class="inline-block"><span class="opacitymedium">'.$langs->trans("StatisticsOn").'</span></div> ';
453print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1, '', 0, 1);
454if (empty($conf->use_javascript_ajax)) {
455 print '<input type="submit" class="button buttongen button-save nomargintop" name="changeobjecttype" value="'.$langs->trans("Refresh").'">';
456} else {
457 print '<!-- js code to reload page with good object type -->
458 <script nonce="'.getNonce().'" type="text/javascript">
459 jQuery(document).ready(function() {
460 jQuery("#objecttype").change(function() {
461 console.log("Reload for "+jQuery("#objecttype").val());
462 location.href = "'.$_SERVER["PHP_SELF"].'?objecttype="+jQuery("#objecttype").val()+"'.($tabfamily ? '&tabfamily='.urlencode($tabfamily) : '').(GETPOST('show_search_component_params_hidden', 'int') ? '&show_search_component_params_hidden='.((int) GETPOST('show_search_component_params_hidden', 'int')) : '').'";
463 });
464 });
465 </script>';
466}
467print '</div><div class="clearboth"></div>';
468
469// Filter (you can use param &show_search_component_params_hidden=1 for debug)
470print '<div class="divadvancedsearchfield quatrevingtpercent">';
471print $form->searchComponent(array($object->element => $object->fields), $search_component_params, array(), $search_component_params_hidden);
472print '</div>';
473
474// YAxis (add measures into array)
475$count = 0;
476//var_dump($arrayofmesures);
477print '<div class="divadvancedsearchfield clearboth">';
478print '<div class="inline-block"><span class="fas fa-ruler-combined paddingright pictofixedwidth" title="'.dol_escape_htmltag($langs->trans("Measures")).'"></span><span class="fas fa-caret-left caretleftaxis" title="'.dol_escape_htmltag($langs->trans("Measures")).'"></span></div>';
479$simplearrayofmesures = array();
480foreach ($arrayofmesures as $key => $val) {
481 $simplearrayofmesures[$key] = $arrayofmesures[$key]['label'];
482}
483print $form->multiselectarray('search_measures', $simplearrayofmesures, $search_measures, 0, 0, 'minwidth300', 1, 0, '', '', $langs->trans("Measures")); // Fill the array $arrayofmeasures with possible fields
484print '</div>';
485
486// XAxis
487$count = 0;
488print '<div class="divadvancedsearchfield">';
489print '<div class="inline-block"><span class="fas fa-ruler-combined paddingright pictofixedwidth" title="'.dol_escape_htmltag($langs->trans("XAxis")).'"></span><span class="fas fa-caret-down caretdownaxis" title="'.dol_escape_htmltag($langs->trans("XAxis")).'"></span></div>';
490//var_dump($arrayofxaxis);
491print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis, $langs->trans("XAxis"), 'minwidth300 maxwidth400'); // Fill the array $arrayofxaxis with possible fields
492print '</div>';
493
494// Group by
495$count = 0;
496print '<div class="divadvancedsearchfield">';
497print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-horizontal paddingright pictofixedwidth" title="'.dol_escape_htmltag($langs->trans("GroupBy")).'"></span></div>';
498print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby, 'minwidth250 maxwidth300', $langs->trans("GroupBy")); // Fill the array $arrayofgroupby with possible fields
499print '</div>';
500
501
502if ($mode == 'grid') {
503 // YAxis
504 print '<div class="divadvancedsearchfield">';
505 foreach ($object->fields as $key => $val) {
506 if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) {
507 if (in_array($key, array('id', 'rowid', 'entity', 'last_main_doc', 'extraparams'))) {
508 continue;
509 }
510 if (preg_match('/^fk_/', $key)) {
511 continue;
512 }
513 if (in_array($val['type'], array('html', 'text'))) {
514 continue;
515 }
516 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
517 $arrayofyaxis['t.'.$key.'-year'] = array(
518 'label' => $langs->trans($val['label']).' ('.$YYYY.')',
519 'position' => $val['position'],
520 'table' => $object->table_element
521 );
522 $arrayofyaxis['t.'.$key.'-month'] = array(
523 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')',
524 'position' => $val['position'],
525 'table' => $object->table_element
526 );
527 $arrayofyaxis['t.'.$key.'-day'] = array(
528 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')',
529 'position' => $val['position'],
530 'table' => $object->table_element
531 );
532 } else {
533 $arrayofyaxis['t.'.$key] = array(
534 'label' => $val['label'],
535 'position' => (int) $val['position'],
536 'table' => $object->table_element
537 );
538 }
539 }
540 }
541 // Add measure from extrafields
542 if ($object->isextrafieldmanaged) {
543 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
544 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) {
545 $arrayofyaxis['te.'.$key] = array(
546 'label' => $extrafields->attributes[$object->table_element]['label'][$key],
547 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key],
548 'table' => $object->table_element
549 );
550 }
551 }
552 }
553 $arrayofyaxis = dol_sort_array($arrayofyaxis, 'position');
554 $arrayofyaxislabel = array();
555 foreach ($arrayofyaxis as $key => $val) {
556 $arrayofyaxislabel[$key] = $val['label'];
557 }
558 print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-vertical paddingright" title="'.$langs->trans("YAxis").'"></span>'.$langs->trans("YAxis").'</div> ';
559 print $form->multiselectarray('search_yaxis', $arrayofyaxislabel, $search_yaxis, 0, 0, 'minwidth100', 1);
560 print '</div>';
561}
562
563if ($mode == 'graph') {
564 //
565}
566
567print '<div class="divadvancedsearchfield">';
568print '<input type="submit" class="button buttongen button-save nomargintop" value="'.$langs->trans("Refresh").'">';
569print '</div>';
570print '</div>';
571print '</form>';
572
573// Generate the SQL request
574$sql = '';
575if (!empty($search_measures) && !empty($search_xaxis)) {
576 $errormessage = '';
577
578 $fieldid = 'rowid';
579
580 $sql = "SELECT ";
581 foreach ($search_xaxis as $key => $val) {
582 if (preg_match('/\-year$/', $val)) {
583 $tmpval = preg_replace('/\-year$/', '', $val);
584 $sql .= "DATE_FORMAT(".$tmpval.", '%Y') as x_".$key.', ';
585 } elseif (preg_match('/\-month$/', $val)) {
586 $tmpval = preg_replace('/\-month$/', '', $val);
587 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m') as x_".$key.', ';
588 } elseif (preg_match('/\-day$/', $val)) {
589 $tmpval = preg_replace('/\-day$/', '', $val);
590 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d') as x_".$key.', ';
591 } else {
592 $sql .= $val." as x_".$key.", ";
593 }
594 }
595 foreach ($search_groupby as $key => $val) {
596 if (preg_match('/\-year$/', $val)) {
597 $tmpval = preg_replace('/\-year$/', '', $val);
598 $sql .= "DATE_FORMAT(".$tmpval.", '%Y') as g_".$key.', ';
599 } elseif (preg_match('/\-month$/', $val)) {
600 $tmpval = preg_replace('/\-month$/', '', $val);
601 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m') as g_".$key.', ';
602 } elseif (preg_match('/\-day$/', $val)) {
603 $tmpval = preg_replace('/\-day$/', '', $val);
604 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d') as g_".$key.', ';
605 } else {
606 $sql .= $val." as g_".$key.", ";
607 }
608 }
609 foreach ($search_measures as $key => $val) {
610 if ($val == 't.count') {
611 $sql .= "COUNT(t.".$fieldid.") as y_".$key.', ';
612 } elseif (preg_match('/\-sum$/', $val)) {
613 $tmpval = preg_replace('/\-sum$/', '', $val);
614 $sql .= "SUM(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
615 } elseif (preg_match('/\-average$/', $val)) {
616 $tmpval = preg_replace('/\-average$/', '', $val);
617 $sql .= "AVG(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
618 } elseif (preg_match('/\-min$/', $val)) {
619 $tmpval = preg_replace('/\-min$/', '', $val);
620 $sql .= "MIN(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
621 } elseif (preg_match('/\-max$/', $val)) {
622 $tmpval = preg_replace('/\-max$/', '', $val);
623 $sql .= "MAX(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
624 }
625 }
626 $sql = preg_replace('/,\s*$/', '', $sql);
627 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
628 // Add measure from extrafields
629 if ($object->isextrafieldmanaged) {
630 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te ON te.fk_object = t.".$fieldid;
631 }
632 // Add table for link on multientity
633 if ($object->ismultientitymanaged) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
634 if ($object->ismultientitymanaged == 1) {
635 // No table to add here
636 } else {
637 $tmparray = explode('@', $object->ismultientitymanaged);
638 $sql .= " INNER JOIN ".MAIN_DB_PREFIX.$tmparray[1]." as parenttableforentity ON t.".$tmparray[0]." = parenttableforentity.rowid";
639 $sql .= " AND parenttableforentity.entity IN (".getEntity($tmparray[1]).")";
640 }
641 }
642
643 // Init the list of tables added. We include by default always the main table.
644 $listoftablesalreadyadded = array($object->table_element => $object->table_element);
645
646 // Add LEFT JOIN for all parent tables mentionned into the Xaxis
647 //var_dump($arrayofxaxis); var_dump($search_xaxis);
648 foreach ($search_xaxis as $key => $val) {
649 if (!empty($arrayofxaxis[$val])) {
650 $tmpval = explode('.', $val);
651 //var_dump($arrayofgroupby);
652 $tmpforloop = dolExplodeIntoArray($arrayofxaxis[$val]['tablefromt'], ',');
653 foreach ($tmpforloop as $tmptable => $tmptablealias) {
654 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
655 $tmpforexplode = explode('__', $tmptablealias);
656 $endpart = end($tmpforexplode);
657 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
658
659 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
660 $listoftablesalreadyadded[$tmptable] = $tmptable;
661
662 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
663 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
664 $listoftablesalreadyadded[$tmptable] = $tmptable;
665 }
666 }
667 }
668 } else {
669 $errormessage = 'Found a key into search_xaxis not found into arrayofxaxis';
670 }
671 }
672
673 // Add LEFT JOIN for all parent tables mentionned into the Group by
674 //var_dump($arrayofgroupby); var_dump($search_groupby);
675 foreach ($search_groupby as $key => $val) {
676 if (!empty($arrayofgroupby[$val])) {
677 $tmpval = explode('.', $val);
678 //var_dump($arrayofgroupby[$val]); var_dump($tmpval);
679 $tmpforloop = dolExplodeIntoArray($arrayofgroupby[$val]['tablefromt'], ',');
680 foreach ($tmpforloop as $tmptable => $tmptablealias) {
681 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
682 $tmpforexplode = explode('__', $tmptablealias);
683 $endpart = end($tmpforexplode);
684 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
685
686 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
687 $listoftablesalreadyadded[$tmptable] = $tmptable;
688
689 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
690 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
691 $listoftablesalreadyadded[$tmptable] = $tmptable;
692 }
693 }
694 }
695 } else {
696 $errormessage = 'Found a key into search_groupby not found into arrayofgroupby';
697 }
698 }
699
700 // Add LEFT JOIN for all parent tables mentionned into the Yaxis
701 //var_dump($arrayofgroupby); var_dump($search_groupby);
702 foreach ($search_measures as $key => $val) {
703 if (!empty($arrayofmesures[$val])) {
704 $tmpval = explode('.', $val);
705 //var_dump($arrayofgroupby);
706 $tmpforloop = dolExplodeIntoArray($arrayofmesures[$val]['tablefromt'], ',');
707 foreach ($tmpforloop as $tmptable => $tmptablealias) {
708 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
709 $tmpforexplode = explode('__', $tmptablealias);
710 $endpart = end($tmpforexplode);
711 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
712
713 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
714 $listoftablesalreadyadded[$tmptable] = $tmptable;
715
716 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
717 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
718 $listoftablesalreadyadded[$tmptable] = $tmptable;
719 }
720 }
721 }
722 } else {
723 $errormessage = 'Found a key into search_measures not found into arrayofmesures';
724 }
725 }
726
727 $sql .= " WHERE 1 = 1";
728 if ($object->ismultientitymanaged == 1) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
729 $sql .= " AND t.entity IN (".getEntity($object->element).")";
730 }
731 // Add the where here
732 $sqlfilters = $search_component_params_hidden;
733 if ($sqlfilters) {
734 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage, 0, 0, 1);
735 }
736 $sql .= " GROUP BY ";
737 foreach ($search_xaxis as $key => $val) {
738 if (preg_match('/\-year$/', $val)) {
739 $tmpval = preg_replace('/\-year$/', '', $val);
740 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
741 } elseif (preg_match('/\-month$/', $val)) {
742 $tmpval = preg_replace('/\-month$/', '', $val);
743 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
744 } elseif (preg_match('/\-day$/', $val)) {
745 $tmpval = preg_replace('/\-day$/', '', $val);
746 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
747 } else {
748 $sql .= $val.", ";
749 }
750 }
751 foreach ($search_groupby as $key => $val) {
752 if (preg_match('/\-year$/', $val)) {
753 $tmpval = preg_replace('/\-year$/', '', $val);
754 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
755 } elseif (preg_match('/\-month$/', $val)) {
756 $tmpval = preg_replace('/\-month$/', '', $val);
757 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
758 } elseif (preg_match('/\-day$/', $val)) {
759 $tmpval = preg_replace('/\-day$/', '', $val);
760 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
761 } else {
762 $sql .= $val.', ';
763 }
764 }
765 $sql = preg_replace('/,\s*$/', '', $sql);
766 $sql .= ' ORDER BY ';
767 foreach ($search_xaxis as $key => $val) {
768 if (preg_match('/\-year$/', $val)) {
769 $tmpval = preg_replace('/\-year$/', '', $val);
770 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
771 } elseif (preg_match('/\-month$/', $val)) {
772 $tmpval = preg_replace('/\-month$/', '', $val);
773 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
774 } elseif (preg_match('/\-day$/', $val)) {
775 $tmpval = preg_replace('/\-day$/', '', $val);
776 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
777 } else {
778 $sql .= $val.', ';
779 }
780 }
781 foreach ($search_groupby as $key => $val) {
782 if (preg_match('/\-year$/', $val)) {
783 $tmpval = preg_replace('/\-year$/', '', $val);
784 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
785 } elseif (preg_match('/\-month$/', $val)) {
786 $tmpval = preg_replace('/\-month$/', '', $val);
787 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
788 } elseif (preg_match('/\-day$/', $val)) {
789 $tmpval = preg_replace('/\-day$/', '', $val);
790 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
791 } else {
792 $sql .= $val.', ';
793 }
794 }
795 $sql = preg_replace('/,\s*$/', '', $sql);
796}
797//print $sql;
798
799if ($errormessage) {
800 print dol_escape_htmltag($errormessage);
801 $sql = '';
802}
803
804$legend = array();
805foreach ($search_measures as $key => $val) {
806 $legend[] = $langs->trans($arrayofmesures[$val]['label']);
807}
808
809$useagroupby = (is_array($search_groupby) && count($search_groupby));
810//var_dump($useagroupby);
811//var_dump($arrayofvaluesforgroupby);
812
813// Execute the SQL request
814$totalnbofrecord = 0;
815$data = array();
816if ($sql) {
817 $resql = $db->query($sql);
818 if (!$resql) {
819 dol_print_error($db);
820 }
821
822 $ifetch = 0;
823 $xi = 0;
824 $oldlabeltouse = '';
825 while ($obj = $db->fetch_object($resql)) {
826 $ifetch++;
827 if ($useagroupby) {
828 $xval = $search_xaxis[0];
829 $fieldforxkey = 'x_0';
830 $xlabel = $obj->$fieldforxkey;
831 $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
832
833 // Define $xlabel
834 if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
835 $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
836 }
837 $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined")));
838
839 if ($oldlabeltouse && ($labeltouse != $oldlabeltouse)) {
840 $xi++; // Increase $xi
841 }
842 //var_dump($labeltouse.' '.$oldlabeltouse.' '.$xi);
843 $oldlabeltouse = $labeltouse;
844
845 /* Example of value for $arrayofvaluesforgroupby
846 * array (size=1)
847 * 'g_0' =>
848 * array (size=6)
849 * 0 => string '0' (length=1)
850 * '' => string 'Empty' (length=5)
851 * '__NULL__' => string 'Not defined' (length=11)
852 * 'done' => string 'done' (length=4)
853 * 'processing' => string 'processing' (length=10)
854 * 'undeployed' => string 'undeployed' (length=10)
855 */
856 foreach ($search_measures as $key => $val) {
857 $gi = 0;
858 foreach ($search_groupby as $gkey) {
859 //var_dump('*** Fetch #'.$ifetch.' for labeltouse='.$labeltouse.' measure number '.$key.' and group g_'.$gi);
860 //var_dump($arrayofvaluesforgroupby);
861 foreach ($arrayofvaluesforgroupby['g_'.$gi] as $gvaluepossiblekey => $gvaluepossiblelabel) {
862 $ykeysuffix = $gvaluepossiblelabel;
863 $gvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $gval);
864
865 $fieldfory = 'y_'.$key;
866 $fieldforg = 'g_'.$gi;
867 $fieldforybis = 'y_'.$key.'_'.$ykeysuffix;
868 //var_dump('gvaluepossiblekey='.$gvaluepossiblekey.' gvaluepossiblelabel='.$gvaluepossiblelabel.' ykeysuffix='.$ykeysuffix.' gval='.$gval.' gvalwithoutsuffix='.$gvalwithoutprefix);
869 //var_dump('fieldforg='.$fieldforg.' obj->$fieldforg='.$obj->$fieldforg.' fieldfory='.$fieldfory.' obj->$fieldfory='.$obj->$fieldfory.' fieldforybis='.$fieldforybis);
870
871 if (!is_array($data[$xi])) {
872 $data[$xi] = array();
873 }
874
875 if (!array_key_exists('label', $data[$xi])) {
876 $data[$xi] = array();
877 $data[$xi]['label'] = $labeltouse;
878 }
879
880 $objfieldforg = $obj->$fieldforg;
881 if (is_null($objfieldforg)) {
882 $objfieldforg = '__NULL__';
883 }
884
885 if ($gvaluepossiblekey == '0') { // $gvaluepossiblekey can have type int or string. So we create a special if, used when value is '0'
886 //var_dump($objfieldforg.' == \'0\' -> '.($objfieldforg == '0'));
887 if ($objfieldforg == '0') {
888 // The record we fetch is for this group
889 $data[$xi][$fieldforybis] = $obj->$fieldfory;
890 } elseif (!isset($data[$xi][$fieldforybis])) {
891 // The record we fetch is not for this group
892 $data[$xi][$fieldforybis] = '0';
893 }
894 } else {
895 //var_dump((string) $objfieldforg.' === '.(string) $gvaluepossiblekey.' -> '.((string) $objfieldforg === (string) $gvaluepossiblekey));
896 if ((string) $objfieldforg === (string) $gvaluepossiblekey) {
897 // The record we fetch is for this group
898 $data[$xi][$fieldforybis] = $obj->$fieldfory;
899 } elseif (!isset($data[$xi][$fieldforybis])) {
900 // The record we fetch is not for this group
901 $data[$xi][$fieldforybis] = '0';
902 }
903 }
904 }
905 //var_dump($data[$xi]);
906 $gi++;
907 }
908 }
909 } else { // No group by
910 $xval = $search_xaxis[0];
911 $fieldforxkey = 'x_0';
912 $xlabel = $obj->$fieldforxkey;
913 $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
914
915 // Define $xlabel
916 if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
917 $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
918 }
919
920 $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined")));
921 $xarrayforallseries = array('label' => $labeltouse);
922 foreach ($search_measures as $key => $val) {
923 $fieldfory = 'y_'.$key;
924 $xarrayforallseries[$fieldfory] = $obj->$fieldfory;
925 }
926 $data[$xi] = $xarrayforallseries;
927 $xi++;
928 }
929 }
930
931 $totalnbofrecord = count($data);
932}
933//var_dump($data);
934
935
936print '<div class="customreportsoutput'.($totalnbofrecord ? '' : ' customreportsoutputnotdata').'">';
937
938
939if ($mode == 'grid') {
940 // TODO
941}
942
943if ($mode == 'graph') {
944 $WIDTH = '80%';
945 $HEIGHT = (empty($_SESSION['dol_screenheight']) ? 400 : $_SESSION['dol_screenheight'] - 500);
946
947 // Show graph
948 $px1 = new DolGraph();
949 $mesg = $px1->isGraphKo();
950 if (!$mesg) {
951 //var_dump($legend);
952 //var_dump($data);
953 $px1->SetData($data);
954 unset($data);
955
956 $arrayoftypes = array();
957 foreach ($search_measures as $key => $val) {
958 $arrayoftypes[] = $search_graph;
959 }
960
961 $px1->SetLegend($legend);
962 $px1->SetMinValue($px1->GetFloorMinValue());
963 $px1->SetMaxValue($px1->GetCeilMaxValue());
964 $px1->SetWidth($WIDTH);
965 $px1->SetHeight($HEIGHT);
966 $px1->SetYLabel($langs->trans("Y"));
967 $px1->SetShading(3);
968 $px1->SetHorizTickIncrement(1);
969 $px1->SetCssPrefix("cssboxes");
970 $px1->SetType($arrayoftypes);
971 $px1->mode = 'depth';
972 $px1->SetTitle('');
973
974 $dir = $conf->user->dir_temp;
975 dol_mkdir($dir);
976 $filenamenb = $dir.'/customreport_'.$object->element.'.png';
977 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=user&file=customreport_'.$object->element.'.png';
978
979 $px1->draw($filenamenb, $fileurlnb);
980
981 $texttoshow = $langs->trans("NoRecordFound");
982 if (!GETPOSTISSET('search_measures') || !GETPOSTISSET('search_xaxis')) {
983 $texttoshow = $langs->trans("SelectYourGraphOptionsFirst");
984 }
985
986 print $px1->show($totalnbofrecord ? 0 : $texttoshow);
987 }
988}
989
990if ($sql) {
991 // Show admin info
992 print '<br>'.info_admin($langs->trans("SQLUsedForExport").':<br> '.$sql, 0, 0, 1, '', 'TechnicalInformation');
993}
994
995print '<div>';
996
997if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
998 print dol_get_fiche_end();
999}
1000
1001// End of page
1002llxFooter();
1003
1004$db->close();
1005
1006
1007
1008
1021function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesures, $level = 0, &$count = 0, &$tablepath = '')
1022{
1023 global $langs, $extrafields, $db;
1024
1025 if ($level > 10) { // Protection against infinite loop
1026 return $arrayofmesures;
1027 }
1028
1029 if (empty($tablepath)) {
1030 $tablepath = $object->table_element.'='.$tablealias;
1031 } else {
1032 $tablepath .= ','.$object->table_element.'='.$tablealias;
1033 }
1034
1035 if ($level == 0) {
1036 // Add the count of record only for the main/first level object. Parents are necessarly unique for each record.
1037 $arrayofmesures[$tablealias.'.count'] = array(
1038 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': Count',
1039 'labelnohtml' => $labelofobject.': Count',
1040 'position' => 0,
1041 'table' => $object->table_element,
1042 'tablefromt' => $tablepath
1043 );
1044 }
1045
1046 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1047
1048 // Add main fields of object
1049 foreach ($object->fields as $key => $val) {
1050 if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) {
1051 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1052 $arrayofmesures[$tablealias.'.'.$key.'-sum'] = array(
1053 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Sum").')</span>',
1054 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1055 'position' => ($position + ($count * 100000)).'.1',
1056 'table' => $object->table_element,
1057 'tablefromt' => $tablepath
1058 );
1059 $arrayofmesures[$tablealias.'.'.$key.'-average'] = array(
1060 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Average").')</span>',
1061 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1062 'position' => ($position + ($count * 100000)).'.2',
1063 'table' => $object->table_element,
1064 'tablefromt' => $tablepath
1065 );
1066 $arrayofmesures[$tablealias.'.'.$key.'-min'] = array(
1067 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Minimum").')</span>',
1068 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1069 'position' => ($position + ($count * 100000)).'.3',
1070 'table' => $object->table_element,
1071 'tablefromt' => $tablepath
1072 );
1073 $arrayofmesures[$tablealias.'.'.$key.'-max'] = array(
1074 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Maximum").')</span>',
1075 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1076 'position' => ($position + ($count * 100000)).'.4',
1077 'table' => $object->table_element,
1078 'tablefromt' => $tablepath
1079 );
1080 }
1081 }
1082 // Add extrafields to Measures
1083 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1084 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1085 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) {
1086 $position = (!empty($val['position']) ? $val['position'] : 0);
1087 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-sum'] = array(
1088 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Sum").')</span>',
1089 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1090 'position' => ($position+($count * 100000)).'.1',
1091 'table' => $object->table_element,
1092 'tablefromt' => $tablepath
1093 );
1094 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-average'] = array(
1095 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Average").')</span>',
1096 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1097 'position' => ($position+($count * 100000)).'.2',
1098 'table' => $object->table_element,
1099 'tablefromt' => $tablepath
1100 );
1101 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-min'] = array(
1102 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Minimum").')</span>',
1103 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1104 'position' => ($position+($count * 100000)).'.3',
1105 'table' => $object->table_element,
1106 'tablefromt' => $tablepath
1107 );
1108 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-max'] = array(
1109 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Maximum").')</span>',
1110 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1111 'position' => ($position+($count * 100000)).'.4',
1112 'table' => $object->table_element,
1113 'tablefromt' => $tablepath
1114 );
1115 }
1116 }
1117 }
1118 // Add fields for parent objects
1119 foreach ($object->fields as $key => $val) {
1120 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1121 $tmptype = explode(':', $val['type'], 4);
1122 if ($tmptype[0] == 'integer' && !empty($tmptype[1]) && !empty($tmptype[2])) {
1123 $newobject = $tmptype[1];
1124 dol_include_once($tmptype[2]);
1125 if (class_exists($newobject)) {
1126 $tmpobject = new $newobject($db);
1127 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1128 $count++;
1129 $arrayofmesures = fillArrayOfMeasures($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofmesures, $level + 1, $count, $tablepath);
1130 } else {
1131 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1132 }
1133 }
1134 }
1135 }
1136
1137 return $arrayofmesures;
1138}
1139
1140
1153function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, $level = 0, &$count = 0, &$tablepath = '')
1154{
1155 global $langs, $extrafields, $db;
1156
1157 if ($level >= 3) { // Limit scan on 2 levels max
1158 return $arrayofxaxis;
1159 }
1160
1161 if (empty($tablepath)) {
1162 $tablepath = $object->table_element.'='.$tablealias;
1163 } else {
1164 $tablepath .= ','.$object->table_element.'='.$tablealias;
1165 }
1166
1167 $YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
1168 $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
1169 $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
1170 $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
1171 $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
1172 $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
1173
1174 /*if ($level > 0) {
1175 var_dump($object->element.' '.$object->isextrafieldmanaged);
1176 }*/
1177
1178 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1179
1180 // Add main fields of object
1181 foreach ($object->fields as $key => $val) {
1182 if (empty($val['measure'])) {
1183 if (in_array($key, array(
1184 'id', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
1185 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) {
1186 continue;
1187 }
1188 if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) {
1189 continue;
1190 }
1191 if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) {
1192 continue;
1193 }
1194 if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) {
1195 continue;
1196 }
1197 if (preg_match('/^pass/', $key)) {
1198 continue;
1199 }
1200 if (in_array($val['type'], array('html', 'text'))) {
1201 continue;
1202 }
1203 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
1204 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1205 $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array(
1206 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>',
1207 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1208 'position' => ($position + ($count * 100000)).'.1',
1209 'table' => $object->table_element,
1210 'tablefromt' => $tablepath
1211 );
1212 $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array(
1213 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1214 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1215 'position' => ($position + ($count * 100000)).'.2',
1216 'table' => $object->table_element,
1217 'tablefromt' => $tablepath
1218 );
1219 $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array(
1220 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1221 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1222 'position' => ($position + ($count * 100000)).'.3',
1223 'table' => $object->table_element,
1224 'tablefromt' => $tablepath
1225 );
1226 } else {
1227 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1228 $arrayofxaxis[$tablealias.'.'.$key] = array(
1229 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']),
1230 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1231 'position' => ($position + ($count * 100000)),
1232 'table' => $object->table_element,
1233 'tablefromt' => $tablepath
1234 );
1235 }
1236 }
1237 }
1238
1239 // Add extrafields to X-Axis
1240 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1241 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1242 if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') {
1243 continue;
1244 }
1245 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
1246 continue;
1247 }
1248
1249 if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('timestamp', 'date', 'datetime'))) {
1250 $position = (empty($extrafields->attributes[$object->table_element]['pos'][$key]) ? 0 : intVal($extrafields->attributes[$object->table_element]['pos'][$key]));
1251 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-year'] = array(
1252 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.')</span>',
1253 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1254 'position' => ($position + ($count * 100000)).'.1',
1255 'table' => $object->table_element,
1256 'tablefromt' => $tablepath
1257 );
1258 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-month'] = array(
1259 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1260 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1261 'position' => ($position + ($count * 100000)).'.2',
1262 'table' => $object->table_element,
1263 'tablefromt' => $tablepath
1264 );
1265 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-day'] = array(
1266 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1267 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1268 'position' => ($position + ($count * 100000)).'.3',
1269 'table' => $object->table_element,
1270 'tablefromt' => $tablepath
1271 );
1272 } else {
1273 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key] = array(
1274 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val),
1275 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1276 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000),
1277 'table' => $object->table_element,
1278 'tablefromt' => $tablepath
1279 );
1280 }
1281 }
1282 }
1283
1284 // Add fields for parent objects
1285 foreach ($object->fields as $key => $val) {
1286 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1287 $tmptype = explode(':', $val['type'], 4);
1288 if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) {
1289 $newobject = $tmptype[1];
1290 dol_include_once($tmptype[2]);
1291 if (class_exists($newobject)) {
1292 $tmpobject = new $newobject($db);
1293 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1294 $count++;
1295 $arrayofxaxis = fillArrayOfXAxis($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofxaxis, $level + 1, $count, $tablepath);
1296 } else {
1297 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1298 }
1299 }
1300 }
1301 }
1302
1303 return $arrayofxaxis;
1304}
1305
1306
1319function fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroupby, $level = 0, &$count = 0, &$tablepath = '')
1320{
1321 global $langs, $extrafields, $db;
1322
1323 if ($level >= 3) {
1324 return $arrayofgroupby;
1325 }
1326
1327 if (empty($tablepath)) {
1328 $tablepath = $object->table_element.'='.$tablealias;
1329 } else {
1330 $tablepath .= ','.$object->table_element.'='.$tablealias;
1331 }
1332
1333 $YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
1334 $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
1335 $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
1336 $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
1337 $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
1338 $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
1339
1340 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1341
1342 // Add main fields of object
1343 foreach ($object->fields as $key => $val) {
1344 if (empty($val['isameasure'])) {
1345 if (in_array($key, array(
1346 'id', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
1347 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) {
1348 continue;
1349 }
1350 if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) {
1351 continue;
1352 }
1353 if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) {
1354 continue;
1355 }
1356 if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) {
1357 continue;
1358 }
1359 if (preg_match('/^pass/', $key)) {
1360 continue;
1361 }
1362 if (in_array($val['type'], array('html', 'text'))) {
1363 continue;
1364 }
1365 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
1366 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1367 $arrayofgroupby[$tablealias.'.'.$key.'-year'] = array(
1368 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>',
1369 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1370 'position' => ($position + ($count * 100000)).'.1',
1371 'table' => $object->table_element,
1372 'tablefromt' => $tablepath
1373 );
1374 $arrayofgroupby[$tablealias.'.'.$key.'-month'] = array(
1375 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1376 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1377 'position' => ($position + ($count * 100000)).'.2',
1378 'table' => $object->table_element,
1379 'tablefromt' => $tablepath
1380 );
1381 $arrayofgroupby[$tablealias.'.'.$key.'-day'] = array(
1382 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1383 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1384 'position' => ($position + ($count * 100000)).'.3',
1385 'table' => $object->table_element,
1386 'tablefromt' => $tablepath
1387 );
1388 } else {
1389 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1390 $arrayofgroupby[$tablealias.'.'.$key] = array(
1391 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']),
1392 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1393 'position' => ($position + ($count * 100000)),
1394 'table' => $object->table_element,
1395 'tablefromt' => $tablepath
1396 );
1397 }
1398 }
1399 }
1400
1401 // Add extrafields to Group by
1402 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1403 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1404 if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') {
1405 continue;
1406 }
1407 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
1408 continue;
1409 }
1410
1411 if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('timestamp', 'date', 'datetime'))) {
1412 $position = (empty($extrafields->attributes[$object->table_element]['pos'][$key]) ? 0 : intVal($extrafields->attributes[$object->table_element]['pos'][$key]));
1413 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-year'] = array(
1414 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.')</span>',
1415 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1416 'position' => ($position + ($count * 100000)).'.1',
1417 'table' => $object->table_element,
1418 'tablefromt' => $tablepath
1419 );
1420 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-month'] = array(
1421 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1422 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1423 'position' => ($position + ($count * 100000)).'.2',
1424 'table' => $object->table_element,
1425 'tablefromt' => $tablepath
1426 );
1427 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-day'] = array(
1428 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1429 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1430 'position' => ($position + ($count * 100000)).'.3',
1431 'table' => $object->table_element,
1432 'tablefromt' => $tablepath
1433 );
1434 } else {
1435 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key] = array(
1436 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val),
1437 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1438 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000),
1439 'table' => $object->table_element,
1440 'tablefromt' => $tablepath
1441 );
1442 }
1443 }
1444 }
1445
1446 // Add fields for parent objects
1447 foreach ($object->fields as $key => $val) {
1448 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1449 $tmptype = explode(':', $val['type'], 4);
1450 if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) {
1451 $newobject = $tmptype[1];
1452 dol_include_once($tmptype[2]);
1453 if (class_exists($newobject)) {
1454 $tmpobject = new $newobject($db);
1455 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1456 $count++;
1457 $arrayofgroupby = fillArrayOfGroupBy($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofgroupby, $level + 1, $count, $tablepath);
1458 } else {
1459 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1460 }
1461 }
1462 }
1463 }
1464
1465 return $arrayofgroupby;
1466}
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:56
llxFooter()
Empty footer.
Definition wrapper.php:70
Class to build graphs.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroupby, $level=0, &$count=0, &$tablepath='')
Fill arrayofgrupby for an object.
fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesures, $level=0, &$count=0, &$tablepath='')
Fill arrayofmesures for an object.
fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, $level=0, &$count=0, &$tablepath='')
Fill arrayofmesures for an object.
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:597
dolExplodeIntoArray($string, $delimiter=';', $kv='=')
Split a string with 2 keys into key array.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_eval($s, $returnvalue=0, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.