Passed
Branch develop (f6c1a1)
by
unknown
28:54
created

Website::getLibStatut()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/* Copyright (C) 2007-2018  Laurent Destailleur <[email protected]>
3
 * Copyright (C) 2014       Juanjo Menent       <[email protected]>
4
 * Copyright (C) 2015       Florian Henry       <[email protected]>
5
 * Copyright (C) 2015       Raphaël Doursenaud  <[email protected]>
6
 * Copyright (C) 2018       Frédéric France         <[email protected]>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
/**
23
 * \file    htdocs/website/class/website.class.php
24
 * \ingroup website
25
 * \brief   File for the CRUD class of website (Create/Read/Update/Delete)
26
 */
27
28
// Put here all includes required by your class file
29
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
30
//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31
//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32
33
/**
34
 * Class Website
35
 */
36
class Website extends CommonObject
37
{
38
	/**
39
	 * @var string Id to identify managed objects
40
	 */
41
	public $element = 'website';
42
43
	/**
44
	 * @var string Name of table without prefix where object is stored
45
	 */
46
	public $table_element = 'website';
47
48
	/**
49
	 * @var array  Does website support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
50
	 */
51
	public $ismultientitymanaged = 1;
52
53
	/**
54
	 * @var string String with name of icon for website. Must be the part after the 'object_' into object_myobject.png
55
	 */
56
	public $picto = 'globe';
57
58
	/**
59
	 * @var int Entity
60
	 */
61
	public $entity;
62
63
	/**
64
	 * @var string Ref
65
	 */
66
	public $ref;
67
68
	/**
69
	 * @var string description
70
	 */
71
	public $description;
72
73
	/**
74
	 * @var string Main language of web site
75
	 */
76
	public $lang;
77
78
	/**
79
	 * @var string List of languages of web site ('fr', 'es_MX', ...)
80
	 */
81
	public $otherlang;
82
83
	/**
84
	 * @var int Status
85
	 */
86
	public $status;
87
88
	/**
89
	 * @var integer|string date_creation
90
	 */
91
	public $date_creation;
92
93
	/**
94
	 * @var integer|string date_modification
95
	 */
96
	public $date_modification;
97
98
	/**
99
	 * @var integer
100
	 */
101
	public $fk_default_home;
102
	public $fk_user_creat;
103
104
	/**
105
	 * @var string
106
	 */
107
	public $virtualhost;
108
109
	/**
110
	 * @var int
111
	 */
112
	public $use_manifest;
113
114
	/**
115
	 * @var int
116
	 */
117
	public $position;
118
119
	/**
120
	 * List of containers
121
	 *
122
	 * @var array
123
	 */
124
	public $lines;
125
126
127
	const STATUS_DRAFT = 0;
128
	const STATUS_VALIDATED = 1;
129
130
131
	/**
132
	 * Constructor
133
	 *
134
	 * @param DoliDb $db Database handler
135
	 */
136
	public function __construct(DoliDB $db)
137
	{
138
		$this->db = $db;
139
		return 1;
140
	}
141
142
	/**
143
	 * Create object into database
144
	 *
145
	 * @param  User $user      User that creates
146
	 * @param  bool $notrigger false=launch triggers after, true=disable triggers
147
	 *
148
	 * @return int <0 if KO, Id of created object if OK
149
	 */
150
	public function create(User $user, $notrigger = false)
151
	{
152
		global $conf, $langs;
153
154
		dol_syslog(__METHOD__, LOG_DEBUG);
155
156
		$error = 0;
157
		$now = dol_now();
158
159
		// Clean parameters
160
		if (isset($this->entity)) {
161
			 $this->entity = (int) $this->entity;
162
		}
163
		if (isset($this->ref)) {
164
			 $this->ref = trim($this->ref);
165
		}
166
		if (isset($this->description)) {
167
			 $this->description = trim($this->description);
168
		}
169
		if (isset($this->status)) {
170
			 $this->status = (int) $this->status;
171
		}
172
        if (empty($this->date_creation)) {
173
            $this->date_creation = $now;
174
        }
175
        if (empty($this->date_modification)) {
176
            $this->date_modification = $now;
177
        }
178
        // Remove spaces and be sure we have main language only
179
        $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en
180
        $tmparray = explode(',', $this->otherlang);
181
		if (is_array($tmparray)) {
182
			foreach ($tmparray as $key => $val) {
183
				$tmparray[$key] = preg_replace('/[_-].*$/', '', trim($val)); // en_US or en-US -> en
184
			}
185
			$this->otherlang = join(',', $tmparray);
186
		}
187
188
        // Check parameters
189
        if (empty($this->entity)) {
190
            $this->entity = $conf->entity;
191
        }
192
        if (empty($this->lang)) {
193
        	$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MainLanguage"));
194
        	return -1;
195
        }
196
197
		// Insert request
198
		$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
199
		$sql .= 'entity,';
200
		$sql .= 'ref,';
201
		$sql .= 'description,';
202
		$sql .= 'lang,';
203
		$sql .= 'otherlang,';
204
		$sql .= 'status,';
205
		$sql .= 'fk_default_home,';
206
		$sql .= 'virtualhost,';
207
		$sql .= 'fk_user_creat,';
208
		$sql .= 'date_creation,';
209
		$sql .= 'position,';
210
		$sql .= 'tms';
211
		$sql .= ') VALUES (';
212
		$sql .= ' '.((empty($this->entity) && $this->entity != '0') ? 'NULL' : $this->entity).',';
213
		$sql .= ' '.(!isset($this->ref) ? 'NULL' : "'".$this->db->escape($this->ref)."'").',';
214
		$sql .= ' '.(!isset($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").',';
215
		$sql .= ' '.(!isset($this->lang) ? 'NULL' : "'".$this->db->escape($this->lang)."'").',';
216
		$sql .= ' '.(!isset($this->otherlang) ? 'NULL' : "'".$this->db->escape($this->otherlang)."'").',';
217
		$sql .= ' '.(!isset($this->status) ? '1' : $this->status).',';
218
		$sql .= ' '.(!isset($this->fk_default_home) ? 'NULL' : $this->fk_default_home).',';
219
		$sql .= ' '.(!isset($this->virtualhost) ? 'NULL' : "'".$this->db->escape($this->virtualhost)."'").",";
220
		$sql .= ' '.(!isset($this->fk_user_creat) ? $user->id : $this->fk_user_creat).',';
221
		$sql .= ' '.(!isset($this->date_creation) || dol_strlen($this->date_creation) == 0 ? 'NULL' : "'".$this->db->idate($this->date_creation)."'").",";
222
		$sql .= ' '.((int) $this->position).",";
223
		$sql .= ' '.(!isset($this->date_modification) || dol_strlen($this->date_modification) == 0 ? 'NULL' : "'".$this->db->idate($this->date_modification)."'");
224
		$sql .= ')';
225
226
		$this->db->begin();
227
228
		$resql = $this->db->query($sql);
229
		if (!$resql) {
230
			$error++;
231
			$this->errors[] = 'Error '.$this->db->lasterror();
232
			dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
233
		}
234
235
		if (!$error) {
236
			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
237
238
			// Create subdirectory per language
239
			$tmplangarray = explode(',', $this->otherlang);
240
			if (is_array($tmplangarray)) {
241
				dol_mkdir($conf->website->dir_output.'/'.$this->ref);
242
				foreach ($tmplangarray as $val) {
243
					if (trim($val) == $this->lang) continue;
244
					dol_mkdir($conf->website->dir_output.'/'.$this->ref.'/'.trim($val));
245
				}
246
			}
247
248
            // Uncomment this and change MYOBJECT to your own tag if you
249
            // want this action to call a trigger.
250
            // if (!$notrigger) {
251
252
            //     // Call triggers
253
            //     $result = $this->call_trigger('MYOBJECT_CREATE',$user);
254
            //     if ($result < 0) $error++;
255
            //     // End call triggers
256
            // }
257
        }
258
259
	    if (! $error) {
260
	    	$stringtodolibarrfile = "# Some properties for Dolibarr web site CMS\n";
261
	    	$stringtodolibarrfile .= "param=value\n";
262
	    	//print $conf->website->dir_output.'/'.$this->ref.'/.dolibarr';exit;
263
	    	file_put_contents($conf->website->dir_output.'/'.$this->ref.'/.dolibarr', $stringtodolibarrfile);
264
        }
265
266
		// Commit or rollback
267
		if ($error) {
268
			$this->db->rollback();
269
270
			return -1 * $error;
271
		} else {
272
			$this->db->commit();
273
274
			return $this->id;
275
		}
276
	}
277
278
	/**
279
	 * Load object in memory from the database
280
	 *
281
	 * @param 	int    $id  	Id object
282
	 * @param 	string $ref 	Ref
283
	 * @return 	int 			<0 if KO, 0 if not found, >0 if OK
284
	 */
285
	public function fetch($id, $ref = null)
286
	{
287
		dol_syslog(__METHOD__, LOG_DEBUG);
288
289
		$sql = 'SELECT';
290
		$sql .= ' t.rowid,';
291
		$sql .= " t.entity,";
292
		$sql .= " t.ref,";
293
		$sql .= " t.position,";
294
		$sql .= " t.description,";
295
		$sql .= " t.lang,";
296
		$sql .= " t.otherlang,";
297
		$sql .= " t.status,";
298
		$sql .= " t.fk_default_home,";
299
		$sql .= " t.use_manifest,";
300
		$sql .= " t.virtualhost,";
301
		$sql .= " t.fk_user_creat,";
302
		$sql .= " t.fk_user_modif,";
303
		$sql .= " t.date_creation,";
304
		$sql .= " t.tms as date_modification";
305
		$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
306
		$sql .= ' WHERE t.entity IN ('.getEntity('website').')';
307
		if (!empty($ref)) {
308
			$sql .= " AND t.ref = '".$this->db->escape($ref)."'";
309
		} else {
310
			$sql .= ' AND t.rowid = '.(int) $id;
311
		}
312
313
		$resql = $this->db->query($sql);
314
		if ($resql) {
315
			$numrows = $this->db->num_rows($resql);
316
			if ($numrows) {
317
				$obj = $this->db->fetch_object($resql);
318
319
				$this->id = $obj->rowid;
320
321
				$this->entity = $obj->entity;
322
				$this->ref = $obj->ref;
323
				$this->position = $obj->position;
324
				$this->description = $obj->description;
325
				$this->lang = $obj->lang;
326
				$this->otherlang = $obj->otherlang;
327
				$this->status = $obj->status;
328
				$this->fk_default_home = $obj->fk_default_home;
329
				$this->virtualhost = $obj->virtualhost;
330
				$this->use_manifest = $obj->use_manifest;
331
				$this->fk_user_creat = $obj->fk_user_creat;
332
				$this->fk_user_modif = $obj->fk_user_modif;
333
				$this->date_creation = $this->db->jdate($obj->date_creation);
334
				$this->date_modification = $this->db->jdate($obj->date_modification);
335
			}
336
			$this->db->free($resql);
337
338
			if ($numrows > 0) {
339
				// Lines
340
				$this->fetchLines();
341
			}
342
343
			if ($numrows > 0) {
344
				return 1;
345
			} else {
346
				return 0;
347
			}
348
		} else {
349
			$this->errors[] = 'Error '.$this->db->lasterror();
350
			dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
351
352
			return -1;
353
		}
354
	}
355
356
	/**
357
	 * Load object lines in memory from the database
358
	 *
359
	 * @return int         <0 if KO, 0 if not found, >0 if OK
360
	 */
361
	public function fetchLines()
362
	{
363
		$this->lines = array();
364
365
		// Load lines with object MyObjectLine
366
367
		return count($this->lines) ? 1 : 0;
368
	}
369
370
371
	/**
372
	 * Load all object in memory ($this->records) from the database
373
	 *
374
	 * @param string $sortorder Sort Order
375
	 * @param string $sortfield Sort field
376
	 * @param int    $limit     offset limit
377
	 * @param int    $offset    offset limit
378
	 * @param array  $filter    filter array
379
	 * @param string $filtermode filter mode (AND or OR)
380
	 *
381
	 * @return int <0 if KO, >0 if OK
382
	 */
383
	public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
384
	{
385
		dol_syslog(__METHOD__, LOG_DEBUG);
386
387
		$sql = 'SELECT';
388
		$sql .= ' t.rowid,';
389
		$sql .= " t.entity,";
390
		$sql .= " t.ref,";
391
		$sql .= " t.description,";
392
		$sql .= " t.lang,";
393
		$sql .= " t.otherlang,";
394
		$sql .= " t.status,";
395
		$sql .= " t.fk_default_home,";
396
		$sql .= " t.virtualhost,";
397
		$sql .= " t.fk_user_creat,";
398
		$sql .= " t.fk_user_modif,";
399
		$sql .= " t.date_creation,";
400
		$sql .= " t.tms as date_modification";
401
		$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
402
		$sql .= ' WHERE t.entity IN ('.getEntity('website').')';
403
		// Manage filter
404
		$sqlwhere = array();
405
		if (count($filter) > 0) {
406
			foreach ($filter as $key => $value) {
407
				$sqlwhere [] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
408
			}
409
		}
410
		if (count($sqlwhere) > 0) {
411
			$sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere);
412
		}
413
414
		if (!empty($sortfield)) {
415
			$sql .= $this->db->order($sortfield, $sortorder);
416
		}
417
		if (!empty($limit)) {
418
		    $sql .= ' '.$this->db->plimit($limit, $offset);
419
		}
420
		$this->records = array();
421
422
		$resql = $this->db->query($sql);
423
		if ($resql) {
424
			$num = $this->db->num_rows($resql);
425
426
			while ($obj = $this->db->fetch_object($resql)) {
427
				$line = new self($this->db);
428
429
				$line->id = $obj->rowid;
430
431
				$line->entity = $obj->entity;
432
				$line->ref = $obj->ref;
433
				$line->description = $obj->description;
434
				$line->lang = $obj->lang;
435
				$line->otherlang = $obj->otherlang;
436
				$line->status = $obj->status;
437
				$line->fk_default_home = $obj->fk_default_home;
438
				$line->virtualhost = $obj->virtualhost;
439
				$this->fk_user_creat = $obj->fk_user_creat;
440
				$this->fk_user_modif = $obj->fk_user_modif;
441
				$line->date_creation = $this->db->jdate($obj->date_creation);
442
				$line->date_modification = $this->db->jdate($obj->date_modification);
443
444
				$this->records[$line->id] = $line;
445
			}
446
			$this->db->free($resql);
447
448
			return $num;
449
		} else {
450
			$this->errors[] = 'Error '.$this->db->lasterror();
451
			dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
452
453
			return -1;
454
		}
455
	}
456
457
	/**
458
	 * Update object into database
459
	 *
460
	 * @param  User $user      User that modifies
461
	 * @param  bool $notrigger false=launch triggers after, true=disable triggers
462
	 *
463
	 * @return int <0 if KO, >0 if OK
464
	 */
465
	public function update(User $user, $notrigger = false)
466
	{
467
		global $conf, $langs;
468
469
		$error = 0;
470
471
		dol_syslog(__METHOD__, LOG_DEBUG);
472
473
		// Clean parameters
474
475
		if (isset($this->entity)) {
476
			 $this->entity = (int) $this->entity;
477
		}
478
		if (isset($this->ref)) {
479
			 $this->ref = trim($this->ref);
480
		}
481
		if (isset($this->description)) {
482
			 $this->description = trim($this->description);
483
		}
484
		if (isset($this->status)) {
485
			 $this->status = (int) $this->status;
486
		}
487
488
		// Remove spaces and be sure we have main language only
489
		$this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en
490
		$tmparray = explode(',', $this->otherlang);
491
		if (is_array($tmparray)) {
492
			foreach ($tmparray as $key => $val) {
493
				$tmparray[$key] = preg_replace('/[_-].*$/', '', trim($val)); // en_US or en-US -> en
494
			}
495
			$this->otherlang = join(',', $tmparray);
496
		}
497
		if (empty($this->lang)) {
498
			$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MainLanguage"));
499
			return -1;
500
		}
501
502
		// Check parameters
503
		// Put here code to add a control on parameters values
504
505
		// Update request
506
		$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
507
		$sql .= ' entity = '.(isset($this->entity) ? $this->entity : "null").',';
508
		$sql .= ' ref = '.(isset($this->ref) ? "'".$this->db->escape($this->ref)."'" : "null").',';
509
		$sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
510
		$sql .= ' lang = '.(isset($this->lang) ? "'".$this->db->escape($this->lang)."'" : "null").',';
511
		$sql .= ' otherlang = '.(isset($this->otherlang) ? "'".$this->db->escape($this->otherlang)."'" : "null").',';
512
		$sql .= ' status = '.(isset($this->status) ? $this->status : "null").',';
513
		$sql .= ' fk_default_home = '.(($this->fk_default_home > 0) ? $this->fk_default_home : "null").',';
514
		$sql .= ' use_manifest = '.((int) $this->use_manifest).',';
515
		$sql .= ' virtualhost = '.(($this->virtualhost != '') ? "'".$this->db->escape($this->virtualhost)."'" : "null").',';
516
		$sql .= ' fk_user_modif = '.(!isset($this->fk_user_modif) ? $user->id : $this->fk_user_modif).',';
517
		$sql .= ' date_creation = '.(!isset($this->date_creation) || dol_strlen($this->date_creation) != 0 ? "'".$this->db->idate($this->date_creation)."'" : 'null').',';
518
		$sql .= ' tms = '.(dol_strlen($this->date_modification) != 0 ? "'".$this->db->idate($this->date_modification)."'" : "'".$this->db->idate(dol_now())."'");
519
		$sql .= ' WHERE rowid='.$this->id;
520
521
		$this->db->begin();
522
523
		$resql = $this->db->query($sql);
524
		if (!$resql) {
525
			$error++;
526
			$this->errors[] = 'Error '.$this->db->lasterror();
527
			dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
528
		}
529
530
		if (!$error && !$notrigger) {
531
			// Uncomment this and change MYOBJECT to your own tag if you
532
			// want this action calls a trigger.
533
534
			// Create subdirectory per language
535
			$tmplangarray = explode(',', $this->otherlang);
536
			if (is_array($tmplangarray)) {
537
				dol_mkdir($conf->website->dir_output.'/'.$this->ref);
538
				foreach ($tmplangarray as $val) {
539
					if (trim($val) == $this->lang) continue;
540
					dol_mkdir($conf->website->dir_output.'/'.$this->ref.'/'.trim($val));
541
				}
542
			}
543
544
			//// Call triggers
545
			//$result=$this->call_trigger('MYOBJECT_MODIFY',$user);
546
			//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
547
			//// End call triggers
548
		}
549
550
		// Commit or rollback
551
		if ($error) {
552
			$this->db->rollback();
553
554
			return -1 * $error;
555
		} else {
556
			$this->db->commit();
557
558
			return 1;
559
		}
560
	}
561
562
	/**
563
	 * Delete object in database
564
	 *
565
	 * @param User $user      User that deletes
566
	 * @param bool $notrigger false=launch triggers after, true=disable triggers
567
	 *
568
	 * @return int <0 if KO, >0 if OK
569
	 */
570
	public function delete(User $user, $notrigger = false)
571
	{
572
		dol_syslog(__METHOD__, LOG_DEBUG);
573
574
		$error = 0;
575
576
		$this->db->begin();
577
578
		if (!$error) {
579
			if (!$notrigger) {
580
				// Uncomment this and change MYOBJECT to your own tag if you
581
				// want this action calls a trigger.
582
583
				//// Call triggers
584
				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
585
				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
586
				//// End call triggers
587
			}
588
		}
589
590
		if (!$error) {
591
			$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
592
			$sql .= ' WHERE rowid='.$this->id;
593
594
			$resql = $this->db->query($sql);
595
			if (!$resql) {
596
				$error++;
597
				$this->errors[] = 'Error '.$this->db->lasterror();
598
				dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
599
			}
600
		}
601
602
		if (!$error && !empty($this->ref))
603
		{
604
			$pathofwebsite = DOL_DATA_ROOT.'/website/'.$this->ref;
605
606
			dol_delete_dir_recursive($pathofwebsite);
607
		}
608
609
		// Commit or rollback
610
		if ($error) {
611
			$this->db->rollback();
612
613
			return -1 * $error;
614
		} else {
615
			$this->db->commit();
616
617
			return 1;
618
		}
619
	}
620
621
	/**
622
	 * Load an object from its id and create a new one in database.
623
	 * This copy website directories, regenerate all the pages + alias pages and recreate the medias link.
624
	 *
625
	 * @param	User	$user		User making the clone
626
	 * @param 	int 	$fromid 	Id of object to clone
627
	 * @param	string	$newref		New ref
628
	 * @param	string	$newlang	New language
629
	 * @return 	mixed 				New object created, <0 if KO
630
	 */
631
	public function createFromClone($user, $fromid, $newref, $newlang = '')
632
	{
633
        global $conf, $langs;
634
		global $dolibarr_main_data_root;
635
636
		$now = dol_now();
637
		$error = 0;
638
639
        dol_syslog(__METHOD__, LOG_DEBUG);
640
641
		$object = new self($this->db);
642
643
        // Check no site with ref exists
644
		if ($object->fetch(0, $newref) > 0)
645
		{
646
			$this->error = 'ErrorNewRefIsAlreadyUsed';
647
			return -1;
648
		}
649
650
		$this->db->begin();
651
652
		// Load source object
653
		$object->fetch($fromid);
654
655
		$oldidforhome = $object->fk_default_home;
656
		$oldref = $object->ref;
657
658
		$pathofwebsiteold = $dolibarr_main_data_root.'/website/'.$oldref;
659
		$pathofwebsitenew = $dolibarr_main_data_root.'/website/'.$newref;
660
		dol_delete_dir_recursive($pathofwebsitenew);
661
662
		$fileindex = $pathofwebsitenew.'/index.php';
663
664
		// Reset some properties
665
		unset($object->id);
666
		unset($object->fk_user_creat);
667
		unset($object->import_key);
668
669
		// Clear fields
670
		$object->ref = $newref;
671
		$object->fk_default_home = 0;
672
		$object->virtualhost = '';
673
		$object->date_creation = $now;
674
		$object->fk_user_creat = $user->id;
675
		$object->position = ((int) $object->position) + 1;
676
		$object->status = self::STATUS_DRAFT;
677
		if (empty($object->lang)) $object->lang = substr($langs->defaultlang, 0, 2); // Should not happen. Protection for corrupted site with no languages
678
679
		// Create clone
680
		$object->context['createfromclone'] = 'createfromclone';
681
		$result = $object->create($user);
682
		if ($result < 0) {
683
			$error++;
684
			$this->error = $object->error;
685
			$this->errors = $object->errors;
686
			dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
687
		}
688
689
		if (!$error)
690
		{
691
			dolCopyDir($pathofwebsiteold, $pathofwebsitenew, $conf->global->MAIN_UMASK, 0, null, 2);
692
693
			// Check symlink to medias and restore it if ko
694
			$pathtomedias = DOL_DATA_ROOT.'/medias'; // Target
695
			$pathtomediasinwebsite = $pathofwebsitenew.'/medias'; // Source / Link name
696
			if (!is_link(dol_osencode($pathtomediasinwebsite)))
697
			{
698
				dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
699
				dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
700
				$result = symlink($pathtomedias, $pathtomediasinwebsite);
701
			}
702
703
			// Copy images and js dir
704
			$pathofmediasjsold = DOL_DATA_ROOT.'/medias/js/'.$oldref;
705
			$pathofmediasjsnew = DOL_DATA_ROOT.'/medias/js/'.$newref;
706
			dolCopyDir($pathofmediasjsold, $pathofmediasjsnew, $conf->global->MAIN_UMASK, 0);
707
708
			$pathofmediasimageold = DOL_DATA_ROOT.'/medias/image/'.$oldref;
709
			$pathofmediasimagenew = DOL_DATA_ROOT.'/medias/image/'.$newref;
710
			dolCopyDir($pathofmediasimageold, $pathofmediasimagenew, $conf->global->MAIN_UMASK, 0);
711
712
			$newidforhome = 0;
713
714
			// Duplicate pages
715
			$objectpages = new WebsitePage($this->db);
716
			$listofpages = $objectpages->fetchAll($fromid);
717
			foreach ($listofpages as $pageid => $objectpageold)
0 ignored issues
show
Bug introduced by
The expression $listofpages of type integer is not traversable.
Loading history...
718
			{
719
				// Delete old file
720
				$filetplold = $pathofwebsitenew.'/page'.$pageid.'.tpl.php';
721
				dol_delete_file($filetplold);
722
723
				// Create new file
724
				$objectpagenew = $objectpageold->createFromClone($user, $pageid, $objectpageold->pageurl, '', 0, $object->id, 1);
725
726
				//print $pageid.' = '.$objectpageold->pageurl.' -> '.$objectpagenew->id.' = '.$objectpagenew->pageurl.'<br>';
727
				if (is_object($objectpagenew) && $objectpagenew->pageurl)
728
				{
729
		            $filealias = $pathofwebsitenew.'/'.$objectpagenew->pageurl.'.php';
730
					$filetplnew = $pathofwebsitenew.'/page'.$objectpagenew->id.'.tpl.php';
731
732
					// Save page alias
733
					$result = dolSavePageAlias($filealias, $object, $objectpagenew);
734
					if (!$result) setEventMessages('Failed to write file '.$filealias, null, 'errors');
735
736
					$result = dolSavePageContent($filetplnew, $object, $objectpagenew);
737
					if (!$result) setEventMessages('Failed to write file '.$filetplnew, null, 'errors');
738
739
					if ($pageid == $oldidforhome)
740
					{
741
						$newidforhome = $objectpagenew->id;
742
					}
743
				}
744
				else {
745
					setEventMessages($objectpageold->error, $objectpageold->errors, 'errors');
746
					$error++;
747
				}
748
			}
749
		}
750
751
		if (!$error)
752
		{
753
			// Restore id of home page
754
			$object->fk_default_home = $newidforhome;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $newidforhome does not seem to be defined for all execution paths leading up to this point.
Loading history...
755
		    $res = $object->update($user);
756
		    if (!$res > 0)
757
		    {
758
		        $error++;
759
		        setEventMessages($object->error, $object->errors, 'errors');
760
		    }
761
762
		    if (!$error)
763
		    {
764
		    	$filetpl = $pathofwebsitenew.'/page'.$newidforhome.'.tpl.php';
765
		    	$filewrapper = $pathofwebsitenew.'/wrapper.php';
766
767
		    	// Generate the index.php page to be the home page
768
		    	//-------------------------------------------------
769
		    	$result = dolSaveIndexPage($pathofwebsitenew, $fileindex, $filetpl, $filewrapper);
770
		    }
771
		}
772
773
		unset($object->context['createfromclone']);
774
775
		// End
776
		if (!$error) {
777
			$this->db->commit();
778
779
			return $object;
780
		} else {
781
			$this->db->rollback();
782
783
			return -1;
784
		}
785
	}
786
787
	/**
788
	 *  Return a link to the user card (with optionally the picto)
789
	 * 	Use this->id,this->lastname, this->firstname
790
	 *
791
	 *	@param	int		$withpicto			Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
792
	 *	@param	string	$option				On what the link point to
793
     *  @param	integer	$notooltip			1=Disable tooltip
794
     *  @param	int		$maxlen				Max length of visible user name
795
     *  @param  string  $morecss            Add more css on link
796
	 *	@return	string						String with URL
797
	 */
798
	public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
799
	{
800
		global $langs, $conf, $db;
801
        global $dolibarr_main_authentication, $dolibarr_main_demo;
802
        global $menumanager;
803
804
805
        $result = '';
806
        $companylink = '';
807
808
        $label = '<u>'.$langs->trans("WebSite").'</u>';
809
        $label .= '<br>';
810
        $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref.'<br>';
811
        $label .= '<b>'.$langs->trans('MainLanguage').':</b> '.$this->lang;
812
813
        $linkstart = '<a href="'.DOL_URL_ROOT.'/website/card.php?id='.$this->id.'"';
814
        $linkstart .= ($notooltip ? '' : ' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip'.($morecss ? ' '.$morecss : '').'"');
815
        $linkstart .= '>';
816
		$linkend = '</a>';
817
818
		$linkstart = $linkend = '';
819
820
        if ($withpicto)
821
        {
822
            $result .= ($linkstart.img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? '' : 'class="classfortooltip"')).$linkend);
823
            if ($withpicto != 2) $result .= ' ';
824
		}
825
		$result .= $linkstart.$this->ref.$linkend;
826
		return $result;
827
	}
