Completed
Branch develop (984435)
by
unknown
36:46
created

BlockedLog::getLog()   F

Complexity

Conditions 15
Paths 2048

Size

Total Lines 61
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 35
nc 2048
nop 11
dl 0
loc 61
rs 2.9944
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2017 ATM Consulting      <[email protected]>
3
 * Copyright (C) 2017 Laurent Destailleur <[email protected]>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
 *
18
 * See https://medium.com/@lhartikk/a-blockchain-in-200-lines-of-code-963cc1cc0e54
19
 */
20
21
/**
22
 *	Class to manage Blocked Log
23
 */
24
25
class BlockedLog
26
{
27
	/**
28
	 * Id of the log
29
	 * @var int
30
	 */
31
	public $id;
32
	/**
33
	 * Entity
34
	 * @var int
35
	 */
36
	public $entity;
37
38
	public $error = '';
39
	public $errors = array();
40
41
	/**
42
	 * Unique fingerprint of the log
43
	 * @var string
44
	 */
45
	public $signature = '';
46
47
	/**
48
	 * Unique fingerprint of the line log content
49
	 * @var string
50
	 */
51
	public $signature_line = '';
52
53
	public $amounts = null;
54
55
	/**
56
	 * trigger action
57
	 * @var string
58
	 */
59
	public $action = '';
60
61
	/**
62
	 * Object element
63
	 * @var string
64
	 */
65
	public $element = '';
66
67
	/**
68
	 * Object id
69
	 * @var int
70
	 */
71
	public $fk_object = 0;
72
73
	/**
74
	 * Log certified by remote authority or not
75
	 * @var boolean
76
	 */
77
	public $certified = false;
78
79
	/**
80
	 * Author
81
	 * @var int
82
	 */
83
	public $fk_user = 0;
84
85
	public $date_creation;
86
	public $date_modification;
87
88
	public $date_object = 0;
89
90
	public $ref_object = '';
91
92
	public $object_data = null;
93
94
	/**
95
	 * Array of tracked event codes
96
	 * @var string[]
97
	 */
98
	public $trackedevents = array();
99
100
101
102
	/**
103
	 *      Constructor
104
	 *
105
	 *      @param		DoliDB		$db      Database handler
106
	 */
107
	public function __construct(DoliDB $db)
108
	{
109
		global $conf;
110
111
		$this->db = $db;
112
113
		$this->trackedevents = array();
114
115
		if ($conf->facture->enabled) $this->trackedevents['BILL_VALIDATE']='logBILL_VALIDATE';
116
		if ($conf->facture->enabled) $this->trackedevents['BILL_DELETE']='logBILL_DELETE';
117
		if ($conf->facture->enabled) $this->trackedevents['BILL_SENTBYMAIL']='logBILL_SENTBYMAIL';
118
		if ($conf->facture->enabled) $this->trackedevents['DOC_DOWNLOAD']='BlockedLogBillDownload';
119
		if ($conf->facture->enabled) $this->trackedevents['DOC_PREVIEW']='BlockedLogBillPreview';
120
121
		if ($conf->facture->enabled) $this->trackedevents['PAYMENT_CUSTOMER_CREATE']='logPAYMENT_CUSTOMER_CREATE';
122
		if ($conf->facture->enabled) $this->trackedevents['PAYMENT_CUSTOMER_DELETE']='logPAYMENT_CUSTOMER_DELETE';
123
124
		/* Supplier
125
		if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate';
126
		if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete';
127
		if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done
128
		if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload';		// Trigger key does not exists, we want just into array to list it as done
129
		if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview';		// Trigger key does not exists, we want just into array to list it as done
130
131
		if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate';
132
		if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate';
133
		*/
134
135
		if ($conf->don->enabled) $this->trackedevents['DON_VALIDATE']='logDON_VALIDATE';
136
		if ($conf->don->enabled) $this->trackedevents['DON_DELETE']='logDON_DELETE';
137
		//if ($conf->don->enabled) $this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL';
138
139
		if ($conf->don->enabled) $this->trackedevents['DONATION_PAYMENT_CREATE']='logDONATION_PAYMENT_CREATE';
140
		if ($conf->don->enabled) $this->trackedevents['DONATION_PAYMENT_DELETE']='logDONATION_PAYMENT_DELETE';
141
142
		/*
143
		if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate';
144
		if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate';
145
		if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate';
146
		*/
147
148
		if ($conf->adherent->enabled) $this->trackedevents['MEMBER_SUBSCRIPTION_CREATE']='logMEMBER_SUBSCRIPTION_CREATE';
149
		if ($conf->adherent->enabled) $this->trackedevents['MEMBER_SUBSCRIPTION_MODIFY']='logMEMBER_SUBSCRIPTION_MODIFY';
150
		if ($conf->adherent->enabled) $this->trackedevents['MEMBER_SUBSCRIPTION_DELETE']='logMEMBER_SUBSCRIPTION_DELETE';
151
152
		/*
153
		 $trackedevents['PAYMENT_VARIOUS_CREATE']='BlockedLogVariousPaymentCreate';
154
		 $trackedevents['PAYMENT_VARIOUS_MODIFY']='BlockedLogVariousPaymentModify';
155
		 $trackedevents['PAYMENT_VARIOUS_DELETE']='BlockedLogVariousPaymentDelete';
156
		*/
157
	}
158
159
	/**
160
	 *  Try to retrieve source object (it it still exists)
161
	 */
162
	public function getObjectLink()
163
	{
164
		global $langs;
165
166
		if($this->element === 'facture') {
167
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
168
169
			$object = new Facture($this->db);
170
			if ($object->fetch($this->fk_object)>0) {
171
				return $object->getNomUrl(1);
172
			}
173
			else{
174
				$this->error++;
175
			}
176
		}
177
		if($this->element === 'invoice_supplier') {
178
			require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
179
180
			$object = new FactureFournisseur($this->db);
181
			if ($object->fetch($this->fk_object)>0) {
182
				return $object->getNomUrl(1);
183
			}
184
			else{
185
				$this->error++;
186
			}
187
		}
188
		else if($this->element === 'payment') {
189
			require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
190
191
			$object = new Paiement($this->db);
192
			if ($object->fetch($this->fk_object)>0) {
193
				return $object->getNomUrl(1);
194
			}
195
			else{
196
				$this->error++;
197
			}
198
		}
199
		else if($this->element === 'payment_supplier') {
200
			require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
201
202
			$object = new PaiementFourn($this->db);
203
			if ($object->fetch($this->fk_object)>0) {
204
				return $object->getNomUrl(1);
205
			}
206
			else{
207
				$this->error++;
208
			}
209
		}
210
		else if($this->element === 'payment_donation') {
211
			require_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php';
212
213
			$object = new PaymentDonation($this->db);
214
			if ($object->fetch($this->fk_object)>0) {
215
				return $object->getNomUrl(1);
216
			}
217
			else{
218
				$this->error++;
219
			}
220
		}
221
		else if($this->element === 'don' || $this->element === 'donation') {
222
			require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
223
224
			$object = new Don($this->db);
225
			if ($object->fetch($this->fk_object)>0) {
226
				return $object->getNomUrl(1);
227
			}
228
			else{
229
				$this->error++;
230
			}
231
		}
232
		else if ($this->action == 'MODULE_SET')
233
		{
234
			return '<i class="opacitymedium">System to track events into unalterable logs were enabled</i>';
235
		}
236
		else if ($this->action == 'MODULE_RESET')
237
		{
238
			if ($this->signature == '0000000000')
239
			{
240
				return '<i class="opacitymedium">System to track events into unalterable logs were disabled after some recording were done. We saved a special Fingerprint to track the chain as broken.</i>';
241
			}
242
			else
243
			{
244
				return '<i class="opacitymedium">System to track events into unalterable logs were disabled. This is possible because no record were done yet.</i>';
245
			}
246
		}
247
248
		return '<i class="opacitymedium">'.$langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object).'</i>';
249
250
	}
