HMG + PHP simplexml_load_file()

HMG en Español

Moderator: Rathinagiri

franco
Posts: 426
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Re: HMG + PHP simplexml_load_file()

Post by franco »

Here is what i would like to do.
Customer logs into web., username would become CCode so it would be set up to get only their data from file.
I do not know how to create xml so I used text file.

I use build.bat to compile

Code: Select all

include <hmg.ch>
***************            This is a Consignment store 

Function Main

Crtabletext()
CrText()
WebView()

RETURN

FUNCTION CrText    // Client would send this file to folder on web every day
USE WebClient Shared
SET INDEX TO Ccode
Go Top
SET CONSOLE OFF
SET PRINT ON
SET PRINTER TO 'CLLIST.TXT'
LIST CCODE,ITEM,DESC,STR(PRICE),STR(SALEPRICE) TO PRINTER
SET PRINTER TO
SET PRINT OFF
SET CONSOLE OFF
CLOSE ALL

***************************** this type code would be on website or ????
* <?php
* $myfile = fopen("cllist.txt", "r") or die("Unable to open file!");
* // Output one line until end-of-file
* while(!feof($myfile)) {                                   // and $ccode == $username    ??????
* echo fgets($myfile) . "<br>";
* }
* fclose($myfile);
* ?>



RETURN

FUNCTION WEBVIEW   // Clients Customer could go on website and look at only their information
**************************** Would be in php
	Local MMCODE:= '', MPRICE := 0, TEMP := ''
	MMCODE := InputBox('Enter Id..10001..10002')           // On the web this would be username aADD(CF,{'CCode'     ,'C' , 7,0})
	IF LEN(ALLTRIM(MMCODE)) = 0
		MSGBOX('No ID Entered... Program will Close')
		CLOSE ALL
		DELETE FILE WebClient.dbf
		DELETE FILE CCODE.NTX
		DELETE FILE CLLIST.TXT
		RETURN
	ENDIF
	CF := {}	
	aADD(CF,{'REC'     ,'C' , 30,0})			
	aADD(CF,{'CCODE'    ,'C' , 7,0})      // Client Id Code
	aADD(CF,{'ITEM'  ,'C' , 25,0})        // Inventory Number
	aADD(CF,{'DESC'  ,'C' , 25,0})        // Item Description 
	aADD(CF,{'PRICE'     ,'C' , 15,0})    // Suggested Price to sell for 
	aADD(CF,{'SALEPRICE' ,'C' , 15,0})   //If sold
	aADD(CF,{'NPRICE'     ,'N' , 10,2})    // Suggested Price to sell for 
	aADD(CF,{'NSALEPRICE' ,'N' , 10,2})

	DBCREATE( 'temp.dbf',CF )
   	USE
	USE TEMP NEW EXCLUSIVE
	APPEND FROM CLLIST.TXT DELIMITED WITH BLANK
	IF LEN(ALLTRIM(MMCODE)) > 0 
		INDEX  ON CCODE TO TEMP FOR ALLTRIM(CCODE) == MMCODE
	ENDIF
	REPLACE ALL NPRICE WITH VAL(PRICE)
	REPLACE ALL NSALEPRICE WITH VAL(SALEPRICE)
	DBAPPEND()      
	REPLACE REC WITH 'TOTALS'
	REPLACE CCODE WITH MMCODE
	SUM ALL NPRICE TO MPRICE
	GO BOTTOM
	REPLACE NPRICE WITH MPRICE
	SUM ALL NSALEPRICE TO MPRICE
	GO BOTTOM
	REPLACE NSALEPRICE WITH MPRICE
	
		EDIT EXTENDED WORKAREA TEMP   // I used edit here for simplicity
	
	CLOSE ALL
	DELETE FILE TEMP.DBF
	DELETE FILE TEMP.NTX
	DELETE FILE WebClient.dbf
	DELETE FILE CCODE.NTX
	DELETE FILE CLLIST.TXT
	RETURN