828
829
	/**
830
	 *  Retourne le libelle du status d'un user (actif, inactif)
831
	 *
832
	 *  @param	int		$mode          0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
833
	 *  @return	string 			       Label of status
834
	 */
835
	public function getLibStatut($mode = 0)
836
	{
837
		return $this->LibStatut($this->status, $mode);
838
	}
839
840
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
841
	/**
842
	 *  Renvoi le libelle d'un status donne
843
	 *
844
	 *  @param	int		$status        	Id status
845
	 *  @param  int		$mode          	0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
846
	 *  @return string 			       	Label of status
847
	 */
848
	public function LibStatut($status, $mode = 0)
849
	{
850
        // phpcs:enable
851
		global $langs;
852
853
		if (empty($this->labelStatus) || empty($this->labelStatusShort))
854
		{
855
			global $langs;
856
			//$langs->load("mymodule");
857
			$this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Disabled');
858
			$this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
859
			$this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Disabled');
860
			$this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
861
		}
862
863
		$statusType = 'status5';
864
		if ($status == self::STATUS_VALIDATED) $statusType = 'status4';
865
866
		return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
867
	}
868
869
870
	/**
871
	 * Initialise object with example values
872
	 * Id must be 0 if object instance is a specimen
873
	 *
874
	 * @return void
875
	 */
