1919 * --------------------------------------------------------------------
2020 * ZnetDK 4 Mobile User sessions module Controller class
2121 *
22- * File version: 1.0
23- * Last update: 04/25 /2025
22+ * File version: 1.1
23+ * Last update: 06/10 /2025
2424 */
2525
2626namespace z4m_usersessions \mod \controller ;
2727
28- use \z4m_usersessions \mod \Z4MUserSessionFile ;
28+ use \z4m_usersessions \mod \UserSessionManager ;
2929
3030class Z4MUserSessionsCtrl extends \AppController {
3131
@@ -66,7 +66,7 @@ static protected function action_all() {
6666 $ rowCount = $ request ->count ;
6767 $ response = new \Response ();
6868 $ rows = [];
69- $ isSessionSavePathReadable = self ::getSessionDataFromFiles ($ rows );
69+ $ isSessionSavePathReadable = UserSessionManager ::getSessionDataFromFiles ($ rows );
7070 if (!$ isSessionSavePathReadable ) {
7171 $ sessionSavePath = session_save_path ();
7272 $ rows [0 ]['summary ' ] = MOD_Z4M_USERSESSIONS_SETTINGS_PHP_ROW ;
@@ -86,11 +86,9 @@ static protected function action_all() {
8686 static protected function action_clean () {
8787 $ method = \Request::getMethod ();
8888 $ response = new \Response ($ method !== 'GET ' );
89- $ count = session_gc ();
90- $ message = \General::getFilledMessage (MOD_Z4M_USERSESSIONS_ACTION_CLEAN_SUCCESS , $ count );
89+ $ message = UserSessionManager::clean ($ method === 'GET ' );
9190 if ($ method === 'GET ' ) {
92- session_destroy ();
93- $ response ->setCustomContent ($ message );
91+ $ response ->setCustomContent ($ message . PHP_EOL );
9492 } else {
9593 $ response ->setSuccessMessage (NULL , $ message );
9694 }
@@ -109,7 +107,7 @@ static protected function action_kill() {
109107 return $ response ;
110108 }
111109 try {
112- $ count = self ::killUserSessions ($ request ->login_name , $ request ->application_key , FALSE );
110+ $ count = UserSessionManager ::killUserSessions ($ request ->login_name , $ request ->application_key , FALSE );
113111 $ response ->setSuccessMessage (NULL , \General::getFilledMessage (MOD_Z4M_USERSESSIONS_ACTION_KILL_SUCCESS , $ count ));
114112 } catch (\Exception $ ex ) {
115113 \General::writeErrorLog (__METHOD__ , $ ex ->getMessage ());
@@ -127,119 +125,18 @@ static protected function action_kill() {
127125 static protected function action_killall () {
128126 $ request = new \Request ();
129127 $ response = new \Response ();
130- if ($ request ::getMethod ()=== 'GET ' ) {
131- // Call by web service: session data are saved before killing sessions
132- session_write_close ();
133- }
134128 try {
135- $ count = self :: killUserSessions ( NULL , NULL , $ request ->preserve_current_session );
136- $ message = \General:: getFilledMessage ( MOD_Z4M_USERSESSIONS_ACTION_KILL_SUCCESS , $ count );
129+ $ message = UserSessionManager:: killAll ( $ request ->preserve_current_session ,
130+ $ request :: getMethod ()=== ' GET ' , $ request :: getMethod ()=== ' GET ' );
137131 if ($ request ::getMethod ()=== 'GET ' ) {
138- $ response ->setCustomContent ($ message );
132+ $ response ->setCustomContent ($ message . PHP_EOL );
139133 } else {
140134 $ response ->setSuccessMessage (NULL , $ message );
141135 }
142136 } catch (\Exception $ ex ) {
143- \General::writeErrorLog (__METHOD__ , $ ex ->getMessage ());
144- if ($ request ::getMethod ()=== 'GET ' ) {
145- $ response ->setCustomContent (MOD_Z4M_USERSESSIONS_ACTION_KILL_FAILED );
146- } else {
147- $ response ->setFailedMessage (NULL , MOD_Z4M_USERSESSIONS_ACTION_KILL_FAILED );
148- }
137+ $ response ->setFailedMessage (NULL , $ ex ->getMessage ());
149138 }
150139 return $ response ;
151140 }
152141
153- /**
154- * Returns the PHP session files.
155- * @return array The absolute file path of the session files found in the
156- * the directory set to the PHP session.save_path parameter.
157- */
158- static protected function getSessionFiles () {
159- $ sessionSavePath = session_save_path ();
160- return glob ($ sessionSavePath . DIRECTORY_SEPARATOR . 'sess_* ' );
161- }
162-
163- /**
164- * Returns the file path of the current user's session
165- * @return string Session file path
166- */
167- static protected function getCurrentSessionFile () {
168- $ currentSessionFile = new Z4MUserSessionFile ();
169- return $ currentSessionFile ->getFilePath ();
170- }
171-
172- /**
173- * Extracts session data from session files and convert them to datatable
174- * rows for display.
175- * @param array $allSessionsData the datatable rows matching the session
176- * data found.
177- * @param string|NULL $loginName Optionally, the login name that the session
178- * files should match.
179- * @param string|NULL $applicationKey Optionally, the application key that
180- * the session files should match.
181- * @param boolean $withFilePath If TRUE, the session file path is added to
182- * the returned rows.
183- * @return bool Value TRUE if session files can be read within the directory
184- * where session files are stored. FALSE otherwise.
185- */
186- static protected function getSessionDataFromFiles (array &$ allSessionsData , $ loginName = NULL , $ applicationKey = NULL , $ withFilePath = FALSE ) {
187- $ sessionFiles = self ::getSessionFiles ();
188- $ isSessionSavePathReadable = TRUE ;
189- if (count ($ sessionFiles ) === 0 ) {
190- $ sessionFiles = [self ::getCurrentSessionFile ()];
191- $ isSessionSavePathReadable = FALSE ;
192- }
193- foreach ($ sessionFiles as $ filepath ) {
194- $ sessionFile = new Z4MUserSessionFile ($ filepath , $ loginName , $ applicationKey );
195- $ rows = $ sessionFile ->convertSessionDataToDatalistRows ($ withFilePath );
196- if (count ($ rows ) > 0 ) {
197- $ allSessionsData = array_merge ($ allSessionsData , $ rows );
198- }
199- }
200- self ::sortByModificationTime ($ allSessionsData );
201- return $ isSessionSavePathReadable ;
202- }
203-
204- /**
205- * Sorts the specified rows by session file modification time in reverse
206- * order.
207- * @param array $rows The rows to sort.
208- */
209- static protected function sortByModificationTime (&$ rows ) {
210- usort ($ rows , function ($ a , $ b ){
211- return $ b ['session_timestamp ' ] - $ a ['session_timestamp ' ];
212- });
213- }
214-
215- /**
216- * Kills user sessions.
217- * @param string $loginName Optional, the login name that session file
218- * should match to be removed.
219- * @param string $applicationKey Optional, the application key that session
220- * file should match to be removed.
221- * @param boolean $preserveCurrentSession When TRUE, the current user
222- * session is preserved and not killed.
223- * @return int Number of session files removed.
224- * @throws \Exception No session file to remove for the specified login name
225- * and application key.
226- */
227- static protected function killUserSessions ($ loginName = NULL , $ applicationKey = NULL , $ preserveCurrentSession = TRUE ) {
228- $ rows = [];
229- self ::getSessionDataFromFiles ($ rows , $ loginName , $ applicationKey , TRUE );
230- if (count ($ rows ) === 0 && !is_null ($ loginName ) && !is_null ($ applicationKey )) {
231- throw new \Exception ("No session to kill for user 'login_name= {$ loginName }' and 'application_key= {$ applicationKey }'. " );
232- }
233- $ count = 0 ;
234- foreach ($ rows as $ row ) {
235- $ sessionFile = new Z4MUserSessionFile ($ row ['file_path ' ]);
236- if ($ preserveCurrentSession && $ sessionFile ->doesMatchCurrentUserSession ()) {
237- continue ;
238- }
239- $ sessionFile ->remove ();
240- $ count ++;
241- }
242- return $ count ;
243- }
244-
245142}
0 commit comments