251
252
	/**
253
	 *      try to retrieve user author
254
	 */
255
	public function getUser()
256
	{
257
		global $langs, $cachedUser;
258
259
		if(empty($cachedUser))$cachedUser=array();
260
261
		if(empty($cachedUser[$this->fk_user])) {
262
			$u=new User($this->db);
263
			if($u->fetch($this->fk_user)>0) {
264
				$cachedUser[$this->fk_user] = $u;
265
			}
266
		}
267
268
		if(!empty($cachedUser[$this->fk_user])) {
269
			return $cachedUser[$this->fk_user]->getNomUrl(1);
270
		}
271
272
		return $langs->trans('ImpossibleToRetrieveUser', $this->fk_user);
273
	}
274
275
	/**
276
	 *      Populate properties of log from object data
277
	 *
278
	 *      @param		Object		$object     object to store
279
	 *      @param		string		$action     action
280
	 *      @param		string		$amounts    amounts
281
	 *      @return		int						>0 if OK, <0 if KO
282
	 */
283
	public function setObjectData(&$object, $action, $amounts)
284
	{
285
		global $langs, $user, $mysoc;
286
287
		// Generic fields
288
289
		// action
290
		$this->action = $action;
291
		// amount
292
		$this->amounts= $amounts;
293
		// date
294
		if ($object->element == 'payment' || $object->element == 'payment_supplier')
295
		{
296
			$this->date_object = $object->datepaye;
297
		}
298
		elseif ($object->element=='payment_salary')
299
		{
300
			$this->date_object = $object->datev;
301
		}
302
		elseif ($object->element == 'payment_donation')
303
		{
304
			$this->date_object = $object->datepaid?$object->datepaid:$object->datep;
305
		}
306
		else {
307
			$this->date_object = $object->date;
308
		}
309
		// ref
310
		$this->ref_object = ((! empty($object->newref)) ? $object->newref : $object->ref);		// newref is set when validating a draft, ref is set in other cases
311
		// type of object
312
		$this->element = $object->element;
313
		// id of object
314
		$this->fk_object = $object->id;
315
316
		$this->object_data=new stdClass();
317
318
		// Add thirdparty info
319
		if (empty($object->thirdparty) && method_exists($object, 'fetch_thirdparty')) $object->fetch_thirdparty();
320
		if (! empty($object->thirdparty))
321
		{
322
			$this->object_data->thirdparty = new stdClass();
323
324
			foreach($object->thirdparty as $key=>$value)
325
			{
326
				if (in_array($key, array('fields'))) continue;	// Discard some properties
327
				if (! in_array($key, array(
328
				'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode',
329
				'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
330
				))) continue;								// Discard if not into a dedicated list
331
				if (!is_object($value)) $this->object_data->thirdparty->{$key} = $value;
332
			}
333
		}
334
335
		// Add company info
336
		if (! empty($mysoc))
337
		{
338
			$this->object_data->mycompany = new stdClass();
339
340
			foreach($mysoc as $key=>$value)
341
			{
342
				if (in_array($key, array('fields'))) continue;	// Discard some properties
343
				if (! in_array($key, array(
344
				'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode',
345
				'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
346
				))) continue;									// Discard if not into a dedicated list
347
				if (!is_object($value)) $this->object_data->mycompany->{$key} = $value;
348
			}
349
		}
350
351
		// Add user info
352
		$this->fk_user = $user->id;
353
		$this->user_fullname = $user->getFullName($langs);
354
355
		// Field specific to object
356
357
		if ($this->element == 'facture')
358
		{
359
			foreach($object as $key=>$value)
360
			{
361
				if (in_array($key, array('fields'))) continue;	// Discard some properties
362
				if (! in_array($key, array(
363
				'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
364
				))) continue;									// Discard if not into a dedicated list
365
				if (!is_object($value)) $this->object_data->{$key} = $value;
366
			}
367
		}
368
		elseif ($this->element == 'invoice_supplier')
369
		{
370
			foreach($object as $key=>$value)
371
			{
372
				if (in_array($key, array('fields'))) continue;	// Discard some properties
373
				if (! in_array($key, array(
374
				'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
375
				))) continue;									// Discard if not into a dedicated list
376
				if (!is_object($value)) $this->object_data->{$key} = $value;
377
			}
378
		}
379
		elseif ($this->element == 'payment' || $this->element == 'payment_supplier' || $this->element == 'payment_donation')
380
		{
381
			$datepayment = $object->datepaye?$object->datepaye:($object->datepaid?$object->datepaid:$object->datep);
382
			$paymenttypeid = $object->paiementid?$object->paiementid:$object->paymenttype;
383
384
			$this->object_data->ref = $object->ref;
385
			$this->object_data->date = $datepayment;
386
			$this->object_data->type_code = dol_getIdFromCode($this->db, $paymenttypeid, 'c_paiement', 'id', 'code');
387
			$this->object_data->payment_num = $object->num_paiement;
388
			//$this->object_data->fk_account = $object->fk_account;
389
			$this->object_data->note = $object->note;
390
			//var_dump($this->object_data);exit;
391
392
			$totalamount=0;
393
394
			$paymentpartnumber=0;
395
			foreach($object->amounts as $objid => $amount)
396
			{
397
				if (empty($amount)) continue;
398
399
				$totalamount += $amount;
400
401
				if ($this->element == 'payment_supplier')
402
				{
403
					include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
404
					$tmpobject = new FactureFournisseur($this->db);
405
				}
406
				elseif ($this->element == 'payment')
407
				{
408
					include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
409
					$tmpobject = new Facture($this->db);
410
				}
411
				elseif ($this->element == 'payment_donation')
412
				{
413
					include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
414
					$tmpobject = new Don($this->db);
415
				}
416
417
				$result = $tmpobject->fetch($objid);
0 ignored issues
show
Bug introduced by
The variable $tmpobject does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
418
				if ($result <= 0)
419
				{
420
					$this->error = $tmpobject->error;
421
					$this->errors = $tmpobject->errors;
422
					return -1;
423
				}
424
425
				$paymentpart = new stdClass();
426
				$paymentpart->amount = $amount;
427
428
				if ($this->element != 'payment_donation')
429
				{
430
					$result = $tmpobject->fetch_thirdparty();
431
					if ($result <= 0)
432
					{
433
						$this->error = $tmpobject->error;
434
						$this->errors = $tmpobject->errors;
435
						return -1;
436
					}
437
438
					$paymentpart->thirdparty = new stdClass();
439
					foreach($tmpobject->thirdparty as $key=>$value)
440
					{
441
						if (in_array($key, array('fields'))) continue;	// Discard some properties
442
						if (! in_array($key, array(
443
						'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode',
444
						'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
445
						))) continue;									// Discard if not into a dedicated list
446
						if (!is_object($value)) $paymentpart->thirdparty->{$key} = $value;
447
					}
448
				}
449
450
				// Init object to avoid warnings
451
				if ($this->element == 'payment_donation') $paymentpart->donation = new stdClass();
452
				else $paymentpart->invoice = new stdClass();
453
454
				foreach($tmpobject as $key=>$value)
455
				{
456
					if (in_array($key, array('fields'))) continue;	// Discard some properties
457
					if (! in_array($key, array(
458
					'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
459
					))) continue;									// Discard if not into a dedicated list
460
					if (!is_object($value))
461
					{
462
						if ($this->element == 'payment_donation') $paymentpart->donation->{$key} = $value;
463
						else $paymentpart->invoice->{$key} = $value;
464
					}
465
				}
466
467
				$paymentpartnumber++;
468
				$this->object_data->payment_part[$paymentpartnumber] = $paymentpart;
469
			}
470
471
			$this->object_data->amount = $totalamount;
472
		}
473
		elseif($this->element == 'payment_salary')
474
		{
475
			$this->object_data->amounts = array($object->amount);
476
		}
477
478
		return 1;
479
	}