876
	public function initAsSpecimen()
877
	{
878
	    global $user;
879
880
		$this->id = 0;
881
882
		$this->entity = 1;
883
		$this->ref = 'myspecimenwebsite';
884
		$this->description = 'A specimen website';
885
		$this->lang = 'en';
886
		$this->otherlang = 'fr,es';
887
		$this->status = '';
888
		$this->fk_default_home = null;
889
		$this->virtualhost = 'http://myvirtualhost';
890
		$this->fk_user_creat = $user->id;
891
		$this->fk_user_modif = $user->id;
892
		$this->date_creation = dol_now();
893
		$this->tms = dol_now();
894
	}
895
896
897
	/**
898
	 * Generate a zip with all data of web site.
899
	 *
900
	 * @return  string						Path to file with zip or '' if error
901
	 */
902
	public function exportWebSite()
903
	{
904
		global $conf, $mysoc;
905
906
		$website = $this;
907
908
		if (empty($website->id) || empty($website->ref))
909
		{
910
			setEventMessages("Website id or ref is not defined", null, 'errors');
911
			return '';
912
		}
913
914
		dol_syslog("Create temp dir ".$conf->website->dir_temp);
915
		dol_mkdir($conf->website->dir_temp);
916
		if (!is_writable($conf->website->dir_temp))
917
		{
918
			setEventMessages("Temporary dir ".$conf->website->dir_temp." is not writable", null, 'errors');
919
			return '';
920
		}
921
922
		$destdir = $conf->website->dir_temp.'/'.$website->ref;
923
924
		dol_syslog("Clear temp dir ".$destdir);
925
		$count = 0; $countreallydeleted = 0;
926
		$counttodelete = dol_delete_dir_recursive($destdir, $count, 1, 0, $countreallydeleted);
927
		if ($counttodelete != $countreallydeleted)
928
		{
929
			setEventMessages("Failed to clean temp directory ".$destdir, null, 'errors');
930
			return '';
931
		}
932
933
		$arrayreplacementinfilename = array();
934
		$arrayreplacementincss = array();
935
		$arrayreplacementincss['file=image/'.$website->ref.'/'] = "file=image/__WEBSITE_KEY__/";
936
		$arrayreplacementincss['file=js/'.$website->ref.'/'] = "file=js/__WEBSITE_KEY__/";
937
		$arrayreplacementincss['medias/image/'.$website->ref.'/'] = "medias/image/__WEBSITE_KEY__/";
938
		$arrayreplacementincss['medias/js/'.$website->ref.'/'] = "medias/js/__WEBSITE_KEY__/";
939
		if ($mysoc->logo_small) {
940
		    $arrayreplacementincss['file=logos%2Fthumbs%2F'.$mysoc->logo_small] = "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__";
941
		}
942
		if ($mysoc->logo_mini) {
943
		    $arrayreplacementincss['file=logos%2Fthumbs%2F'.$mysoc->logo_mini] = "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__";
944
		}
945
		if ($mysoc->logo) {
946
		    $arrayreplacementincss['file=logos%2Fthumbs%2F'.$mysoc->logo] = "file=logos%2Fthumbs%2F__LOGO_KEY__";
947
		}
948
949
		// Create output directories
950
		dol_syslog("Create containers dir");
951
		dol_mkdir($conf->website->dir_temp.'/'.$website->ref.'/containers');
952
		dol_mkdir($conf->website->dir_temp.'/'.$website->ref.'/medias/image/websitekey');
953
		dol_mkdir($conf->website->dir_temp.'/'.$website->ref.'/medias/js/websitekey');
954
955
		// Copy files into 'containers'
956
		$srcdir = $conf->website->dir_output.'/'.$website->ref;
957
		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/containers';
958
959
		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
960
		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacementinfilename, 2);