FUNCTION Crtabletext
if ! file('WebClient.dbf')
	CF := {}
	aADD(CF,{'NAME'     ,'C' , 30,0})
	aADD(CF,{'CCODE'    ,'C' , 7,0})      // Client Id Code
	aADD(CF,{'ITEM'  ,'C' , 25,0})        // Inventory Number
	aADD(CF,{'DESC'  ,'C' , 25,0})        // Item Description 
	aADD(CF,{'PRICE'     ,'N' , 10,2})    // Suggested Price to sell for 
	aADD(CF,{'SALEPRICE' ,'N' , 10,2})   //If sold

	DBCREATE( 'WebClient.dbf',CF )
    USE
    USE WebClient EXCLUSIVE NEW
	WebClient->( DBAPPEND())
	WebClient->( FIELDPUT(1, 'JOHN DOE' ))
	WebClient->( FIELDPUT(2, '10001' ))
   	WebClient->( FIELDPUT(3,'10001-1'))
    	WebClient->( FIELDPUT(4,'WAGON'))
    	WebClient->( FIELDPUT(5,5.00))
	WebClient->( FIELDPUT(6,5.00))

	WebClient->( DBAPPEND())
	WebClient->( FIELDPUT(1, 'TOM SMITH' ))
	WebClient->( FIELDPUT(2, '10002' ))
   	WebClient->( FIELDPUT(3,'10002-1'))
    	WebClient->( FIELDPUT(4,'SWEATER'))
    	WebClient->( FIELDPUT(5,10.00))
	WebClient->( FIELDPUT(6,0.00))

	WebClient->( DBAPPEND())
	WebClient->( FIELDPUT(1, 'JOHN DOE' ))
	WebClient->( FIELDPUT(2, '10001' ))
   	WebClient->( FIELDPUT(3,'10001-2'))
    	WebClient->( FIELDPUT(4,'BIKE'))
    	WebClient->( FIELDPUT(5,25.00))
	WebClient->( FIELDPUT(6,0.00))
   USE
	USE WebClient EXCLUSIVE NEW
	INDEX ON CCODE TO CCODE
	USE
endif

Return
I hope this makes sense,
Franco
All The Best,
Franco
Canada

User avatar
mol
Posts: 3326
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 249 times
Been thanked: 152 times
Contact:

Post by mol »

My first suggestion is creating different file for different client. The problem is if you have thousands of clients, you will need upload to www server a lot of files with sale reports.
Second suggestion is creating XML file - it will contain whole sale.

Code: Select all

#include "hmg.ch"
***************            This is a Consignment store 
#define tab	space(5)

Function Main

Crtabletext()
//CrText()
generateXML("CLIST.XML")
//WebView()

RETURN

Code: Select all

*------------------------
function generateXML
	param cOutputFileName
	
	local cClient := ""
	local fOutputXML
	local lFirstClient := .t.
	local lFinishClient := .f.
	
	fOutputXML := fcreate(cOutputFileName)
	if fOutputXML = -1
		// error
		MsgStop("Error while creating: "+cOutputFileName)
		return .f.
	endif

	USE WebClient Shared
	SET INDEX TO Ccode
	Go Top
	
	pxml('<?xml version="1.0" encoding="utf-8"?>',,fOutputXML,'')
	pxml('<Sale>',,fOutputXML,'')
	do while !WebClient->(eof())
		if cClient <> alltrim(WebClient->cCode)
			cClient := alltrim(WebClient->cCode)
			if !lFirstClient
				// finish previous client
				pxml('</Client>',,fOutputXML,'')
				lFinishClient := .f.
			endif
			pxml('<Client cCode="'+cClient+'">',,fOutputXML,'')
			lFirstClient := .f.
			lFinishClient := .t.
		endif
		pxml(tab+'<SalePosition>',, fOutputXML,'')
		pxml('ITEM', WebClient->Item, fOutputXML,'')
		pxml('DESC', WebClient->Desc, fOutputXML,'')
		pxml('PRICE', str(WebClient->Price,12,2), fOutputXML,'')
		pxml('SALEPRICE', str(WebClient->Saleprice,12,2), fOutputXML,'')
		pxml(tab+'</SalePosition>',, fOutputXML,'')
		WebClient->(DBSkip())
	enddo
	
	if lFinishClient
		// finish last client
		pxml('</Client>',,fOutputXML,'')
	endif
	
	// finish Sale
	pxml('</Sale>',,fOutputXML,'')
	fClose(fOutputXML)
	Close All
return .t.
		
