1<?php
2
3class XMLizer {
4
5
6	/**
7	 * Link to DB
8	 *
9	 * @var object|resource
10	 */
11	var $dblink;
12
13	/**
14	 * DB connection parameters
15	 *
16	 * @var array
17	 */
18	var $db1;
19
20	/**
21	 * Send XML http header
22	 *
23	 * @var bool
24	 */
25	var $header=true;
26
27	/**
28	 * DTD rules in external file
29	 *
30	 * @var string
31	 */
32	var $dtd;
33
34	/**
35	 * XSL rules in external file
36	 *
37	 * @var unknown_type
38	 */
39	private $xsl;
40
41	/**
42	 * Tot records
43	 *
44	 * @var int
45	 */
46	var $tot;
47
48	/**
49	* Output type: stream | filesystem
50	*/
51	var $output='stream';
52
53	/**
54	 * FIlename to copy XML (alternative method)
55	 *
56	 * @var string
57	 */
58	var $filename='';
59
60	/**
61	 * XML generated source
62	 *
63	 * @var string
64	 */
65	private $XML ;
66
67
68
69	/**
70	 * Contructor
71	 *
72	 * @param object $dblink
73	 * @param array $db1
74	 * @return XMLizer
75	 */
76	function XMLizer($dblink, $db1){
77
78		if(is_object($dblink) || is_resource($dblink)){
79
80			$this->dblink=$dblink;
81		}
82		else{
83			die("Impossibile usare la connessione fornita alla classe XMLizer");
84		}
85
86		if(is_array($db1)){
87
88			$this->db1=$db1;
89
90		}
91		else{
92			die("Impossibile usare la variabile db1 fornita alla classe XMLizer");
93		}
94
95	}
96
97
98
99	/**
100	 * Add a XSL stylesheet to XML
101	 *
102	 * @param string $xsl
103	 */
104	function addXSL($xsl){
105
106		$this->xsl=$xsl;
107
108	}
109
110	/**
111	 * Add a DTD reference to XML
112	 *
113	 * @param string $dtd
114	 */
115	function addDTD($dtd){
116
117		$this->dtd=$dtd;
118
119	}
120
121
122	function _prendi_diritti_report($rif_tab_nome,$query_based){
123
124
125			if($query_based){
126
127				// cerca i diritti come report tabella
128				$q=$vmreg->query("SELECT * FROM {$this->db1['frontend']}.xml_rules WHERE nome_report='$rif_tab_nome' ORDER BY lastData DESC LIMIT 1",$this->dblink);
129			}
130			else{
131				// cerca i diritti come report tabella
132				$q=$vmreg->query("SELECT * FROM {$this->db1['frontend']}.xml_rules WHERE tabella='$rif_tab_nome' ORDER BY lastData DESC LIMIT 1",$this->dblink);
133
134			}
135
136
137			// Gestione della presenza
138
139			if($vmreg->num_rows($q)==0){
140
141				return false;
142			}
143			else $RS_rules=$vmreg->fetch_assoc($q);
144
145
146
147			// Gestione dei diritti
148
149			if($RS_rules['accesso']=='PUBLIC'){
150
151				// non fa niente e continua con lo script
152			}
153			elseif($RS_rules['accesso']=='FRONTEND'){
154				if(!isset($_SESSION['user']['livello'])) return false;
155			}
156			elseif($RS_rules['accesso']=='GROUP'){
157
158				$gruppi=explode(",",$RS_rules['accesso_gruppo']);
159
160				if(is_array($gruppi) && in_array($_SESSION['gid'],$gruppi)){
161
162					// va avanti
163				}
164				else{
165					return false;
166				}
167			}
168			else{
169				// RESTRICT o altro...
170
171				return false;
172			}
173
174			return true;
175	}
176
177
178
179
180
181
182
183
184
185
186
187	/**
188	 * Create a XML file from table
189	 *
190	 * @param string $tabella
191	 * @param bool $include_submask
192	 * @param mixed $tipo
193	 * @param int $id_record
194	 * @param int $gid
195	 * @param bool $RAW
196	 */
197	function table2XML($tabella,$include_submask=false,$tipo='all',$id_record=null,$gid=null,$RAW=false){
198
199		$test_diritti = $this->_prendi_diritti_report($tabella,false);
200
201		if(!$test_diritti) die("Non si possiedono i diritti per leggere questo report");
202
203		if($gid==null) $gid=intval($_SESSION['gid']);
204
205		$PK = prendi_PK($tabella,$gid);
206
207
208		$orderby = prendi_orderby($tabella,$gid);
209
210		if(trim($orderby)=='ASC') $orderby = 1;
211
212		//aggiungi l'ID all'order by
213		$orderby_doppio=$orderby.", $PK ";
214
215		$campo_orderby = str_replace(array(" ASC"," DESC"),"",$orderby);
216		$operatore_orderby = preg_match('| DESC|i',$orderby) ? " > " : " < ";
217
218
219
220		// CASO RISULTATO DI RICERCA-------------------------------------------------------
221		// SE c'� l'id in GET prendi calcola a che punto dell'elenco si � arrivati
222		if(isset($_GET['id']) && intval($_GET['id'])>0){
223
224			// Prendi il moe del campo orderby ed il vaolre relativo all'id
225
226			$sql_calcola_sub = "SELECT s.$campo_orderby
227									FROM $tabella s WHERE s.".$PK."='".$_GET['id']."'";
228
229			$sql_calcola = "SELECT count(*) FROM ".$_GET['action']." t
230									WHERE t.$campo_orderby $operatore_orderby ($sql_calcola_sub) OR t.$campo_orderby IS NULL";
231
232			$query_calcola = $vmsql->query($sql_calcola,$this->dblink);
233
234			list($offset)=$vmsql->fetch_row($query_calcola);
235
236		}
237		else{
238			$offset= (int) $_GET['c'];
239		}
240
241
242		list($tot_records) = $vmsql->fetch_row($vmsql->query("SELECT count(*) FROM $tabella",$this->dblink));
243
244
245
246
247
248		if($include_submask){
249
250			// SINGOLO RECORD BASATO SULLA SERIE ORDINATA
251			if(is_numeric($tipo)){
252
253				$this->xmlize_table_sub($tabella,$gid,null,$offset,1);
254			}
255			// INTERVALLO DI RECORD BASATO SULLA SERIE ORDINATA
256			elseif(preg_match("'([0-9]+),([0-9]+)'",$tipo,$match)>0){
257
258				$offset=intval($match[1]);
259				$limit=intval($match[2]);
260
261				$this->xmlize_table_sub($tabella,$gid,null,$offset,$limit);
262			}
263			// TUTTI I RECORD
264			else{
265
266				$this->xmlize_table_sub($tabella,$gid);
267
268			}
269
270
271
272
273		}
274		else{
275
276
277			// OPZIONE PER AVERE I CAMPI ROW
278			// i campi row sono quelli non elaborati, in caso contrario mostra i campi richiesti in tabella con le subquery
279			if($RAW){
280
281				$campi_tabella="*";
282			}
283			else{
284
285				$campi_tabella = campi_elaborati($tabella,true);
286				$tabella = $tabella . " t ";
287			}
288
289			// SINGOLO RECORD BASATO SULLA SERIE ORDINATA
290			if(is_numeric($tipo)){
291
292				$sql = "SELECT ".$campi_tabella." FROM $tabella  ORDER BY $orderby_doppio ".$vmsql->limit(1,$offset);
293			}
294
295			// INTERVALLO DI RECORD BASATO SULLA SERIE ORDINATA
296			elseif(preg_match("'([0-9]+),([0-9]+)'",$tipo,$match)>0){
297
298				$offset=intval($match[1]);
299				$limit=intval($match[2]);
300
301				$sql="SELECT ".$campi_tabella." FROM $tabella ORDER BY $orderby_doppio ".$vmsql->limit($limit,$offset);
302
303			}
304
305			// RECORD PER SINGOLO ID (DA CAMPO PK)
306			elseif(isset($id_record) && $id_record>0){
307
308				$sql="SELECT ".$campi_tabella." FROM $tabella WHERE $PK=".intval($_GET['id'])." ORDER BY $orderby_doppio ";
309			}
310
311			// TUTTI I RECORD
312			else{
313
314				$sql="SELECT ".$campi_tabella." FROM $tabella ORDER BY $orderby_doppio ";
315
316			}
317
318
319
320			// restituisco l'XML
321
322			$this->xmlize($sql, $offset);
323
324
325		}
326
327
328		$this->stream();
329
330	}
331
332
333
334
335
336
337
338
339
340
341
342
343	function query2XML(){
344
345		$test_diritti = $this->_prendi_diritti_report($tabella,true);
346
347		if(!$test_diritti) die("Non si possiedono i diritti per leggere questo report");
348	}
349
350
351
352
353	/**
354	 * Funzione che genera l'XML da una data query.
355	 * La funzione � utilizzata in molte occasioni da VFront.
356	 *
357	 * @param string $sql SQL SELECT che genera l'XML
358	 * @param int $offset OFFSET della query SQL
359	 * @return string XML risultato della query
360	 */
361	function xmlize($sql,$offset=0){
362
363
364		$q = $vmsql->query($sql,$this->dblink);
365
366		$tot=$vmsql->num_rows($q);
367
368		if($tot==0){
369
370			return null;
371		}
372
373		// Inizia a fare l'xml
374
375
376
377		$XML="";
378
379		$XML.= ($this->header) ? "<?xml version='1.0' encoding='utf-8'?>\n" : "";
380
381		$XML.= ($this->dtd) ? "<!DOCTYPE vfront SYSTEM \"".$this->dtd."\">\n" : "";
382
383		$XML.= ($this->xsl!='') ? "<?xml-stylesheet type=\"text/xsl\" href=\"".$this->xsl."\" ?>\n" : "";
384
385		$XML.="<recordset tot=\"$tot\">\n";
386
387		if($offset===false){
388			$auto_offset=true;
389			$offset =1;
390		}else{
391			$auto_offset=false;
392		}
393
394		while($RS=$vmsql->fetch_assoc($q)){
395
396			$XML.="\t".$this->xmlize_campo('row',array("offset"=>$offset))."\n";
397
398			foreach($RS as $k=>$val){
399
400				$val = vf_utf8_encode(trim($val));
401
402				if($val!="" && !is_numeric($val)){
403					$val="<![CDATA[".$val."]]>";
404				}
405
406				$XML.="\t\t".$this->xmlize_campo($k,array());
407				$XML.=$val;
408				$XML.="</$k>\n";
409			}
410
411			$XML.="\t</row>\n";
412
413			if($auto_offset){
414				$offset++;
415			}
416
417		}
418
419		$XML.="</recordset>";
420
421
422
423
424		if($this->output=='stream') {
425
426			$this->XML=$XML;
427		}
428
429		else{
430
431			$fp =fopen($this->filename,"w");
432			fwrite($fp,$XML);
433			fclose($fp);
434			return true;
435		}
436
437	}
438
439
440	/**
441	 * Funzione che genera l'XML per uno specifico campo
442	 *
443	 * @param string $tag Il nome del campo (che diverr� il nome del tag)
444	 * @param array $attr Array di attributi (nome_attributo=>valore)
445	 * @return string XML
446	 */
447	function xmlize_campo($tag,$attr){
448
449			$attributi="";
450
451			foreach($attr as $k=>$val){
452
453				$attributi .=" $k=\"$val\"";
454			}
455
456			return "<".$tag.$attributi.">";
457
458	}
459
460
461
462
463	/**
464	 * Funzione che genera l'XML con anche i record delle sottomaschere.
465	 * Partendo da una tabella prestabilita con anche la gestione
466	 * dei record figli presenti nelle sottomaschere attivate.
467	 *
468	 * @param int $oid ID della tabella per il gruppo
469	 * @param string $filename Nome della tabella
470	 * @param bool $sub Mostra anche i record delle sottomaschere
471	 * @param int $offset Offset riportato nell'XML
472	 * @param int $tot Totale di record, riportato nell'XML
473	 * @param string $xsl Eventuale foglio di stile da associare
474	 * @param string $dtd Eventuale DTD da associare
475	 * @param bool $header Manda un header di tipo "Content-type=XML" (default: true)
476	 * @return string XML output
477	 * @see xml.php
478	 * @todo Questa funzione se ottimizzata pu� sostituire la procedura richiamata dal file xml.php
479	 */
480	function xmlize_table_sub($tabella,$gid=null,$filename=null,$offset=0,$tot=0){
481
482		if($gid==null){
483			$gid= (int) $_SESSION['gid'];
484		}
485
486		$oid=name2oid($tabella,$gid);
487
488		$cols=prendi_colonne_frontend($oid,"column_name,table_name, orderby, orderby_sort",true);
489
490		$ORDER_BY = ($cols[2][0]!='') ? "ORDER BY ".$cols[2][0]." ".$cols[3][0] : "";
491
492		$OFF= ($offset==0) ? "" : "$offset";
493
494		$LIMIT = ($tot==0) ? "" : $vmsql->limit($tot,$OFF);
495
496		$sql="SELECT ".implode(",",$cols[0])." FROM ".$cols[1][0]." $ORDER_BY  $LIMIT";
497
498
499
500		$q = $vmsql->query($sql,$this->dblink);
501
502		if($vmsql->num_rows($q)==0){
503
504			return null;
505		}
506
507		// Inizia a fare l'xml
508
509
510
511		$XML="";
512
513
514
515		$XML.= ($this->header) ? "<?xml version='1.0' encoding='utf-8'?>\n" : "";
516
517		$XML.= ($this->dtd!='') ? "<!DOCTYPE vfront SYSTEM \"".$this->dtd."\">\n" : "";
518
519		$XML.= ($this->xsl!='') ? "<?xml-stylesheet type=\"text/xsl\" href=\"".$this->xsl."\" ?>\n" : "";
520
521		$XML.="<recordset tot=\"$tot\">\n";
522
523		if($offset==0){
524			$auto_offset=true;
525			$offset =1;
526		}else{
527			$auto_offset=false;
528		}
529
530		$fkk = prendi_K_relazione_sub($oid);
531
532		while($RS=$vmsql->fetch_assoc($q)){
533
534			$XML.="\t".$this->xmlize_campo('row',array("offset"=>$offset))."\n";
535
536			foreach($RS as $k=>$val){
537
538				$val = vf_utf8_encode(trim($val));
539
540				if($val!="" && !is_numeric($val)){
541					$val="<![CDATA[".$val."]]>";
542				}
543
544				$XML.="\t\t".$this->xmlize_campo($k,array());
545				$XML.=trim($val);
546				$XML.="</$k>\n";
547
548				if($fkk[0][0]==$k){
549
550	//				echo "ORA!";
551					$XML.=$this->xmlize_sottomaschera($val,$oid);
552
553				}
554			}
555
556
557
558			$XML.="\t</row>\n";
559
560			if($auto_offset){
561				$offset++;
562			}
563
564		}
565
566		$XML.="</recordset>\n";
567
568
569
570
571		if($this->output=='stream') $this->XML = $XML;
572		else{
573
574			$fp =fopen($filename,"w");
575			fwrite($fp,$XML);
576			fclose($fp);
577			return true;
578		}
579
580	}
581
582
583	/**
584	 * Funzione di generazione di XML da una sottomaschera
585	 *
586	 * @param int $id_parent id_table della tabella parent di questa sottomaschera
587	 * @param int $oid ID della sottomaschera considerata
588	 * @param int $gid ID del gruppo considerato
589	 * @param bool $solo_campi_visibili Se vera mostra solo i campi con diritti SELECT della sottomaschera
590	 * @return string Frammento di XML
591	 */
592	function xmlize_sottomaschera($id_parent,$oid,$gid=0,$solo_campi_visibili=false){
593
594		$sub=prendi_sottomaschere($oid);
595
596		for($i=0;$i<count($sub);$i++){
597
598			$order_sub = ($sub[$i]["orderby_sub"]!='') ?  "ORDER BY ".$sub[$i]["orderby_sub"] : "";
599
600			$sql_sub="SELECT * FROM ".$sub[$i]['nome_tabella']." WHERE ".$sub[$i]['campo_fk_sub']."='$id_parent' $order_sub limit 10";
601
602			$q_sub=$vmsql->query($sql_sub,$this->dblink);
603
604			if($vmsql->num_rows($q_sub)>0){
605
606				$XMLSUB.="\t\t<subrecordset tabella=\"".$sub[$i]['nome_tabella']."\" nomefrontend=\"".$sub[$i]['nome_frontend']."\">\n";
607
608				$offset=1;
609
610				while($RS=$vmsql->fetch_assoc($q_sub)){
611
612					$XMLSUB.="\t\t\t".$this->xmlize_campo('subrow',array("offset"=>$offset))."\n";
613
614					foreach($RS as $k=>$val){
615
616						$val = vf_utf8_encode(trim($val));
617
618						if($val!="" && !is_numeric($val)){
619							$val="<![CDATA[".$val."]]>";
620						}
621
622						$XMLSUB.="\t\t\t\t".$this->xmlize_campo($k,array());
623						$XMLSUB.=$val;
624						$XMLSUB.="</$k>\n";
625					}
626
627					$XMLSUB.="\t\t\t</subrow>\n";
628
629					$offset++;
630
631				}
632
633				$XMLSUB.="\t\t</subrecordset>\n";
634
635			}
636
637		}
638
639		return $XMLSUB;
640	}
641
642
643	/**
644	 * Stream output XML
645	 *
646	 */
647	function stream(){
648
649		header("Content-Type: text/xml; charset=".FRONT_ENCODING);
650		echo $this->XML;
651	}
652
653
654
655}
656
657
658
659
660
661
662?>