961
962
		// Copy files into medias/image
963
		$srcdir = DOL_DATA_ROOT.'/medias/image/'.$website->ref;
964
		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/image/websitekey';
965
966
		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
967
		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacementinfilename);
968
969
		// Copy files into medias/js
970
		$srcdir = DOL_DATA_ROOT.'/medias/js/'.$website->ref;
971
		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/js/websitekey';
972
973
		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
974
		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacementinfilename);
975
976
		// Make some replacement into some files
977
		$cssindestdir = $conf->website->dir_temp.'/'.$website->ref.'/containers/styles.css.php';
978
		dolReplaceInFile($cssindestdir, $arrayreplacementincss);
979
980
		$htmldeaderindestdir = $conf->website->dir_temp.'/'.$website->ref.'/containers/htmlheader.html';
981
		dolReplaceInFile($htmldeaderindestdir, $arrayreplacementincss);
982
983
		// Build sql file
984
		$filesql = $conf->website->dir_temp.'/'.$website->ref.'/website_pages.sql';
985
		$fp = fopen($filesql, "w");
986
		if (empty($fp))
987
		{
988
			setEventMessages("Failed to create file ".$filesql, null, 'errors');
989
			return '';
990
		}
991
992
		$objectpages = new WebsitePage($this->db);
993
		$listofpages = $objectpages->fetchAll($website->id);