480
481
	/**
482
	 *	Get object from database
483
	 *
484
	 *	@param      int		$id       	Id of object to load
485
	 *	@return     int         			>0 if OK, <0 if KO, 0 if not found
486
	 */
487
	public function fetch($id) {
488
489
		global $langs;
490
491
		dol_syslog(get_class($this)."::fetch id=".$id, LOG_DEBUG);
492
493
		if (empty($id))
494
		{
495
			$this->error='BadParameter';
496
			return -1;
497
		}
498
499
		$langs->load("blockedlog");
500
501
		$sql = "SELECT b.rowid, b.date_creation, b.signature, b.signature_line, b.amounts, b.action, b.element, b.fk_object, b.entity,";
502
		$sql.= " b.certified, b.tms, b.fk_user, b.user_fullname, b.date_object, b.ref_object, b.object_data";
503
		$sql.= " FROM ".MAIN_DB_PREFIX."blockedlog as b";
504
		if ($id) $sql.= " WHERE b.rowid = ". $id;
505
506
		$resql=$this->db->query($sql);
507
		if ($resql)
508
		{
509
			if ($this->db->num_rows($resql))
510
			{
511
				$obj = $this->db->fetch_object($resql);
512
513
				$this->id				= $obj->rowid;
514
				$this->entity			= $obj->entity;
515
				$this->ref				= $obj->rowid;
516
517
				$this->date_creation    = $this->db->jdate($obj->date_creation);
518
				$this->tms				= $this->db->jdate($obj->tms);
519
520
				$this->amounts			= (double) $obj->amounts;
521
				$this->action			= $obj->action;
522
				$this->element			= $obj->element;
523
524
				$this->fk_object		= $obj->fk_object;
525
				$this->date_object		= $this->db->jdate($obj->date_object);
526
				$this->ref_object		= $obj->ref_object;
527
528
				$this->fk_user 			= $obj->fk_user;
529
				$this->user_fullname	= $obj->user_fullname;
530
531
				$this->object_data		= unserialize($obj->object_data);
532
533
				$this->signature		= $obj->signature;
534
				$this->signature_line	= $obj->signature_line;
535
				$this->certified		= ($obj->certified == 1);
536
537
				return 1;
538
			}
539
			else
540
			{
541
				$this->error=$langs->trans("RecordNotFound");
542
				return 0;
543
			}
544
		}
545
		else
546
		{
547
			$this->error=$this->db->error();
548
			return -1;
549
		}
550
551
	}
