dolibarr 19.0.3
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]+\./', '', $gval);
264
265 if (preg_match('/\-year$/', $search_groupby[$gkey])) {
266 $tmpval = preg_replace('/\-year$/', '', $search_groupby[$gkey]);
267 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y')";
268 } elseif (preg_match('/\-month$/', $search_groupby[$gkey])) {
269 $tmpval = preg_replace('/\-month$/', '', $search_groupby[$gkey]);
270 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m')";
271 } elseif (preg_match('/\-day$/', $search_groupby[$gkey])) {
272 $tmpval = preg_replace('/\-day$/', '', $search_groupby[$gkey]);
273 $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d')";
274 } else {
275 $fieldtocount = $search_groupby[$gkey];
276 }
277
278 $sql = "SELECT DISTINCT ".$fieldtocount." as val";
279
280 if (strpos($fieldtocount, 'te') === 0) {
281 $tabletouse = $object->table_element;
282 $tablealiastouse = 'te';
283 if (!empty($arrayofgroupby[$gval])) {
284 $tmpval = explode('.', $gval);
285 $tabletouse = $arrayofgroupby[$gval]['table'];
286 $tablealiastouse = $tmpval[0];
287 }
288 //var_dump($tablealiastouse);exit;
289
290 //$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te";
291 $sql .= " FROM ".MAIN_DB_PREFIX.$tabletouse."_extrafields as ".$tablealiastouse;
292 } else {
293 $tabletouse = $object->table_element;
294 $tablealiastouse = 't';
295 if (!empty($arrayofgroupby[$gval])) {
296 $tmpval = explode('.', $gval);
297 $tabletouse = $arrayofgroupby[$gval]['table'];
298 $tablealiastouse = $tmpval[0];
299 }
300 $sql .= " FROM ".MAIN_DB_PREFIX.$tabletouse." as ".$tablealiastouse;
301 }
302
303 // Add a where here keeping only the citeria on $tabletouse
304 // TODO
305 /*$sqlfilters = ... GETPOST('search_component_params_hidden', 'alphanohtml');
306 if ($sqlfilters) {
307 $errormessage = '';
308 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
309 }*/
310
311 $sql .= " LIMIT ".((int) ($MAXUNIQUEVALFORGROUP + 1));
312
313 //print $sql;
314 $resql = $db->query($sql);
315 if (!$resql) {
316 dol_print_error($db);
317 }
318
319 while ($obj = $db->fetch_object($resql)) {
320 if (is_null($obj->val)) {
321 $keytouse = '__NULL__';
322 $valuetranslated = $langs->transnoentitiesnoconv("NotDefined");
323 } elseif ($obj->val === '') {
324 $keytouse = '';
325 $valuetranslated = $langs->transnoentitiesnoconv("Empty");
326 } else {
327 $keytouse = (string) $obj->val;
328 $valuetranslated = $obj->val;
329 }
330
331 $regs = array();
332 if (!empty($object->fields[$gvalwithoutprefix]['arrayofkeyval'])) {
333 $valuetranslated = $object->fields[$gvalwithoutprefix]['arrayofkeyval'][$obj->val];
334 if (is_null($valuetranslated)) {
335 $valuetranslated = $langs->transnoentitiesnoconv("UndefinedKey");
336 }
337 $valuetranslated = $langs->trans($valuetranslated);
338 } elseif (preg_match('/integer:([^:]+):([^:]+)$/', $object->fields[$gvalwithoutprefix]['type'], $regs)) {
339 $classname = $regs[1];
340 $classpath = $regs[2];
341 dol_include_once($classpath);
342 if (class_exists($classname)) {
343 $tmpobject = new $classname($db);
344 $tmpobject->fetch($obj->val);
345 foreach ($tmpobject->fields as $fieldkey => $field) {
346 if ($field['showoncombobox']) {
347 $valuetranslated = $tmpobject->$fieldkey;
348 //if ($valuetranslated == '-') $valuetranslated = $langs->transnoentitiesnoconv("Unknown")
349 break;
350 }
351 }
352 //$valuetranslated = $tmpobject->ref.'eee';
353 }
354 }
355
356 $arrayofvaluesforgroupby['g_'.$gkey][$keytouse] = $valuetranslated;
357 }
358 // Add also the possible NULL value if field is a parent field that is not a strict join
359 $tmpfield = explode('.', $gval);
360 if ($tmpfield[0] != 't' || (is_array($object->fields[$tmpfield[1]]) && empty($object->fields[$tmpfield[1]]['notnull']))) {
361 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");
362 //var_dump($gval); var_dump($object->fields);
363 $arrayofvaluesforgroupby['g_'.$gkey]['__NULL__'] = $langs->transnoentitiesnoconv("NotDefined");
364 }
365
366 asort($arrayofvaluesforgroupby['g_'.$gkey]);
367
368 // Add a protection/error to refuse the request if number of differentr values for the group by is higher than $MAXUNIQUEVALFORGROUP
369 if (count($arrayofvaluesforgroupby['g_'.$gkey]) > $MAXUNIQUEVALFORGROUP) {
370 $langs->load("errors");
371
372 if (strpos($fieldtocount, 'te') === 0) { // This is a field of an extrafield
373 //if (!empty($extrafields->attributes[$object->table_element]['langfile'][$gvalwithoutprefix])) {
374 // $langs->load($extrafields->attributes[$object->table_element]['langfile'][$gvalwithoutprefix]);
375 //}
376 $keyforlabeloffield = $extrafields->attributes[$object->table_element]['label'][$gvalwithoutprefix];
377 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
378 } elseif (strpos($fieldtocount, 't__') === 0) { // This is a field of a foreign key
379 $reg = array();
380 if (preg_match('/^(.*)\.(.*)/', $gvalwithoutprefix, $reg)) {
381 /*
382 $gvalwithoutprefix = preg_replace('/\..*$/', '', $gvalwithoutprefix);
383 $gvalwithoutprefix = preg_replace('/^t__/', '', $gvalwithoutprefix);
384 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
385 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield).'-'.$reg[2];
386 */
387 $labeloffield = $arrayofgroupby[$fieldtocount]['labelnohtml'];
388 } else {
389 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
390 }
391 } else { // This is a common field
392 $reg = array();
393 if (preg_match('/^(.*)\-(year|month|day)/', $gvalwithoutprefix, $reg)) {
394 $gvalwithoutprefix = preg_replace('/\-(year|month|day)/', '', $gvalwithoutprefix);
395 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
396 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield).'-'.$reg[2];
397 } else {
398 $keyforlabeloffield = $object->fields[$gvalwithoutprefix]['label'];
399 $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield);
400 }
401 }
402 //var_dump($object->fields);
403 setEventMessages($langs->trans("ErrorTooManyDifferentValueForSelectedGroupBy", $MAXUNIQUEVALFORGROUP, $labeloffield), null, 'warnings');
404 $search_groupby = array();
405 }
406
407 $db->free($resql);
408 }
409}
410//var_dump($arrayofvaluesforgroupby);exit;
411
412
413$tmparray = dol_getdate(dol_now());
414$endyear = $tmparray['year'];
415$endmonth = $tmparray['mon'];
416$datelastday = dol_get_last_day($endyear, $endmonth, 1);
417$startyear = $endyear - 2;
418
419$param = '';
420
421print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" autocomplete="off">';
422print '<input type="hidden" name="token" value="'.newToken().'">';
423print '<input type="hidden" name="action" value="viewgraph">';
424print '<input type="hidden" name="tabfamily" value="'.$tabfamily.'">';
425
426$viewmode = '';
427
428$viewmode .= '<div class="divadvancedsearchfield">';
429$arrayofgraphs = array('bars' => 'Bars', 'lines' => 'Lines'); // also 'pies'
430$viewmode .= '<div class="inline-block opacitymedium"><span class="fas fa-chart-area paddingright" title="'.$langs->trans("Graph").'"></span>'.$langs->trans("Graph").'</div> ';
431$viewmode .= $form->selectarray('search_graph', $arrayofgraphs, $search_graph, 0, 0, 0, '', 1, 0, 0, '', 'graphtype width100');
432$viewmode .= '</div>';
433
434$num = 0;
435$massactionbutton = '';
436$nav = '';
437$newcardbutton = '';
438$limit = 0;
439
440print_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);
441
442
443foreach ($newarrayoftype as $tmpkey => $tmpval) {
444 $newarrayoftype[$tmpkey]['label'] = img_picto('', $tmpval['picto'], 'class="pictofixedwidth"').$langs->trans($tmpval['label']);
445}
446
447print '<div class="liste_titre liste_titre_bydiv liste_titre_bydiv_inlineblock centpercent">';
448
449// Select object
450print '<div class="divadvancedsearchfield center floatnone">';
451print '<div class="inline-block"><span class="opacitymedium">'.$langs->trans("StatisticsOn").'</span></div> ';
452print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1, '', 0, 1);
453if (empty($conf->use_javascript_ajax)) {
454 print '<input type="submit" class="button buttongen button-save nomargintop" name="changeobjecttype" value="'.$langs->trans("Refresh").'">';
455} else {
456 print '<!-- js code to reload page with good object type -->
457 <script nonce="'.getNonce().'" type="text/javascript">
458 jQuery(document).ready(function() {
459 jQuery("#objecttype").change(function() {
460 console.log("Reload for "+jQuery("#objecttype").val());
461 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')) : '').'";
462 });
463 });
464 </script>';
465}
466print '</div><div class="clearboth"></div>';
467
468// Filter (you can use param &show_search_component_params_hidden=1 for debug)
469print '<div class="divadvancedsearchfield quatrevingtpercent">';
470print $form->searchComponent(array($object->element => $object->fields), $search_component_params, array(), $search_component_params_hidden);
471print '</div>';
472
473// YAxis (add measures into array)
474$count = 0;
475//var_dump($arrayofmesures);
476print '<div class="divadvancedsearchfield clearboth">';
477print '<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>';
478$simplearrayofmesures = array();
479foreach ($arrayofmesures as $key => $val) {
480 $simplearrayofmesures[$key] = $arrayofmesures[$key]['label'];
481}
482print $form->multiselectarray('search_measures', $simplearrayofmesures, $search_measures, 0, 0, 'minwidth300', 1, 0, '', '', $langs->trans("Measures")); // Fill the array $arrayofmeasures with possible fields
483print '</div>';
484
485// XAxis
486$count = 0;
487print '<div class="divadvancedsearchfield">';
488print '<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>';
489//var_dump($arrayofxaxis);
490print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis, $langs->trans("XAxis"), 'minwidth300 maxwidth400'); // Fill the array $arrayofxaxis with possible fields
491print '</div>';
492
493// Group by
494$count = 0;
495print '<div class="divadvancedsearchfield">';
496print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-horizontal paddingright pictofixedwidth" title="'.dol_escape_htmltag($langs->trans("GroupBy")).'"></span></div>';
497print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby, 'minwidth250 maxwidth300', $langs->trans("GroupBy")); // Fill the array $arrayofgroupby with possible fields
498print '</div>';
499
500
501if ($mode == 'grid') {
502 // YAxis
503 print '<div class="divadvancedsearchfield">';
504 foreach ($object->fields as $key => $val) {
505 if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) {
506 if (in_array($key, array('id', 'rowid', 'entity', 'last_main_doc', 'extraparams'))) {
507 continue;
508 }
509 if (preg_match('/^fk_/', $key)) {
510 continue;
511 }
512 if (in_array($val['type'], array('html', 'text'))) {
513 continue;
514 }
515 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
516 $arrayofyaxis['t.'.$key.'-year'] = array(
517 'label' => $langs->trans($val['label']).' ('.$YYYY.')',
518 'position' => $val['position'],
519 'table' => $object->table_element
520 );
521 $arrayofyaxis['t.'.$key.'-month'] = array(
522 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')',
523 'position' => $val['position'],
524 'table' => $object->table_element
525 );
526 $arrayofyaxis['t.'.$key.'-day'] = array(
527 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')',
528 'position' => $val['position'],
529 'table' => $object->table_element
530 );
531 } else {
532 $arrayofyaxis['t.'.$key] = array(
533 'label' => $val['label'],
534 'position' => (int) $val['position'],
535 'table' => $object->table_element
536 );
537 }
538 }
539 }
540 // Add measure from extrafields
541 if ($object->isextrafieldmanaged) {
542 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
543 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'))) {
544 $arrayofyaxis['te.'.$key] = array(
545 'label' => $extrafields->attributes[$object->table_element]['label'][$key],
546 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key],
547 'table' => $object->table_element
548 );
549 }
550 }
551 }
552 $arrayofyaxis = dol_sort_array($arrayofyaxis, 'position');
553 $arrayofyaxislabel = array();
554 foreach ($arrayofyaxis as $key => $val) {
555 $arrayofyaxislabel[$key] = $val['label'];
556 }
557 print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-vertical paddingright" title="'.$langs->trans("YAxis").'"></span>'.$langs->trans("YAxis").'</div> ';
558 print $form->multiselectarray('search_yaxis', $arrayofyaxislabel, $search_yaxis, 0, 0, 'minwidth100', 1);
559 print '</div>';
560}
561
562if ($mode == 'graph') {
563 //
564}
565
566print '<div class="divadvancedsearchfield">';
567print '<input type="submit" class="button buttongen button-save nomargintop" value="'.$langs->trans("Refresh").'">';
568print '</div>';
569print '</div>';
570print '</form>';
571
572// Generate the SQL request
573$sql = '';
574if (!empty($search_measures) && !empty($search_xaxis)) {
575 $errormessage = '';
576
577 $fieldid = 'rowid';
578
579 $sql = "SELECT ";
580 foreach ($search_xaxis as $key => $val) {
581 if (preg_match('/\-year$/', $val)) {
582 $tmpval = preg_replace('/\-year$/', '', $val);
583 $sql .= "DATE_FORMAT(".$tmpval.", '%Y') as x_".$key.', ';
584 } elseif (preg_match('/\-month$/', $val)) {
585 $tmpval = preg_replace('/\-month$/', '', $val);
586 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m') as x_".$key.', ';
587 } elseif (preg_match('/\-day$/', $val)) {
588 $tmpval = preg_replace('/\-day$/', '', $val);
589 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d') as x_".$key.', ';
590 } else {
591 $sql .= $val." as x_".$key.", ";
592 }
593 }
594 foreach ($search_groupby as $key => $val) {
595 if (preg_match('/\-year$/', $val)) {
596 $tmpval = preg_replace('/\-year$/', '', $val);
597 $sql .= "DATE_FORMAT(".$tmpval.", '%Y') as g_".$key.', ';
598 } elseif (preg_match('/\-month$/', $val)) {
599 $tmpval = preg_replace('/\-month$/', '', $val);
600 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m') as g_".$key.', ';
601 } elseif (preg_match('/\-day$/', $val)) {
602 $tmpval = preg_replace('/\-day$/', '', $val);
603 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d') as g_".$key.', ';
604 } else {
605 $sql .= $val." as g_".$key.", ";
606 }
607 }
608 foreach ($search_measures as $key => $val) {
609 if ($val == 't.count') {
610 $sql .= "COUNT(t.".$fieldid.") as y_".$key.', ';
611 } elseif (preg_match('/\-sum$/', $val)) {
612 $tmpval = preg_replace('/\-sum$/', '', $val);
613 $sql .= "SUM(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
614 } elseif (preg_match('/\-average$/', $val)) {
615 $tmpval = preg_replace('/\-average$/', '', $val);
616 $sql .= "AVG(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
617 } elseif (preg_match('/\-min$/', $val)) {
618 $tmpval = preg_replace('/\-min$/', '', $val);
619 $sql .= "MIN(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
620 } elseif (preg_match('/\-max$/', $val)) {
621 $tmpval = preg_replace('/\-max$/', '', $val);
622 $sql .= "MAX(".$db->ifsql($tmpval.' IS NULL', '0', $tmpval).") as y_".$key.", ";
623 }
624 }
625 $sql = preg_replace('/,\s*$/', '', $sql);
626 $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
627 // Add measure from extrafields
628 if ($object->isextrafieldmanaged) {
629 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te ON te.fk_object = t.".$fieldid;
630 }
631 // Add table for link on multientity
632 if ($object->ismultientitymanaged) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
633 if ($object->ismultientitymanaged == 1) {
634 // No table to add here
635 } else {
636 $tmparray = explode('@', $object->ismultientitymanaged);
637 $sql .= " INNER JOIN ".MAIN_DB_PREFIX.$tmparray[1]." as parenttableforentity ON t.".$tmparray[0]." = parenttableforentity.rowid";
638 $sql .= " AND parenttableforentity.entity IN (".getEntity($tmparray[1]).")";
639 }
640 }
641
642 // Init the list of tables added. We include by default always the main table.
643 $listoftablesalreadyadded = array($object->table_element => $object->table_element);
644
645 // Add LEFT JOIN for all parent tables mentionned into the Xaxis
646 //var_dump($arrayofxaxis); var_dump($search_xaxis);
647 foreach ($search_xaxis as $key => $val) {
648 if (!empty($arrayofxaxis[$val])) {
649 $tmpval = explode('.', $val);
650 //var_dump($arrayofgroupby);
651 $tmpforloop = dolExplodeIntoArray($arrayofxaxis[$val]['tablefromt'], ',');
652 foreach ($tmpforloop as $tmptable => $tmptablealias) {
653 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
654 $tmpforexplode = explode('__', $tmptablealias);
655 $endpart = end($tmpforexplode);
656 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
657
658 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
659 $listoftablesalreadyadded[$tmptable] = $tmptable;
660
661 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
662 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
663 $listoftablesalreadyadded[$tmptable] = $tmptable;
664 }
665 }
666 }
667 } else {
668 $errormessage = 'Found a key into search_xaxis not found into arrayofxaxis';
669 }
670 }
671
672 // Add LEFT JOIN for all parent tables mentionned into the Group by
673 //var_dump($arrayofgroupby); var_dump($search_groupby);
674 foreach ($search_groupby as $key => $val) {
675 if (!empty($arrayofgroupby[$val])) {
676 $tmpval = explode('.', $val);
677 //var_dump($arrayofgroupby[$val]); var_dump($tmpval);
678 $tmpforloop = dolExplodeIntoArray($arrayofgroupby[$val]['tablefromt'], ',');
679 foreach ($tmpforloop as $tmptable => $tmptablealias) {
680 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
681 $tmpforexplode = explode('__', $tmptablealias);
682 $endpart = end($tmpforexplode);
683 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
684
685 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
686 $listoftablesalreadyadded[$tmptable] = $tmptable;
687
688 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
689 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
690 $listoftablesalreadyadded[$tmptable] = $tmptable;
691 }
692 }
693 }
694 } else {
695 $errormessage = 'Found a key into search_groupby not found into arrayofgroupby';
696 }
697 }
698
699 // Add LEFT JOIN for all parent tables mentionned into the Yaxis
700 //var_dump($arrayofgroupby); var_dump($search_groupby);
701 foreach ($search_measures as $key => $val) {
702 if (!empty($arrayofmesures[$val])) {
703 $tmpval = explode('.', $val);
704 //var_dump($arrayofgroupby);
705 $tmpforloop = dolExplodeIntoArray($arrayofmesures[$val]['tablefromt'], ',');
706 foreach ($tmpforloop as $tmptable => $tmptablealias) {
707 if (! in_array($tmptable, $listoftablesalreadyadded)) { // We do not add join for main table and tables already added
708 $tmpforexplode = explode('__', $tmptablealias);
709 $endpart = end($tmpforexplode);
710 $parenttableandfield = preg_replace('/__'.$endpart.'$/', '', $tmptablealias).'.'.$endpart;
711
712 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable." as ".$db->sanitize($tmptablealias)." ON ".$db->sanitize($parenttableandfield)." = ".$db->sanitize($tmptablealias).".rowid";
713 $listoftablesalreadyadded[$tmptable] = $tmptable;
714
715 if (preg_match('/^te/', $tmpval[0]) && preg_replace('/^t_/', 'te_', $tmptablealias) == $tmpval[0]) {
716 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$tmptable."_extrafields as ".$db->sanitize($tmpval[0])." ON ".$db->sanitize($tmpval[0]).".fk_object = ".$db->sanitize($tmptablealias).".rowid";
717 $listoftablesalreadyadded[$tmptable] = $tmptable;
718 }
719 }
720 }
721 } else {
722 $errormessage = 'Found a key into search_measures not found into arrayofmesures';
723 }
724 }
725
726 $sql .= " WHERE 1 = 1";
727 if ($object->ismultientitymanaged == 1) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
728 $sql .= " AND t.entity IN (".getEntity($object->element).")";
729 }
730 // Add the where here
731 $sqlfilters = $search_component_params_hidden;
732 if ($sqlfilters) {
733 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage, 0, 0, 1);
734 }
735 $sql .= " GROUP BY ";
736 foreach ($search_xaxis as $key => $val) {
737 if (preg_match('/\-year$/', $val)) {
738 $tmpval = preg_replace('/\-year$/', '', $val);
739 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
740 } elseif (preg_match('/\-month$/', $val)) {
741 $tmpval = preg_replace('/\-month$/', '', $val);
742 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
743 } elseif (preg_match('/\-day$/', $val)) {
744 $tmpval = preg_replace('/\-day$/', '', $val);
745 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
746 } else {
747 $sql .= $val.", ";
748 }
749 }
750 foreach ($search_groupby as $key => $val) {
751 if (preg_match('/\-year$/', $val)) {
752 $tmpval = preg_replace('/\-year$/', '', $val);
753 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
754 } elseif (preg_match('/\-month$/', $val)) {
755 $tmpval = preg_replace('/\-month$/', '', $val);
756 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
757 } elseif (preg_match('/\-day$/', $val)) {
758 $tmpval = preg_replace('/\-day$/', '', $val);
759 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
760 } else {
761 $sql .= $val.', ';
762 }
763 }
764 $sql = preg_replace('/,\s*$/', '', $sql);
765 $sql .= ' ORDER BY ';
766 foreach ($search_xaxis as $key => $val) {
767 if (preg_match('/\-year$/', $val)) {
768 $tmpval = preg_replace('/\-year$/', '', $val);
769 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
770 } elseif (preg_match('/\-month$/', $val)) {
771 $tmpval = preg_replace('/\-month$/', '', $val);
772 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
773 } elseif (preg_match('/\-day$/', $val)) {
774 $tmpval = preg_replace('/\-day$/', '', $val);
775 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
776 } else {
777 $sql .= $val.', ';
778 }
779 }
780 foreach ($search_groupby as $key => $val) {
781 if (preg_match('/\-year$/', $val)) {
782 $tmpval = preg_replace('/\-year$/', '', $val);
783 $sql .= "DATE_FORMAT(".$tmpval.", '%Y'), ";
784 } elseif (preg_match('/\-month$/', $val)) {
785 $tmpval = preg_replace('/\-month$/', '', $val);
786 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m'), ";
787 } elseif (preg_match('/\-day$/', $val)) {
788 $tmpval = preg_replace('/\-day$/', '', $val);
789 $sql .= "DATE_FORMAT(".$tmpval.", '%Y-%m-%d'), ";
790 } else {
791 $sql .= $val.', ';
792 }
793 }
794 $sql = preg_replace('/,\s*$/', '', $sql);
795}
796//print $sql;
797
798if ($errormessage) {
799 print dol_escape_htmltag($errormessage);
800 $sql = '';
801}
802
803$legend = array();
804foreach ($search_measures as $key => $val) {
805 $legend[] = $langs->trans($arrayofmesures[$val]['label']);
806}
807
808$useagroupby = (is_array($search_groupby) && count($search_groupby));
809//var_dump($useagroupby);
810//var_dump($arrayofvaluesforgroupby);
811
812// Execute the SQL request
813$totalnbofrecord = 0;
814$data = array();
815if ($sql) {
816 $resql = $db->query($sql);
817 if (!$resql) {
818 dol_print_error($db);
819 }
820
821 $ifetch = 0;
822 $xi = 0;
823 $oldlabeltouse = '';
824 while ($obj = $db->fetch_object($resql)) {
825 $ifetch++;
826 if ($useagroupby) {
827 $xval = $search_xaxis[0];
828 $fieldforxkey = 'x_0';
829 $xlabel = $obj->$fieldforxkey;
830 $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
831
832 // Define $xlabel
833 if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
834 $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
835 }
836 $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined")));
837
838 if ($oldlabeltouse && ($labeltouse != $oldlabeltouse)) {
839 $xi++; // Increase $xi
840 }
841 //var_dump($labeltouse.' '.$oldlabeltouse.' '.$xi);
842 $oldlabeltouse = $labeltouse;
843
844 /* Example of value for $arrayofvaluesforgroupby
845 * array (size=1)
846 * 'g_0' =>
847 * array (size=6)
848 * 0 => string '0' (length=1)
849 * '' => string 'Empty' (length=5)
850 * '__NULL__' => string 'Not defined' (length=11)
851 * 'done' => string 'done' (length=4)
852 * 'processing' => string 'processing' (length=10)
853 * 'undeployed' => string 'undeployed' (length=10)
854 */
855 foreach ($search_measures as $key => $val) {
856 $gi = 0;
857 foreach ($search_groupby as $gkey) {
858 //var_dump('*** Fetch #'.$ifetch.' for labeltouse='.$labeltouse.' measure number '.$key.' and group g_'.$gi);
859 //var_dump($arrayofvaluesforgroupby);
860 foreach ($arrayofvaluesforgroupby['g_'.$gi] as $gvaluepossiblekey => $gvaluepossiblelabel) {
861 $ykeysuffix = $gvaluepossiblelabel;
862 $gvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $gval);
863
864 $fieldfory = 'y_'.$key;
865 $fieldforg = 'g_'.$gi;
866 $fieldforybis = 'y_'.$key.'_'.$ykeysuffix;
867 //var_dump('gvaluepossiblekey='.$gvaluepossiblekey.' gvaluepossiblelabel='.$gvaluepossiblelabel.' ykeysuffix='.$ykeysuffix.' gval='.$gval.' gvalwithoutsuffix='.$gvalwithoutprefix);
868 //var_dump('fieldforg='.$fieldforg.' obj->$fieldforg='.$obj->$fieldforg.' fieldfory='.$fieldfory.' obj->$fieldfory='.$obj->$fieldfory.' fieldforybis='.$fieldforybis);
869
870 if (!is_array($data[$xi])) {
871 $data[$xi] = array();
872 }
873
874 if (!array_key_exists('label', $data[$xi])) {
875 $data[$xi] = array();
876 $data[$xi]['label'] = $labeltouse;
877 }
878
879 $objfieldforg = $obj->$fieldforg;
880 if (is_null($objfieldforg)) {
881 $objfieldforg = '__NULL__';
882 }
883
884 if ($gvaluepossiblekey == '0') { // $gvaluepossiblekey can have type int or string. So we create a special if, used when value is '0'
885 //var_dump($objfieldforg.' == \'0\' -> '.($objfieldforg == '0'));
886 if ($objfieldforg == '0') {
887 // The record we fetch is for this group
888 $data[$xi][$fieldforybis] = $obj->$fieldfory;
889 } elseif (!isset($data[$xi][$fieldforybis])) {
890 // The record we fetch is not for this group
891 $data[$xi][$fieldforybis] = '0';
892 }
893 } else {
894 //var_dump((string) $objfieldforg.' === '.(string) $gvaluepossiblekey.' -> '.((string) $objfieldforg === (string) $gvaluepossiblekey));
895 if ((string) $objfieldforg === (string) $gvaluepossiblekey) {
896 // The record we fetch is for this group
897 $data[$xi][$fieldforybis] = $obj->$fieldfory;
898 } elseif (!isset($data[$xi][$fieldforybis])) {
899 // The record we fetch is not for this group
900 $data[$xi][$fieldforybis] = '0';
901 }
902 }
903 }
904 //var_dump($data[$xi]);
905 $gi++;
906 }
907 }
908 } else { // No group by
909 $xval = $search_xaxis[0];
910 $fieldforxkey = 'x_0';
911 $xlabel = $obj->$fieldforxkey;
912 $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
913
914 // Define $xlabel
915 if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
916 $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
917 }
918
919 $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined")));
920 $xarrayforallseries = array('label' => $labeltouse);
921 foreach ($search_measures as $key => $val) {
922 $fieldfory = 'y_'.$key;
923 $xarrayforallseries[$fieldfory] = $obj->$fieldfory;
924 }
925 $data[$xi] = $xarrayforallseries;
926 $xi++;
927 }
928 }
929
930 $totalnbofrecord = count($data);
931}
932//var_dump($data);
933
934
935print '<div class="customreportsoutput'.($totalnbofrecord ? '' : ' customreportsoutputnotdata').'">';
936
937
938if ($mode == 'grid') {
939 // TODO
940}
941
942if ($mode == 'graph') {
943 $WIDTH = '80%';
944 $HEIGHT = (empty($_SESSION['dol_screenheight']) ? 400 : $_SESSION['dol_screenheight'] - 500);
945
946 // Show graph
947 $px1 = new DolGraph();
948 $mesg = $px1->isGraphKo();
949 if (!$mesg) {
950 //var_dump($legend);
951 //var_dump($data);
952 $px1->SetData($data);
953 unset($data);
954
955 $arrayoftypes = array();
956 foreach ($search_measures as $key => $val) {
957 $arrayoftypes[] = $search_graph;
958 }
959
960 $px1->SetLegend($legend);
961 $px1->SetMinValue($px1->GetFloorMinValue());
962 $px1->SetMaxValue($px1->GetCeilMaxValue());
963 $px1->SetWidth($WIDTH);
964 $px1->SetHeight($HEIGHT);
965 $px1->SetYLabel($langs->trans("Y"));
966 $px1->SetShading(3);
967 $px1->SetHorizTickIncrement(1);
968 $px1->SetCssPrefix("cssboxes");
969 $px1->SetType($arrayoftypes);
970 $px1->mode = 'depth';
971 $px1->SetTitle('');
972
973 $dir = $conf->user->dir_temp;
974 dol_mkdir($dir);
975 $filenamenb = $dir.'/customreport_'.$object->element.'.png';
976 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=user&file=customreport_'.$object->element.'.png';
977
978 $px1->draw($filenamenb, $fileurlnb);
979
980 $texttoshow = $langs->trans("NoRecordFound");
981 if (!GETPOSTISSET('search_measures') || !GETPOSTISSET('search_xaxis')) {
982 $texttoshow = $langs->trans("SelectYourGraphOptionsFirst");
983 }
984
985 print $px1->show($totalnbofrecord ? 0 : $texttoshow);
986 }
987}
988
989if ($sql) {
990 // Show admin info
991 print '<br>'.info_admin($langs->trans("SQLUsedForExport").':<br> '.$sql, 0, 0, 1, '', 'TechnicalInformation');
992}
993
994print '<div>';
995
996if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
997 print dol_get_fiche_end();
998}
999
1000// End of page
1001llxFooter();
1002
1003$db->close();
1004
1005
1006
1007
1020function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesures, $level = 0, &$count = 0, &$tablepath = '')
1021{
1022 global $langs, $extrafields, $db;
1023
1024 if ($level > 10) { // Protection against infinite loop
1025 return $arrayofmesures;
1026 }
1027
1028 if (empty($tablepath)) {
1029 $tablepath = $object->table_element.'='.$tablealias;
1030 } else {
1031 $tablepath .= ','.$object->table_element.'='.$tablealias;
1032 }
1033
1034 if ($level == 0) {
1035 // Add the count of record only for the main/first level object. Parents are necessarly unique for each record.
1036 $arrayofmesures[$tablealias.'.count'] = array(
1037 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': Count',
1038 'labelnohtml' => $labelofobject.': Count',
1039 'position' => 0,
1040 'table' => $object->table_element,
1041 'tablefromt' => $tablepath
1042 );
1043 }
1044
1045 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1046
1047 // Add main fields of object
1048 foreach ($object->fields as $key => $val) {
1049 if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) {
1050 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1051 $arrayofmesures[$tablealias.'.'.$key.'-sum'] = array(
1052 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Sum").')</span>',
1053 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1054 'position' => ($position + ($count * 100000)).'.1',
1055 'table' => $object->table_element,
1056 'tablefromt' => $tablepath
1057 );
1058 $arrayofmesures[$tablealias.'.'.$key.'-average'] = array(
1059 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Average").')</span>',
1060 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1061 'position' => ($position + ($count * 100000)).'.2',
1062 'table' => $object->table_element,
1063 'tablefromt' => $tablepath
1064 );
1065 $arrayofmesures[$tablealias.'.'.$key.'-min'] = array(
1066 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Minimum").')</span>',
1067 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1068 'position' => ($position + ($count * 100000)).'.3',
1069 'table' => $object->table_element,
1070 'tablefromt' => $tablepath
1071 );
1072 $arrayofmesures[$tablealias.'.'.$key.'-max'] = array(
1073 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$langs->trans("Maximum").')</span>',
1074 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1075 'position' => ($position + ($count * 100000)).'.4',
1076 'table' => $object->table_element,
1077 'tablefromt' => $tablepath
1078 );
1079 }
1080 }
1081 // Add extrafields to Measures
1082 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1083 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1084 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'))) {
1085 $position = (!empty($val['position']) ? $val['position'] : 0);
1086 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-sum'] = array(
1087 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Sum").')</span>',
1088 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1089 'position' => ($position+($count * 100000)).'.1',
1090 'table' => $object->table_element,
1091 'tablefromt' => $tablepath
1092 );
1093 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-average'] = array(
1094 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Average").')</span>',
1095 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1096 'position' => ($position+($count * 100000)).'.2',
1097 'table' => $object->table_element,
1098 'tablefromt' => $tablepath
1099 );
1100 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-min'] = array(
1101 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Minimum").')</span>',
1102 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1103 'position' => ($position+($count * 100000)).'.3',
1104 'table' => $object->table_element,
1105 'tablefromt' => $tablepath
1106 );
1107 $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-max'] = array(
1108 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' <span class="opacitymedium">('.$langs->trans("Maximum").')</span>',
1109 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1110 'position' => ($position+($count * 100000)).'.4',
1111 'table' => $object->table_element,
1112 'tablefromt' => $tablepath
1113 );
1114 }
1115 }
1116 }
1117 // Add fields for parent objects
1118 foreach ($object->fields as $key => $val) {
1119 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1120 $tmptype = explode(':', $val['type'], 4);
1121 if ($tmptype[0] == 'integer' && !empty($tmptype[1]) && !empty($tmptype[2])) {
1122 $newobject = $tmptype[1];
1123 dol_include_once($tmptype[2]);
1124 if (class_exists($newobject)) {
1125 $tmpobject = new $newobject($db);
1126 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1127 $count++;
1128 $arrayofmesures = fillArrayOfMeasures($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofmesures, $level + 1, $count, $tablepath);
1129 } else {
1130 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1131 }
1132 }
1133 }
1134 }
1135
1136 return $arrayofmesures;
1137}
1138
1139
1152function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, $level = 0, &$count = 0, &$tablepath = '')
1153{
1154 global $langs, $extrafields, $db;
1155
1156 if ($level >= 3) { // Limit scan on 2 levels max
1157 return $arrayofxaxis;
1158 }
1159
1160 if (empty($tablepath)) {
1161 $tablepath = $object->table_element.'='.$tablealias;
1162 } else {
1163 $tablepath .= ','.$object->table_element.'='.$tablealias;
1164 }
1165
1166 $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);
1167 $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
1168 $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
1169 $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
1170 $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
1171 $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
1172
1173 /*if ($level > 0) {
1174 var_dump($object->element.' '.$object->isextrafieldmanaged);
1175 }*/
1176
1177 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1178
1179 // Add main fields of object
1180 foreach ($object->fields as $key => $val) {
1181 if (empty($val['measure'])) {
1182 if (in_array($key, array(
1183 'id', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
1184 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) {
1185 continue;
1186 }
1187 if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) {
1188 continue;
1189 }
1190 if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) {
1191 continue;
1192 }
1193 if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) {
1194 continue;
1195 }
1196 if (preg_match('/^pass/', $key)) {
1197 continue;
1198 }
1199 if (in_array($val['type'], array('html', 'text'))) {
1200 continue;
1201 }
1202 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
1203 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1204 $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array(
1205 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>',
1206 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1207 'position' => ($position + ($count * 100000)).'.1',
1208 'table' => $object->table_element,
1209 'tablefromt' => $tablepath
1210 );
1211 $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array(
1212 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1213 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1214 'position' => ($position + ($count * 100000)).'.2',
1215 'table' => $object->table_element,
1216 'tablefromt' => $tablepath
1217 );
1218 $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array(
1219 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1220 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1221 'position' => ($position + ($count * 100000)).'.3',
1222 'table' => $object->table_element,
1223 'tablefromt' => $tablepath
1224 );
1225 } else {
1226 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1227 $arrayofxaxis[$tablealias.'.'.$key] = array(
1228 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']),
1229 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1230 'position' => ($position + ($count * 100000)),
1231 'table' => $object->table_element,
1232 'tablefromt' => $tablepath
1233 );
1234 }
1235 }
1236 }
1237
1238 // Add extrafields to X-Axis
1239 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1240 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1241 if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') {
1242 continue;
1243 }
1244 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
1245 continue;
1246 }
1247
1248 if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('timestamp', 'date', 'datetime'))) {
1249 $position = (empty($extrafields->attributes[$object->table_element]['pos'][$key]) ? 0 : intVal($extrafields->attributes[$object->table_element]['pos'][$key]));
1250 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-year'] = array(
1251 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.')</span>',
1252 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1253 'position' => ($position + ($count * 100000)).'.1',
1254 'table' => $object->table_element,
1255 'tablefromt' => $tablepath
1256 );
1257 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-month'] = array(
1258 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1259 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1260 'position' => ($position + ($count * 100000)).'.2',
1261 'table' => $object->table_element,
1262 'tablefromt' => $tablepath
1263 );
1264 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-day'] = array(
1265 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1266 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1267 'position' => ($position + ($count * 100000)).'.3',
1268 'table' => $object->table_element,
1269 'tablefromt' => $tablepath
1270 );
1271 } else {
1272 $arrayofxaxis[preg_replace('/^t/', 'te', $tablealias).'.'.$key] = array(
1273 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val),
1274 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1275 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000),
1276 'table' => $object->table_element,
1277 'tablefromt' => $tablepath
1278 );
1279 }
1280 }
1281 }
1282
1283 // Add fields for parent objects
1284 foreach ($object->fields as $key => $val) {
1285 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1286 $tmptype = explode(':', $val['type'], 4);
1287 if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) {
1288 $newobject = $tmptype[1];
1289 dol_include_once($tmptype[2]);
1290 if (class_exists($newobject)) {
1291 $tmpobject = new $newobject($db);
1292 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1293 $count++;
1294 $arrayofxaxis = fillArrayOfXAxis($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofxaxis, $level + 1, $count, $tablepath);
1295 } else {
1296 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1297 }
1298 }
1299 }
1300 }
1301
1302 return $arrayofxaxis;
1303}
1304
1305
1318function fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroupby, $level = 0, &$count = 0, &$tablepath = '')
1319{
1320 global $langs, $extrafields, $db;
1321
1322 if ($level >= 3) {
1323 return $arrayofgroupby;
1324 }
1325
1326 if (empty($tablepath)) {
1327 $tablepath = $object->table_element.'='.$tablealias;
1328 } else {
1329 $tablepath .= ','.$object->table_element.'='.$tablealias;
1330 }
1331
1332 $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);
1333 $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
1334 $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
1335 $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
1336 $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
1337 $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
1338
1339 // Note: here $tablealias can be 't' or 't__fk_contract' or 't_fk_contract_fk_soc'
1340
1341 // Add main fields of object
1342 foreach ($object->fields as $key => $val) {
1343 if (empty($val['isameasure'])) {
1344 if (in_array($key, array(
1345 'id', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
1346 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) {
1347 continue;
1348 }
1349 if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) {
1350 continue;
1351 }
1352 if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) {
1353 continue;
1354 }
1355 if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) {
1356 continue;
1357 }
1358 if (preg_match('/^pass/', $key)) {
1359 continue;
1360 }
1361 if (in_array($val['type'], array('html', 'text'))) {
1362 continue;
1363 }
1364 if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
1365 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1366 $arrayofgroupby[$tablealias.'.'.$key.'-year'] = array(
1367 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>',
1368 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1369 'position' => ($position + ($count * 100000)).'.1',
1370 'table' => $object->table_element,
1371 'tablefromt' => $tablepath
1372 );
1373 $arrayofgroupby[$tablealias.'.'.$key.'-month'] = array(
1374 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1375 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1376 'position' => ($position + ($count * 100000)).'.2',
1377 'table' => $object->table_element,
1378 'tablefromt' => $tablepath
1379 );
1380 $arrayofgroupby[$tablealias.'.'.$key.'-day'] = array(
1381 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1382 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1383 'position' => ($position + ($count * 100000)).'.3',
1384 'table' => $object->table_element,
1385 'tablefromt' => $tablepath
1386 );
1387 } else {
1388 $position = (empty($val['position']) ? 0 : intVal($val['position']));
1389 $arrayofgroupby[$tablealias.'.'.$key] = array(
1390 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']),
1391 'labelnohtml' => $labelofobject.': '.$langs->trans($val['label']),
1392 'position' => ($position + ($count * 100000)),
1393 'table' => $object->table_element,
1394 'tablefromt' => $tablepath
1395 );
1396 }
1397 }
1398 }
1399
1400 // Add extrafields to Group by
1401 if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) {
1402 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
1403 if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') {
1404 continue;
1405 }
1406 if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
1407 continue;
1408 }
1409
1410 if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('timestamp', 'date', 'datetime'))) {
1411 $position = (empty($extrafields->attributes[$object->table_element]['pos'][$key]) ? 0 : intVal($extrafields->attributes[$object->table_element]['pos'][$key]));
1412 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-year'] = array(
1413 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.')</span>',
1414 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1415 'position' => ($position + ($count * 100000)).'.1',
1416 'table' => $object->table_element,
1417 'tablefromt' => $tablepath
1418 );
1419 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-month'] = array(
1420 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
1421 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1422 'position' => ($position + ($count * 100000)).'.2',
1423 'table' => $object->table_element,
1424 'tablefromt' => $tablepath
1425 );
1426 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-day'] = array(
1427 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
1428 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1429 'position' => ($position + ($count * 100000)).'.3',
1430 'table' => $object->table_element,
1431 'tablefromt' => $tablepath
1432 );
1433 } else {
1434 $arrayofgroupby[preg_replace('/^t/', 'te', $tablealias).'.'.$key] = array(
1435 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val),
1436 'labelnohtml' => $labelofobject.': '.$langs->trans($val),
1437 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000),
1438 'table' => $object->table_element,
1439 'tablefromt' => $tablepath
1440 );
1441 }
1442 }
1443 }
1444
1445 // Add fields for parent objects
1446 foreach ($object->fields as $key => $val) {
1447 if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
1448 $tmptype = explode(':', $val['type'], 4);
1449 if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) {
1450 $newobject = $tmptype[1];
1451 dol_include_once($tmptype[2]);
1452 if (class_exists($newobject)) {
1453 $tmpobject = new $newobject($db);
1454 //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
1455 $count++;
1456 $arrayofgroupby = fillArrayOfGroupBy($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofgroupby, $level + 1, $count, $tablepath);
1457 } else {
1458 print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."<br>\n";
1459 }
1460 }
1461 }
1462 }
1463
1464 return $arrayofgroupby;
1465}
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
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:613
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.