994
995
		// Assign ->newid and ->newfk_page
996
		$i = 1;
997
		foreach ($listofpages as $pageid => $objectpageold)
0 ignored issues
show
Bug introduced by
The expression $listofpages of type integer is not traversable.
Loading history...
998
		{
999
			$objectpageold->newid = $i;
1000
			$i++;
1001
		}
1002
		$i = 1;
1003
		foreach ($listofpages as $pageid => $objectpageold)
0 ignored issues
show
Bug introduced by
The expression $listofpages of type integer is not traversable.
Loading history...
1004
		{
1005
			// Search newid
1006
			$newfk_page = 0;
1007
			foreach ($listofpages as $pageid2 => $objectpageold2)
0 ignored issues
show
Bug introduced by
The expression $listofpages of type integer is not traversable.
Loading history...
1008
			{
1009
				if ($pageid2 == $objectpageold->fk_page)
1010
				{
1011
					$newfk_page = $objectpageold2->newid;
1012
					break;
1013
				}
1014
			}
1015
			$objectpageold->newfk_page = $newfk_page;
1016
			$i++;
1017
		}
1018
		foreach ($listofpages as $pageid => $objectpageold)
0 ignored issues
show
Bug introduced by
The expression $listofpages of type integer is not traversable.
Loading history...
1019
		{
1020
			$allaliases = $objectpageold->pageurl;
1021
			$allaliases .= ($objectpageold->aliasalt ? ','.$objectpageold->aliasalt : '');
1022
1023
			$line = '-- Page ID '.$objectpageold->id.' -> '.$objectpageold->newid.'__+MAX_llx_website_page__ - Aliases '.$allaliases.' --;'; // newid start at 1, 2...
1024
			$line .= "\n";
1025
			fputs($fp, $line);
1026
1027
			// Warning: We must keep llx_ here. It is a generic SQL.
1028
			$line = 'INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, aliasalt, title, description, lang, image, keywords, status, date_creation, tms, import_key, grabbed_from, type_container, htmlheader, content, author_alias)';
1029
1030
			$line .= " VALUES(";
1031
			$line .= $objectpageold->newid."__+MAX_llx_website_page__, ";
1032
			$line .= ($objectpageold->newfk_page ? $this->db->escape($objectpageold->newfk_page)."__+MAX_llx_website_page__" : "null").", ";
1033
			$line .= "__WEBSITE_ID__, ";
1034
			$line .= "'".$this->db->escape($objectpageold->pageurl)."', ";
1035
			$line .= "'".$this->db->escape($objectpageold->aliasalt)."', ";
1036
			$line .= "'".$this->db->escape($objectpageold->title)."', ";
1037
			$line .= "'".$this->db->escape($objectpageold->description)."', ";
1038
			$line .= "'".$this->db->escape($objectpageold->lang)."', ";
1039
			$line .= "'".$this->db->escape($objectpageold->image)."', ";
1040
			$line .= "'".$this->db->escape($objectpageold->keywords)."', ";
1041
			$line .= "'".$this->db->escape($objectpageold->status)."', ";
1042
			$line .= "'".$this->db->idate($objectpageold->date_creation)."', ";
1043
			$line .= "'".$this->db->idate($objectpageold->date_modification)."', ";
1044
			$line .= ($objectpageold->import_key ? "'".$this->db->escape($objectpageold->import_key)."'" : "null").", ";
1045
			$line .= "'".$this->db->escape($objectpageold->grabbed_from)."', ";
1046
			$line .= "'".$this->db->escape($objectpageold->type_container)."', ";
1047
1048
			$stringtoexport = $objectpageold->htmlheader;
1049
			$stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport);