552
553
	/**
554
	 *	Set block certified by authority
555
	 *
556
	 *	@return	boolean
557
	 */
558
	public function setCertified() {
559
560
		$res = $this->db->query("UPDATE ".MAIN_DB_PREFIX."blockedlog SET certified=1 WHERE rowid=".$this->id);
561
		if($res===false) return false;
562
563
		return true;
564
565
566
	}
567
568
	/**
569
	 *	Create blocked log in database.
570
	 *
571
	 *	@param	User	$user      			Object user that create
572
	 *  @param	int		$forcesignature		Force signature (for example '0000000000' when we disabled the module)
573
	 *	@return	int							<0 if KO, >0 if OK
574
	 */
575
	public function create($user, $forcesignature='') {
576
577
		global $conf,$langs,$hookmanager;
578
579
		$langs->load('blockedlog');
580
581
		$error=0;
582
583
		// Clean data
584
		$this->amounts=(double) $this->amounts;
585
586
		dol_syslog(get_class($this).'::create action='.$this->action.' fk_user='.$this->fk_user.' user_fullname='.$this->user_fullname, LOG_DEBUG);
587
588
		// Check parameters/properties
589
		if (! isset($this->amounts))	// amount can be 0 for some events (like when module is disabled)
590
		{
591
			$this->error=$langs->trans("BlockLogNeedAmountsValue");
592
			dol_syslog($this->error, LOG_WARNING);
593
			return -1;
594
		}
595
596
		if (empty($this->element)) {
597
			$this->error=$langs->trans("BlockLogNeedElement");
598
			dol_syslog($this->error, LOG_WARNING);
599
			return -2;
600
		}
601
602
		if (empty($this->action) || empty($this->fk_user) || empty($this->user_fullname)) {
603
			$this->error=$langs->trans("BadParameterWhenCallingCreateOfBlockedLog");
604
			dol_syslog($this->error, LOG_WARNING);
605
			return -3;
606
		}
607
608
		$this->date_creation = dol_now();
609
610
		$this->db->begin();
611
612
		$previoushash = $this->getPreviousHash(1, 0);	// This get last record and lock database until insert is done
613
614
		$keyforsignature = $this->buildKeyForSignature();
615
616
		$this->signature_line = dol_hash($keyforsignature, '5');		// Not really usefull
617
		$this->signature = dol_hash($previoushash . $keyforsignature, '5');
618
		if ($forcesignature) $this->signature = $forcesignature;
619
		//var_dump($keyforsignature);var_dump($previoushash);var_dump($this->signature_line);var_dump($this->signature);
620
621
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog (";
622
		$sql.= " date_creation,";
623
		$sql.= " action,";
624
		$sql.= " amounts,";
625
		$sql.= " signature,";
626
		$sql.= " signature_line,";
627
		$sql.= " element,";
628
		$sql.= " fk_object,";
629
		$sql.= " date_object,";
630
		$sql.= " ref_object,";
631
		$sql.= " object_data,";
632
		$sql.= " certified,";
633
		$sql.= " fk_user,";
634
		$sql.= " user_fullname,";
635
		$sql.= " entity";
636
		$sql.= ") VALUES (";
637
		$sql.= "'".$this->db->idate($this->date_creation)."',";
638
		$sql.= "'".$this->db->escape($this->action)."',";
639
		$sql.= $this->amounts.",";
640
		$sql.= "'".$this->db->escape($this->signature)."',";
641
		$sql.= "'".$this->db->escape($this->signature_line)."',";
642
		$sql.= "'".$this->db->escape($this->element)."',";
643
		$sql.= $this->fk_object.",";
644
		$sql.= "'".$this->db->idate($this->date_object)."',";
645
		$sql.= "'".$this->db->escape($this->ref_object)."',";
646
		$sql.= "'".$this->db->escape(serialize($this->object_data))."',";
647
		$sql.= "0,";
648
		$sql.= $this->fk_user.",";
649
		$sql.= "'".$this->db->escape($this->user_fullname)."',";
650
		$sql.= ($this->entity ? $this->entity : $conf->entity);
651
		$sql.= ")";
652
653
		$res = $this->db->query($sql);
654
		if ($res)
655
		{
656
			$id = $this->db->last_insert_id(MAIN_DB_PREFIX."blockedlog");
657
658
			if ($id > 0)
659
			{
660
				$this->id = $id;
661
662
				$this->db->commit();
663
664
				return $this->id;
665
			}
666
			else
667
			{
668
				$this->db->rollback();
669
				return -2;
670
			}
671
		}
672
		else
673
		{
674
			$this->error=$this->db->error();
675
			$this->db->rollback();
676
			return -1;
677
		}
678
679
		// The commit will release the lock so we can insert nex record
680
	}
681
682
	/**
683
	 *	Check if current signature still correct compared to the value in chain
684
	 *
685
	 *	@param	string		$previoushash		If previous signature hash is known, we can provide it to avoid to make a search of it in database.
686
	 *	@return	boolean							True if OK, False if KO
687
	 */
688
	public function checkSignature($previoushash='')
689
	{
690
		if (empty($previoushash))
691
		{
692
			$previoushash = $this->getPreviousHash(0, $this->id);
693
		}
694
		// Recalculate hash
695
		$keyforsignature = $this->buildKeyForSignature();
696
697
		$signature_line = dol_hash($keyforsignature, '5');		// Not really usefull
698
		$signature = dol_hash($previoushash . $keyforsignature, '5');
699
		//var_dump($previoushash); var_dump($keyforsignature); var_dump($signature_line); var_dump($signature);
700
701
		$res = ($signature === $this->signature);
702
703
		if (!$res) {
704
			$this->error = 'Signature KO';
705
		}
706
707
		return $res;
708
	}
709
710
	/**
711
	 * Return a string for signature
712
	 *
713
	 * @return string		Key for signature
714
	 */
715
	private function buildKeyForSignature()
716
	{
717
		//print_r($this->object_data);
718
		return $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname.'|'.print_r($this->object_data, true);
719
	}
720
721
722
	/**
723
	 *	Get previous signature/hash in chain
724
	 *
725
	 *	@param int	$withlock		1=With a lock
726
	 *	@param int	$beforeid		ID of a record
727
	 *  @return	string				Hash of previous record (if beforeid is defined) or hash of last record (if beforeid is 0)
728
	 */
729
	 public function getPreviousHash($withlock=0, $beforeid=0)
730
	 {
731
		global $conf;
732
733
		$previoussignature='';
734
735
	 	$sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog";
736
	 	$sql.= " WHERE entity=".$conf->entity;
737
	 	if ($beforeid) $sql.= " AND rowid < ".(int) $beforeid;
738
	 	$sql.=" ORDER BY rowid DESC LIMIT 1";
739
	 	$sql.=($withlock ? " FOR UPDATE ": "");
740
741
	 	$resql = $this->db->query($sql);
742
	 	if ($resql) {
743
	 		$obj = $this->db->fetch_object($resql);
744
	 		if ($obj)
745
	 		{
746
	 			$previoussignature = $obj->signature;
747
	 		}
748
	 	}
749
	 	else
750
	 	{
751
	 		dol_print_error($this->db);
752
	 		exit;
753
	 	}
754
755
	 	if (empty($previoussignature))
756
	 	{
757
			// First signature line (line 0)
758
	 		$previoussignature = $this->getSignature();
759
	 	}
760
761
	 	return $previoussignature;
762
	}
763
764
	/**
765
	 *	Return array of log objects (with criterias)
766
	 *
767
	 *	@param	string 	$element      	element to search
768
	 *	@param	int 	$fk_object		id of object to search
769
	 *	@param	int 	$limit      	max number of element, 0 for all
770
	 *	@param	string 	$sortfield     	sort field
771
	 *	@param	string 	$sortorder     	sort order
772
	 *	@param	int 	$search_fk_user id of user(s)
773
	 *	@param	int 	$search_start   start time limit
774
	 *	@param	int 	$search_end     end time limit
775
	 *  @param	string	$search_ref		search ref
776
	 *  @param	string	$search_amount	search amount
777
	 *  @param	string	$search_code	search code
778
	 *	@return	array					array of object log
779
	 */
780
	public function getLog($element, $fk_object, $limit = 0, $sortfield = '', $sortorder = '', $search_fk_user = -1, $search_start = -1, $search_end = -1, $search_ref='', $search_amount='', $search_code='')
781
	{
782
		global $conf, $cachedlogs;
783
784
		/* $cachedlogs allow fastest search */
785
		if (empty($cachedlogs)) $cachedlogs=array();
786
787
		if ($element=='all') {
788
789
	 		$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
790
	         WHERE entity=".$conf->entity;
791
792
		}
793
		else if ($element=='not_certified') {
794
			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
795
	         WHERE entity=".$conf->entity." AND certified = 0";
796
797
		}
798
		else if ($element=='just_certified') {
799
			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
800
	         WHERE entity=".$conf->entity." AND certified = 1";
801
802
		}
803
		else{
804
			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
805
	         WHERE entity=".$conf->entity." AND element='".$element."' AND fk_object=".(int) $fk_object;
806
		}
807
808
		if ($search_fk_user > 0)  $sql.=natural_search("fk_user", $search_fk_user, 2);
809
		if ($search_start > 0)    $sql.=" AND date_creation >= '".$this->db->idate($search_start)."'";
810
		if ($search_end > 0)      $sql.=" AND date_creation <= '".$this->db->idate($search_end)."'";
811
		if ($search_ref != '')    $sql.=natural_search("ref_object", $search_ref);
812
		if ($search_amount != '') $sql.=natural_search("amounts", $search_amount, 1);
813
		if ($search_code != '' && $search_code != '-1')   $sql.=natural_search("action", $search_code, 3);
814
815
		$sql.=$this->db->order($sortfield, $sortorder);
816
		$sql.=$this->db->plimit($limit);
817
818
		$res = $this->db->query($sql);
819
		if($res) {
820
821
			$results=array();
822
823
			while ($obj = $this->db->fetch_object($res)) {
824
825
				if (!isset($cachedlogs[$obj->rowid])) {
826
					$b=new BlockedLog($this->db);
827
					$b->fetch($obj->rowid);
828
829
					$cachedlogs[$obj->rowid] = $b;
830
				}
831
832
				$results[] = $cachedlogs[$obj->rowid];
833
			}
834
835
			return $results;
836
		}
837
		else{
838
			return false;
839
		}
840
	}
841
842
	/**
843
	 *	Return the signature (hash) of the "genesis-block" (Block 0).
844
	 *
845
	 *	@return	string					Signature of genesis-block for current conf->entity
846
	 */
847
	public function getSignature()
848
	{
849
		global $db,$conf,$mysoc;
850
851
		if (empty($conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT)) { // creation of a unique fingerprint
852
853
			require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
854
			require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
855
856
			$fingerprint = dol_hash(print_r($mysoc,true).getRandomPassword(1), '5');
857
858
			dolibarr_set_const($db, 'BLOCKEDLOG_ENTITY_FINGERPRINT', $fingerprint, 'chaine',0,'Numeric Unique Fingerprint', $conf->entity);
859
860
			$conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT=$fingerprint;
861
		}
862
863
		return $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT;
864
	}
865
866
867
	/**
868
	 * Check if module was already used or not for at least one recording.
869
	 *
870
	 * @param	int		$ignoresystem		Ignore system events for the test
871
	 */
872
	function alreadyUsed($ignoresystem=0)
873
	{
874
		global $conf;
875
876
		$result = false;
877
878
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog";
879
		$sql.= " WHERE entity = ".$conf->entity;
880
		if ($ignoresystem) $sql.=" AND action not in ('MODULE_SET','MODULE_RESET')";
881
		$sql.= $this->db->plimit(1);
882
883
		$res = $this->db->query($sql);
884
		if ($res!==false)
885
		{
886
			$obj = $this->db->fetch_object($res);
887
			if ($obj) $result = true;
888
		}
889
		else dol_print_error($this->db);
890
891
		dol_syslog("Module Blockedlog alreadyUsed with ignoresystem=".$ignoresystem." is ".$result);
892
893
		return $result;
894
	}
895
896
}
897
898