/* * bridge_session.prg - FiveNode * * Copyright (c) 2026 Charles KWON ( Charles KWON Ohjun, charleskwonohjun@gmail.com ) * All rights reserved. */ #include "hbclass.ch" // bridge_session.prg // Session management - mod_harbourv2 MH_Sessions 100% compatible THREAD STATIC ts_oSession // ── Public API ── FUNCTION fn_SessionInit( cName, nExpired ) hb_default( @cName, "MHSID" ) hb_default( @nExpired, 3600 ) ts_oSession := MH_Sessions():New( cName, nExpired ) ts_oSession:Init() RETURN NIL FUNCTION fn_Session( cKey, uValue ) IF ts_oSession == NIL RETURN NIL ENDIF IF cKey == NIL RETURN ts_oSession:hData ENDIF IF uValue != NIL ts_oSession:hData[ cKey ] := uValue RETURN uValue ENDIF IF hb_HHasKey( ts_oSession:hData, cKey ) RETURN ts_oSession:hData[ cKey ] ENDIF RETURN NIL FUNCTION fn_SessionWrite() IF ts_oSession != NIL ts_oSession:Write() ENDIF RETURN NIL FUNCTION fn_SessionEnd() IF ts_oSession != NIL ts_oSession:End() ts_oSession := NIL ENDIF RETURN NIL FUNCTION fn_SessionActive() RETURN ts_oSession != NIL FUNCTION fn_oSession( o ) IF o != NIL ts_oSession := o ENDIF RETURN ts_oSession FUNCTION fn_Garbage() IF ts_oSession != NIL ts_oSession:Garbage() ENDIF RETURN NIL // ── MH_Sessions class ── CREATE CLASS MH_Sessions VAR cName VAR cId VAR nExpired VAR hData VAR cSessionPath VAR lDestroy METHOD New( cName, nExpired ) METHOD Init() METHOD SetId() METHOD SessionFile() METHOD Read_CSID() METHOD Read() METHOD Write() METHOD Data( cKey, uValue ) METHOD End() METHOD Garbage( dMaxDate ) METHOD IsFile() METHOD Info() ENDCLASS METHOD New( cName, nExpired ) CLASS MH_Sessions ::cName := cName ::nExpired := nExpired ::hData := { => } ::cId := "" ::lDestroy := .F. ::cSessionPath := ctx_get( "document_root", "." ) + "/.sessions" IF ! hb_DirExists( ::cSessionPath ) hb_DirCreate( ::cSessionPath ) ENDIF RETURN Self METHOD Init() CLASS MH_Sessions ::Read_CSID() IF Empty( ::cId ) ::SetId() fn_SetCookie( ::cName, ::cId, ::nExpired, "/", NIL, .F., .T. ) ELSE ::Read() ENDIF RETURN NIL METHOD SetId() CLASS MH_Sessions ::cId := hb_MD5( hb_TToS( hb_DateTime() ) + hb_ntos( hb_RandomInt( 100000, 999999 ) ) ) RETURN ::cId METHOD SessionFile() CLASS MH_Sessions RETURN ::cSessionPath + "/" + ::cId + ".session" METHOD Read_CSID() CLASS MH_Sessions LOCAL cCookieVal := fn_GetCookies( ::cName ) IF ! Empty( cCookieVal ) ::cId := cCookieVal ENDIF RETURN ::cId METHOD Read() CLASS MH_Sessions LOCAL cFile := ::SessionFile() LOCAL cContent IF hb_FileExists( cFile ) cContent := hb_MemoRead( cFile ) IF ! Empty( cContent ) hb_jsonDecode( cContent, @::hData ) IF ::hData == NIL ::hData := { => } ENDIF ENDIF ENDIF RETURN NIL METHOD Write() CLASS MH_Sessions LOCAL cFile IF ::lDestroy cFile := ::SessionFile() IF hb_FileExists( cFile ) FErase( cFile ) ENDIF RETURN NIL ENDIF cFile := ::SessionFile() hb_MemoWrit( cFile, hb_jsonEncode( ::hData ) ) RETURN NIL METHOD Data( cKey, uValue ) CLASS MH_Sessions IF cKey == NIL RETURN ::hData ENDIF IF uValue != NIL ::hData[ cKey ] := uValue RETURN uValue ENDIF IF hb_HHasKey( ::hData, cKey ) RETURN ::hData[ cKey ] ENDIF RETURN NIL METHOD End() CLASS MH_Sessions ::lDestroy := .T. ::Write() fn_SetCookie( ::cName, "", 0, "/" ) RETURN NIL METHOD Garbage( dMaxDate ) CLASS MH_Sessions LOCAL aFiles, cFile hb_default( @dMaxDate, Date() - 1 ) aFiles := Directory( ::cSessionPath + "/*.session" ) FOR EACH cFile IN aFiles IF cFile[ 3 ] < dMaxDate FErase( ::cSessionPath + "/" + cFile[ 1 ] ) ENDIF NEXT RETURN NIL METHOD IsFile() CLASS MH_Sessions RETURN hb_FileExists( ::SessionFile() ) METHOD Info() CLASS MH_Sessions RETURN { ; "id" => ::cId, ; "name" => ::cName, ; "expired" => ::nExpired, ; "path" => ::cSessionPath, ; "file" => ::SessionFile(), ; "data" => ::hData, ; "destroy" => ::lDestroy ; } // -- mod_harbour compatibility wrappers -- FUNCTION mh_SessionInit( cName, nExpired ) RETURN fn_SessionInit( cName, nExpired ) FUNCTION mh_Session( cKey, uValue ) RETURN fn_Session( cKey, uValue ) FUNCTION mh_SessionWrite() RETURN fn_SessionWrite() FUNCTION mh_SessionEnd() RETURN fn_SessionEnd() FUNCTION mh_SessionActive() RETURN fn_SessionActive() FUNCTION mh_oSession( o ) RETURN fn_oSession( o ) FUNCTION mh_Garbage() RETURN fn_Garbage()