1050
			$stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport);
1051
			$stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport);
1052
			$stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport);
1053
			$stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport);
1054
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport);
1055
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport);
1056
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport);
1057
			$line .= "'".$this->db->escape(str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport))."', "; // Replace \r \n to have record on 1 line
1058
1059
			$stringtoexport = $objectpageold->content;
1060
			$stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport);
1061
			$stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport);
1062
			$stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport);
1063
			$stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport);
1064
			$stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport);
1065
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport);
1066
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport);
1067
			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport);
1068
1069
			// When we have a link src="image/websiteref/file.png" into html content
1070
			$stringtoexport = str_replace('="image/'.$website->ref.'/', '="image/__WEBSITE_KEY__/', $stringtoexport);
1071
1072
			$line .= "'".$this->db->escape($stringtoexport)."', "; // Replace \r \n to have record on 1 line
1073
			$line .= "'".$this->db->escape($objectpageold->author_alias)."'";
1074
			$line .= ");";
1075
			$line .= "\n";
1076
			fputs($fp, $line);
1077
1078
			// Add line to update home page id during import
1079
			//var_dump($this->fk_default_home.' - '.$objectpageold->id.' - '.$objectpageold->newid);exit;
1080
			if ($this->fk_default_home > 0 && ($objectpageold->id == $this->fk_default_home) && ($objectpageold->newid > 0))	// This is the record with home page
1081
			{
1082
			    // Warning: We must keep llx_ here. It is a generic SQL.
1083
			    $line = "UPDATE llx_website SET fk_default_home = ".($objectpageold->newid > 0 ? $this->db->escape($objectpageold->newid)."__+MAX_llx_website_page__" : "null")." WHERE rowid = __WEBSITE_ID__;";
1084
				$line .= "\n";
1085
				fputs($fp, $line);
1086
			}
1087
		}
1088
1089
		fclose($fp);
1090
		if (!empty($conf->global->MAIN_UMASK))
1091
			@chmod($filesql, octdec($conf->global->MAIN_UMASK));
1092
1093
		// Build zip file
1094
		$filedir  = $conf->website->dir_temp.'/'.$website->ref.'/.';
1095
		$fileglob = $conf->website->dir_temp.'/'.$website->ref.'/website_'.$website->ref.'-*.zip';
1096
		$filename = $conf->website->dir_temp.'/'.$website->ref.'/website_'.$website->ref.'-'.dol_print_date(dol_now(), 'dayhourlog').'-V'.((float) DOL_VERSION).'.zip';
1097
1098
		dol_delete_file($fileglob, 0);
1099
		$result = dol_compress_file($filedir, $filename, 'zip');
1100
1101
		if ($result > 0)
1102
		{
1103
			return $filename;
1104
		}
1105
		else {
1106
			global $errormsg;
1107
			$this->error = $errormsg;
1108
			return '';
1109
		}
1110
	}
1111
1112
1113
	/**
1114
	 * Open a zip with all data of web site and load it into database.
1115
	 *
1116
	 * @param 	string		$pathtofile		Path of zip file
1117
	 * @return  int							<0 if KO, Id of new website if OK
1118
	 */
1119
	public function importWebSite($pathtofile)