*-------------------------
FUNCTION pxml(pole, wartosc, zb_save, obiekt)
Local fbuf, pozt, poz_w_tot

// Thanks to Edk from hmgforum from this function

IF obiekt=NIL
	obiekt:=''
ENDIF
IF !EMPTY(obiekt)
	obiekt=obiekt+':'
ENDIF

IF wartosc=NIL
	IF EMPTY(obiekt)
		fbuf:=pole+CRLF
	ELSE
		fbuf:=pole
		pozt:=AT("</",fbuf)
		IF pozt>0
			fbuf:=SUBSTR(fbuf,1,pozt+1)+obiekt+SUBSTR(fbuf,pozt+2)
		ENDIF
		pozt:=AT("<",fbuf)
		IF pozt>0 .AND. SUBSTR(fbuf,pozt+1,1)#'/'
			fbuf:=SUBSTR(fbuf,1,pozt)+obiekt+SUBSTR(fbuf,pozt+1)
		ENDIF
		fbuf:=fbuf+CRLF
	ENDIF
ELSE
	IF EMPTY(wartosc)
		fbuf:=''
	ELSE
		fbuf:=tab+tab+'<'+obiekt+pole+'>'+ALLTRIM(wartosc)+'</'+obiekt+pole+'> '+CRLF
	ENDIF
ENDIF

FWRITE(zb_save,fbuf,LEN(fbuf))

RETURN Nil
After that, you should upload CLIST.XML file to server.
On the server side, you should have PHP program, which will test user and his password. If it's OK, you should report user's sale.

Here is sample php code without checking reading rights:

Code: Select all

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8;" />
<head>
</head>
<body>
<?PHP
//include('./settings.php'); 

if ( $_GET["cCode"] == false )
{
	print "You dind't send client code!";
	exit;
}
$cRequestedClient = $_GET["cCode"];
print "Requested clinet: ".$cRequestedClient."<br>";
$SalesFile = './CLIST.XML';
$xml = simplexml_load_file($SalesFile);

foreach($xml->children() as $ClientSale)
{
	$cCodeClientSale = $ClientSale['cCode'];
	if($cCodeClientSale==$cRequestedClient	)
	{
		print "Client code: ";
		print $ClientSale['cCode'];
		echo "<br>";
		$i=1;
		foreach($ClientSale->children() as $SaleItem)
		{
			print $i++;
			print " ";
			print $SaleItem->ITEM;
			print " ";
			print $SaleItem->DESC;
			print " ";
			print $SaleItem->PRICE;
			print " ";
			print $SaleItem->SALEPRICE;
			print "<br>";
		}
	}
			
}
//echo $xml;
?>
</body>
</html>
You can test it on my server:
http://molsystemy.pl/franco/test1.php?cCode=10001
or
http://molsystemy.pl/franco/test1.php?cCode=10002

franco
Posts: 426
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

