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

BlockedLog::getObjectLink()   D

Complexity

Conditions 17
Paths 29

Size

Total Lines 89
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 52
nc 29
nop 0
dl 0
loc 89
rs 4.8361
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

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