1120
	{
1121
		global $conf, $mysoc;
1122
1123
		$error = 0;
1124
1125
		$object = $this;
1126
		if (empty($object->ref))
1127
		{
1128
			$this->error = 'Function importWebSite called on object not loaded (object->ref is empty)';
1129
			return -1;
1130
		}
1131
1132
		dol_delete_dir_recursive($conf->website->dir_temp.'/'.$object->ref);
1133
		dol_mkdir($conf->website->dir_temp.'/'.$object->ref);
1134
1135
		$filename = basename($pathtofile);
1136
		if (!preg_match('/^website_(.*)-(.*)$/', $filename, $reg))
1137
		{
1138
			$this->errors[] = 'Bad format for filename '.$filename.'. Must be website_XXX-VERSION.';
1139
			return -1;
1140
		}
1141
1142
		$result = dol_uncompress($pathtofile, $conf->website->dir_temp.'/'.$object->ref);
1143
1144
		if (!empty($result['error']))
1145
		{
1146
			$this->errors[] = 'Failed to unzip file '.$pathtofile.'.';
1147
			return -1;
1148
		}
1149
1150
		$arrayreplacement = array();
1151
		$arrayreplacement['__WEBSITE_ID__'] = $object->id;
1152
		$arrayreplacement['__WEBSITE_KEY__'] = $object->ref;
1153
		$arrayreplacement['__N__'] = $this->db->escape("\n"); // Restore \n
1154
		$arrayreplacement['__LOGO_SMALL_KEY__'] = $this->db->escape($mysoc->logo_small);
1155
		$arrayreplacement['__LOGO_MINI_KEY__'] = $this->db->escape($mysoc->logo_mini);
1156
		$arrayreplacement['__LOGO_KEY__'] = $this->db->escape($mysoc->logo);
1157
1158
		// Copy containers
1159
		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/containers', $conf->website->dir_output.'/'.$object->ref, 0, 1); // Overwrite if exists
1160
1161
		// Make replacement into css and htmlheader file
1162
		$cssindestdir = $conf->website->dir_output.'/'.$object->ref.'/styles.css.php';
1163
		$result = dolReplaceInFile($cssindestdir, $arrayreplacement);
1164
1165
		$htmldeaderindestdir = $conf->website->dir_output.'/'.$object->ref.'/htmlheader.html';
1166
		$result = dolReplaceInFile($htmldeaderindestdir, $arrayreplacement);
1167
1168
		// Now generate the master.inc.php page
1169
		$filemaster = $conf->website->dir_output.'/'.$object->ref.'/master.inc.php';
1170
		$result = dolSaveMasterFile($filemaster);
1171
		if (!$result)
1172
		{
1173
			$this->errors[] = 'Failed to write file '.$filemaster;
1174
			$error++;
1175
		}
1176
1177
		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/image/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/image/'.$object->ref, 0, 1); // Medias can be shared, do not overwrite if exists
1178
		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/js/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/js/'.$object->ref, 0, 1); // Medias can be shared, do not overwrite if exists
1179
1180
		$sqlfile = $conf->website->dir_temp.'/'.$object->ref.'/website_pages.sql';
1181
1182
		$result = dolReplaceInFile($sqlfile, $arrayreplacement);
1183
1184
		$this->db->begin();
1185
1186
		// Search the $maxrowid because we need it later
1187
		$sqlgetrowid = 'SELECT MAX(rowid) as max from '.MAIN_DB_PREFIX.'website_page';
1188
		$resql = $this->db->query($sqlgetrowid);
1189
		if ($resql)
1190
		{
1191
			$obj = $this->db->fetch_object($resql);
1192
			$maxrowid = $obj->max;
1193
		}
1194
1195
		// Load sql record
1196
		$runsql = run_sql($sqlfile, 1, '', 0, '', 'none', 0, 1); // The maxrowid of table is searched into this function two
1197
		if ($runsql <= 0)
1198
		{
1199
			$this->errors[] = 'Failed to load sql file '.$sqlfile;
1200
			$error++;
1201
		}
1202
1203
		$objectpagestatic = new WebsitePage($this->db);
1204
1205
		// Make replacement of IDs
1206
		$fp = fopen($sqlfile, "r");
1207
		if ($fp)
1208
		{
1209
			while (!feof($fp))
1210
			{
1211
				$reg = array();
1212
1213
				// Warning fgets with second parameter that is null or 0 hang.
1214
				$buf = fgets($fp, 65000);
1215
				if (preg_match('/^-- Page ID (\d+)\s[^\s]+\s(\d+).*Aliases\s(.*)\s--;/i', $buf, $reg))
1216
				{
1217
					$oldid = $reg[1];
1218
					$newid = ($reg[2] + $maxrowid);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $maxrowid does not seem to be defined for all execution paths leading up to this point.
Loading history...
1219
					$aliasesarray = explode(',', $reg[3]);
1220
1221
					dol_syslog("Found ID ".$oldid." to replace with ID ".$newid." and shortcut aliases to create: ".$reg[3]);
1222
1223
					dol_move($conf->website->dir_output.'/'.$object->ref.'/page'.$oldid.'.tpl.php', $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php', 0, 1, 0, 0);
1224
1225
					$objectpagestatic->fetch($newid);
1226
1227
					// The move is not enough, so we regenerate page
1228
					$filetpl = $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php';
1229
					$result = dolSavePageContent($filetpl, $object, $objectpagestatic);
1230
					if (!$result) {
1231
						$this->errors[] = 'Failed to write file '.basename($filetpl);
1232
						$error++;
1233
					}
1234
1235
					// Regenerate alternative aliases pages
1236
					if (is_array($aliasesarray))
1237
					{
1238
						foreach ($aliasesarray as $aliasshortcuttocreate)
1239
						{
1240
							if (trim($aliasshortcuttocreate))
1241
							{
1242
								$filealias = $conf->website->dir_output.'/'.$object->ref.'/'.trim($aliasshortcuttocreate).'.php';
1243
								$result = dolSavePageAlias($filealias, $object, $objectpagestatic);
1244
								if (!$result) {
1245
									$this->errors[] = 'Failed to write file '.basename($filealias);
1246
									$error++;
1247
								}
1248
							}
1249
						}
1250
					}
1251
				}
1252
			}
1253
		}
1254
1255
		// Read record of website that has been updated by the run_sql function previously called so we can get the
1256
		// value of fk_default_home that is ID of home page
1257
		$sql = 'SELECT fk_default_home FROM '.MAIN_DB_PREFIX.'website WHERE rowid = '.$object->id;
1258
		$resql = $this->db->query($sql);
1259
		if ($resql) {
1260
			$obj = $this->db->fetch_object($resql);
1261
			if ($obj) {
1262
				$object->fk_default_home = $obj->fk_default_home;
1263
			} else {
1264
				//$this->errors[] = 'Failed to get the Home page';
1265
				//$error++;
1266
			}
1267
		}
1268
1269
		// Regenerate index page to point to the new index page
1270
		$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
1271
		dolSaveIndexPage($pathofwebsite, $pathofwebsite.'/index.php', $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php', $pathofwebsite.'/wrapper.php');
1272
1273
		if ($error)
1274
		{
1275
			$this->db->rollback();
1276
			return -1;
1277
		}
1278
		else {
1279
			$this->db->commit();
1280
			return $object->id;
1281
		}
1282
	}
1283
1284
	/**
1285
	 * Rebuild all files of a containers of a website. TODO Add other files too.
1286
	 * Note: Files are already regenerated during importWebSite so this function is useless when importing a website.
1287
	 *
1288
	 * @return 	int						<0 if KO, >=0 if OK
1289
	 */
1290
	public function rebuildWebSiteFiles()
1291
	{
1292
		global $conf;
1293
1294
		$error = 0;
1295
1296
		$object = $this;
1297
		if (empty($object->ref))
1298
		{
1299
			$this->error = 'Function importWebSite called on object not loaded (object->ref is empty)';
1300
			return -1;
1301
		}
1302
1303
		$objectpagestatic = new WebsitePage($this->db);
1304
1305
		$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'website_page WHERE fk_website = '.$this->id;
1306
1307
		$resql = $this->db->query($sql);
1308
		if (! $resql) {
1309
			$this->error = $this->db->lasterror();
1310
			return -1;
1311
		}
1312
1313
		$num = $this->db->num_rows($resql);
1314
1315
		$i=0;
1316
		while ($i < $num) {
1317
			$obj = $this->db->fetch_object($resql);
1318
1319
			$newid = $obj->rowid;
1320
1321
			$objectpagestatic->fetch($newid);
1322
1323
			$aliasesarray = explode(',', $objectpagestatic->aliasalt);
1324
1325
			$filetpl = $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php';
1326
			$result = dolSavePageContent($filetpl, $object, $objectpagestatic);
1327
			if (!$result) {
1328
				$this->errors[] = 'Failed to write file '.basename($filetpl);
1329
				$error++;
1330
			}
1331
1332
			// Regenerate alternative aliases pages
1333
			if (is_array($aliasesarray))
1334
			{
1335
				foreach ($aliasesarray as $aliasshortcuttocreate)
1336
				{
1337
					if (trim($aliasshortcuttocreate))
1338
					{
1339
						$filealias = $conf->website->dir_output.'/'.$object->ref.'/'.trim($aliasshortcuttocreate).'.php';
1340
						$result = dolSavePageAlias($filealias, $object, $objectpagestatic);
1341
						if (!$result) {
1342
							$this->errors[] = 'Failed to write file '.basename($filealias);
1343
							$error++;
1344
						}
1345
					}
1346
				}
1347
			}
1348
1349
			$i++;
1350
		}
1351
1352
		if ($error)
1353
		{
1354
			return -1;
1355
		} else {
1356
			return $num;
1357
		}
1358
	}
1359
1360
	/**
1361
	 * Return if web site is a multilanguage web site. Return false if there is only 0 or 1 language.
1362
	 *
1363
	 * @return boolean			True if web site is a multilanguage web site
1364
	 */
1365
	public function isMultiLang()
1366
	{
1367
		return (empty($this->otherlang) ? false : true);
1368
	}
1369
1370
	/**
1371
	 * Component to select language inside a container (Full CSS Only)
1372
	 *
1373
	 * @param	array|string	$languagecodes			'auto' to show all languages available for page, or language codes array like array('en','fr','de','es')
1374
	 * @param	Translate		$weblangs				Language Object
1375
	 * @param	string			$morecss				More CSS class on component
1376
	 * @param	string			$htmlname				Suffix for HTML name
1377
	 * @return 	string									HTML select component
1378
	 */
1379
	public function componentSelectLang($languagecodes, $weblangs, $morecss = '', $htmlname = '')
1380
	{
1381
		global $websitepagefile, $website;
1382
1383
		if (!is_object($weblangs)) return 'ERROR componentSelectLang called with parameter $weblangs not defined';
1384
1385
		$arrayofspecialmainlanguages = array(
1386
			'en'=>'en_US',
1387
			'sq'=>'sq_AL',
1388
			'ar'=>'ar_SA',
1389
			'eu'=>'eu_ES',
1390
			'bn'=>'bn_DB',
1391
			'bs'=>'bs_BA',
1392
			'ca'=>'ca_ES',
1393
			'zh'=>'zh_TW',
1394
			'cs'=>'cs_CZ',
1395
			'da'=>'da_DK',
1396
			'et'=>'et_EE',
1397
			'ka'=>'ka_GE',
1398
			'el'=>'el_GR',
1399
			'he'=>'he_IL',
1400
			'kn'=>'kn_IN',
1401
			'km'=>'km_KH',
1402
			'ko'=>'ko_KR',
1403
			'lo'=>'lo_LA',
1404
			'nb'=>'nb_NO',
1405
			'fa'=>'fa_IR',
1406
			'sr'=>'sr_RS',
1407
			'sl'=>'sl_SI',
1408
			'uk'=>'uk_UA',
1409
			'vi'=>'vi_VN'
1410
		);
1411
1412
		// Load tmppage if we have $websitepagefile defined
1413
		$tmppage = new WebsitePage($this->db);
1414
1415
		$pageid = 0;
1416
		if (!empty($websitepagefile))
1417
		{
1418
		    $websitepagefileshort = basename($websitepagefile);
1419
		    if ($websitepagefileshort == 'index.php') $pageid = $website->fk_default_home;
1420
		    else $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), $websitepagefileshort);
1421
			if ($pageid > 0)
1422
			{
1423
				$tmppage->fetch($pageid);
1424
			}
1425
		}
1426
1427
		// Fill $languagecodes array with existing translation, nothing if none
1428
		if (!is_array($languagecodes) && $pageid > 0)
1429
		{
1430
			$languagecodes = array();
1431
1432
			$sql = "SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
1433
			$sql .= " FROM ".MAIN_DB_PREFIX."website_page as wp";
1434
			$sql .= " WHERE wp.fk_website = ".$website->id;
1435
			$sql .= " AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
1436
			if ($tmppage->fk_page > 0) $sql .= " OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
1437
			$sql .= ")";
1438
1439
			$resql = $this->db->query($sql);
1440
			if ($resql)
1441
			{
1442
				while ($obj = $this->db->fetch_object($resql))
1443
				{
1444
					$newlang = $obj->lang;
1445
					if ($obj->rowid == $pageid) $newlang = $obj->lang;
1446
					if (!in_array($newlang, $languagecodes)) $languagecodes[] = $newlang;
1447
				}
1448
			}
1449
		}
1450
		// Now $languagecodes is always an array. Example array('en', 'fr', 'es');
1451
1452
		$languagecodeselected = substr($weblangs->defaultlang, 0, 2); // Because we must init with a value, but real value is the lang of main parent container
1453
		if (!empty($websitepagefile))
1454
		{
1455
			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
1456
			if ($pageid > 0)
1457
			{
1458
				$pagelang = substr($tmppage->lang, 0, 2);
1459
				$languagecodeselected = substr($pagelang, 0, 2);
1460
				if (!in_array($pagelang, $languagecodes)) $languagecodes[] = $pagelang; // We add language code of page into combo list
1461
			}
1462
		}
1463
1464
		$weblangs->load('languages');
1465
		//var_dump($weblangs->defaultlang);
1466
1467
		$url = $_SERVER["REQUEST_URI"];
1468
		$url = preg_replace('/(\?|&)l=([a-zA-Z_]*)/', '', $url); // We remove param l from url
1469
		//$url = preg_replace('/(\?|&)lang=([a-zA-Z_]*)/', '', $url);	// We remove param lang from url
1470
		$url .= (preg_match('/\?/', $url) ? '&' : '?').'l=';
1471
		if (! preg_match('/^\//', $url)) $url = '/'.$url;
1472
1473
		$HEIGHTOPTION = 40;
1474
		$MAXHEIGHT = 4 * $HEIGHTOPTION;
1475
		$nboflanguage = count($languagecodes);
1476
1477
		$out = '<!-- componentSelectLang'.$htmlname.' -->'."\n";
1478
1479
		$out .= '<style>';
1480
		$out .= '.componentSelectLang'.$htmlname.':hover { height: '.min($MAXHEIGHT, ($HEIGHTOPTION * $nboflanguage)).'px; overflow-x: hidden; overflow-y: '.((($HEIGHTOPTION * $nboflanguage) > $MAXHEIGHT) ? ' scroll' : 'hidden').'; }'."\n";
1481
		$out .= '.componentSelectLang'.$htmlname.' li { line-height: '.$HEIGHTOPTION.'px; }'."\n";
1482
		$out .= '.componentSelectLang'.$htmlname.' {
1483
			display: inline-block;
1484
			padding: 0;
1485
			height: '.$HEIGHTOPTION.'px;
1486
			overflow: hidden;
1487
			transition: all .3s ease;
1488
			margin: 0 0 0 0;
1489
			vertical-align: top;
1490
		}