Mol,
Could we send a txt file with all information each day with ccode as first field to the web folder.
Then open file in php with fopen() as in Dragan`s sample 3
In php code echo while ! eof() and $? = ccode.
This looks like it could be very simple and my client would only have to use their own point of sale and create a report.txt to send to web folder
each day.
When their client logs in they would only get the info with their ccode, the rest would skip past.
There would only be one text file on the web with a small amount of php code.
All The Best,
Franco
Canada

User avatar
mol
Posts: 3326
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 249 times
Been thanked: 152 times
Contact:

Post by mol »

So, php file can be like this

Code: Select all

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8;" />
<head>
</head>
<body>
<?PHP
//include('./settings.php'); 

if ( $_GET["cCode"] == false )
{
	print "You dind't send client code!";
	exit;
}
$cRequestedClient = $_GET["cCode"];
print "Requested clinet: ".$cRequestedClient."<br>";
$SalesFile = './CLLIST.TXT';
$lines = file($SalesFile);
foreach ($lines as $line) {
	$cCodeClientSale = trim(substr($line, 9, 7));
	
 	if($cCodeClientSale==$cRequestedClient	)
	{
		print $line."<br>";
	}
}
//echo $xml;
?>
</body>
</html>
You can test it with http://www.molsystemy.pl/franco/test2.php?cCode=10001

franco
Posts: 426
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

That looks pretty straight forward.
I am sure the print can look better say with a header and columns in line, but that is for later.
All The Best,
Franco
Canada

User avatar
mol
Posts: 3326
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 249 times
Been thanked: 152 times
Contact:

Post by mol »

You can change method of generation report file - it's not necessary to use printing system:

Code: Select all

FUNCTION CrText    // Client would send this file to folder on web every day
USE WebClient Shared
SET INDEX TO Ccode
Go Top
COPY FIELDS CCODE,ITEM,DESC,PRICE,SALEPRICE TO CLLIST.TXT DELIMITED WITH ""
CLOSE ALL

After that, it's easier to prepare www:

Code: Select all

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8;" />
<head>
<style>
table {
	width:70%;
}
table, td, th {
	border: 1px solid black;
	border-collapse: collapse;
}
h1 {
	color: #00A;
}
</style>
</head>
<body>
<?PHP
//include('./settings.php'); 

if ( $_GET["cCode"] == false )
{
	print "You dind't send client code!";
	exit;
}
$cRequestedClient = $_GET["cCode"];
print "<h1>Sale of client: ".$cRequestedClient."</h1><br>";
print '<table>';
print "<th>No</th><th>Item</th><th>Description</th><th>Price</th><th>Saleprice</th>";
$SalesFile = './CLLIST.TXT';
$lines = file($SalesFile);
$no=1;
foreach ($lines as $line) {
	$aline=explode(',',$line);
	$cCodeClientSale = trim($aline[0]);
	
 	if($cCodeClientSale==$cRequestedClient	)
	{
		print "<tr>";
		print "<td>".$no."</td>";
		print "<td>".$aline[1]."</td>";
		print "<td>".$aline[2]."</td>";
		print "<td>".$aline[3]."</td>";
		print "<td>".$aline[4]."</td></tr>";
		$no++;
	}
}
print "</table>";
?>
</body>
</html>
You can test it with http://www.molsystemy.pl/franco/test3.php?cCode=10001

franco
Posts: 426
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

Thanks mol,
This look`s very good. Somehow needs totals at bottom of dollar column.
I am going to get web site so I can work With it properly.
I have tried to use your code just in computer but am having trouble to make it work properly.
Franco
All The Best,
Franco
Canada

User avatar
mol
Posts: 3326
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 249 times
Been thanked: 152 times
Contact:

Post by mol »

If you want to test .php program, you should install e.g. WAMP - I'm using it for local testing.

User avatar
mol
Posts: 3326
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 249 times
Been thanked: 152 times
Contact:

Post by mol »

http://molsystemy.pl/franco/test3.php?cCode=10001

Code: Select all

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8;" />
<head>
<style>
table {
	width:70%;
}
table, td, th {
	border: 1px solid black;
	border-collapse: collapse;
}
h1 {
	color: #00A;
}
</style>
</head>
<body>
<?PHP
//include('./settings.php'); 

if ( $_GET["cCode"] == false )
{
	print "You dind't send client code!";
	exit;
}
$cRequestedClient = $_GET["cCode"];
print "<h1>Sale of client: ".$cRequestedClient."</h1><br>";
print '<table>';
print "<th>No</th><th>Item</th><th>Description</th><th>Price</th><th>Saleprice</th>";
$SalesFile = './CLLIST3.TXT';
$lines = file($SalesFile);
$no=1;
$total1=0;
$total2=0;
foreach ($lines as $line) {
	$aline=explode(',',$line);
	$cCodeClientSale = trim($aline[0]);
	
 	if($cCodeClientSale==$cRequestedClient	)
	{
		print "<tr>";
		print "<td>".$no."</td>";
		print "<td>".$aline[1]."</td>";
		print "<td>".$aline[2]."</td>";
		print "<td>".$aline[3]."</td>";
		print "<td>".$aline[4]."</td></tr>";
		$total1+=$aline[3];
		$total2+=$aline[4];
		$no++;
	}
}
print "<tr>";
print "<td></td>";
print "<td></td>";
print "<td>TOTAL</td>";
print "<td>".$total1."</td>";
print "<td>".$total2."</td></tr>";
print "</table>";
?>
</body>
</html>

franco
Posts: 426
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

Can we see the cents in the total.
Then great.
All The Best,
Franco
Canada

Post Reply