1491
		.componentSelectLang'.$htmlname.':hover, .componentSelectLang'.$htmlname.':hover a { background-color: #fff; color: #000 !important; }
1492
		ul.componentSelectLang'.$htmlname.' { width: 150px; }
1493
		ul.componentSelectLang'.$htmlname.':hover .fa { visibility: hidden; }
1494
		.componentSelectLang'.$htmlname.' a { text-decoration: none; width: 100%; }
1495
		.componentSelectLang'.$htmlname.' li { display: block; padding: 0px 15px; margin-left: 0; margin-right: 0; }
1496
		.componentSelectLang'.$htmlname.' li:hover { background-color: #EEE; }
1497
		';
1498
		$out .= '</style>';
1499
		$out .= '<ul class="componentSelectLang'.$htmlname.($morecss ? ' '.$morecss : '').'">';
1500
1501
		if ($languagecodeselected)
1502
		{
1503
			// Convert $languagecodeselected into a long language code
1504
			if (strlen($languagecodeselected) == 2) {
1505
				$languagecodeselected = (empty($arrayofspecialmainlanguages[$languagecodeselected]) ? $languagecodeselected.'_'.strtoupper($languagecodeselected) : $arrayofspecialmainlanguages[$languagecodeselected]);
1506
			}
1507
1508
			$countrycode = strtolower(substr($languagecodeselected, -2));
1509
			$label = $weblangs->trans("Language_".$languagecodeselected);
1510
			if ($countrycode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label);
1511
			$out .= '<a href="'.$url.substr($languagecodeselected, 0, 2).'"><li><img height="12px" src="/medias/image/common/flags/'.$countrycode.'.png" style="margin-right: 5px;"/><span class="websitecomponentlilang">'.$label.'</span>';
1512
			$out .= '<span class="fa fa-caret-down" style="padding-left: 5px;" />';
1513
			$out .= '</li></a>';
1514
		}
1515
		$i = 0;
1516
        if (is_array($languagecodes))
1517
        {
1518
            foreach ($languagecodes as $languagecode)
1519
            {
1520
            	// Convert $languagecode into a long language code
1521
                if (strlen($languagecode) == 2) {
1522
                	$languagecode = (empty($arrayofspecialmainlanguages[$languagecode]) ? $languagecode.'_'.strtoupper($languagecode) : $arrayofspecialmainlanguages[$languagecode]);
1523
                }
1524
1525
                if ($languagecode == $languagecodeselected) continue; // Already output
1526
1527
                $countrycode = strtolower(substr($languagecode, -2));
1528
                $label = $weblangs->trans("Language_".$languagecode);
1529
                if ($countrycode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label);
1530
                $out .= '<a href="'.$url.substr($languagecode, 0, 2).'"><li><img height="12px" src="/medias/image/common/flags/'.$countrycode.'.png" style="margin-right: 5px;"/><span class="websitecomponentlilang">'.$label.'</span>';
1531
                if (empty($i) && empty($languagecodeselected)) $out .= '<span class="fa fa-caret-down" style="padding-left: 5px;" />';
1532
                $out .= '</li></a>';
1533
                $i++;
1534
            }
1535
        }
1536
        $out .= '</ul>';
1537
1538
        return $out;
1539
    }
1540
}
1541