1: <?php
  2: 
  3: /**
  4:  * This file contains the online user collection and item class.
  5:  *
  6:  * @package Core
  7:  * @subpackage GenericDB_Model
  8:  * @author Murat Purc <murat@purc.de>
  9:  * @copyright four for business AG <www.4fb.de>
 10:  * @license http://www.contenido.org/license/LIZENZ.txt
 11:  * @link http://www.4fb.de
 12:  * @link http://www.contenido.org
 13:  */
 14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17: /**
 18:  * Online user collection
 19:  *
 20:  * @package Core
 21:  * @subpackage GenericDB_Model
 22:  */
 23: class cApiOnlineUserCollection extends ItemCollection {
 24:     /**
 25:      * Constructor to create an instance of this class.
 26:      *
 27:      * @param bool $select [optional]
 28:      *                     where clause to use for selection (see ItemCollection::select())
 29:      *
 30:      * @throws cDbException
 31:      * @throws cInvalidArgumentException
 32:      */
 33:     public function __construct($select = false) {
 34:         global $cfg;
 35:         parent::__construct($cfg['tab']['online_user'], 'user_id');
 36:         $this->_setItemClass('cApiOnlineUser');
 37:         if ($select !== false) {
 38:             $this->select($select);
 39:         }
 40:     }
 41: 
 42:     /**
 43:      * Start the User Tracking:
 44:      * 1) First delete all inactive users with timelimit is off
 45:      * 2) If find user in the table, do update
 46:      * 3) Else there is no current user do insert new user
 47:      *
 48:      * @param string $userId [optional]
 49:      *                       Id of user
 50:      *
 51:      * @throws cDbException
 52:      * @throws cException
 53:      * @throws cInvalidArgumentException
 54:      */
 55:     public function startUsersTracking($userId = NULL) {
 56:         global $auth;
 57: 
 58:         $userId = (string) $userId;
 59:         if (empty($userId)) {
 60:             $userId = $auth->auth['uid'];
 61:         }
 62: 
 63:         // Delete all entries being older than defined timeout
 64:         $this->deleteInactiveUser();
 65: 
 66:         $bResult = $this->findUser($userId);
 67:         if ($bResult) {
 68:             // Update the curent user
 69:             $this->updateUser($userId);
 70:         } else {
 71:             // User not found, we can insert the new user
 72:             $this->insertOnlineUser($userId);
 73:         }
 74:     }
 75: 
 76:     /**
 77:      * Insert this user in online_user table
 78:      *
 79:      * @param string $userId
 80:      *         Id of user
 81:      *
 82:      * @return bool
 83:      *         Returns true if successful else false
 84:      * @throws cDbException
 85:      * @throws cException
 86:      * @throws cInvalidArgumentException
 87:      */
 88:     public function insertOnlineUser($userId) {
 89:         $oItem = $this->createNewItem((string) $userId);
 90:         if ($oItem) {
 91:             $created = date('Y-m-d H:i:s');
 92:             $oItem->set('lastaccessed', $created);
 93:             $oItem->store();
 94:         }
 95:         return ($oItem) ? true : false;
 96:     }
 97: 
 98:     /**
 99:      * Find the this user if exists in the table 'online_user'
100:      *
101:      * @param string $userId
102:      *         Is the User-Id (get from auth object)
103:      * @return bool
104:      *         Returns true if this User is found, else false
105:      */
106:     public function findUser($userId) {
107:         $oUser = new cApiOnlineUser((string) $userId);
108:         return $oUser->isLoaded();
109:     }
110: 
111:     /**
112:      * Find all user_ids in the table 'online_user' for get rest information
113:      * from table 'con_user'
114:      *
115:      * @return array
116:      *         Returns array of user-information
117:      * @throws cDbException
118:      * @throws cException
119:      */
120:     public function findAllUser() {
121:         // todo use $perm
122:         $aAllUser = array();
123:         $aUser = array();
124:         $sClientName = '';
125: 
126:         // get all user_ids
127:         $this->select();
128:         while (($oItem = $this->next()) !== false) {
129:             $aUser[] = $oItem->get('user_id');
130:         }
131: 
132:         $oClientColl = new cApiClientCollection();
133: 
134:         // get data of those users
135:         $where = "user_id IN ('" . implode("', '", $aUser) . "')";
136:         $oUserColl = new cApiUserCollection();
137:         $oUserColl->select($where);
138:         while (($oItem = $oUserColl->next()) !== false) {
139:             $sClientNames = '';
140:             $userId = $oItem->get('user_id');
141:             $aAllUser[$userId]['realname'] = $oItem->get('realname');
142:             $aAllUser[$userId]['username'] = $oItem->get('username');
143:             $aPerms = explode(',', $oItem->get('perms'));
144: 
145:             if (in_array('sysadmin', $aPerms)) {
146:                 $aAllUser[$userId]['perms'] = 'Systemadministrator';
147:             } else {
148:                 $bIsAdmin = false;
149:                 $iCounter = 0;
150:                 foreach ($aPerms as $sPerm) {
151:                     $aResults = array();
152:                     if (preg_match('/^admin\[(\d+)\]$/', $sPerm, $aResults)) {
153:                         $iClientId = $aResults[1];
154:                         $bIsAdmin = true;
155:                         $sClientName = $oClientColl->getClientname((int) $iClientId);
156:                         if ($iCounter == 0 && $sClientName != '') {
157:                             $sClientNames .= $sClientName;
158:                         } elseif ($sClientName != '') {
159:                             $sClientNames .= ', ' . $sClientName;
160:                         }
161: 
162:                         $aAllUser[$userId]['perms'] = 'Administrator (' . $sClientNames . ')';
163:                         $iCounter++;
164:                     } elseif (preg_match('/^client\[(\d+)\]$/', $sPerm, $aResults) && !$bIsAdmin) {
165:                         $iClientId = $aResults[1];
166:                         $sClientName = $oClientColl->getClientname((int) $iClientId);
167:                         if ($iCounter == 0 && $sClientName != '') {
168:                             $sClientNames .= $sClientName;
169:                         } elseif ($sClientName != '') {
170:                             $sClientNames .= ', ' . $sClientName;
171:                         }
172: 
173:                         $aAllUser[$userId]['perms'] = '(' . $sClientNames . ')';
174:                         $iCounter++;
175:                     }
176:                 }
177:             }
178:         }
179: 
180:         return $aAllUser;
181:     }
182: 
183:     /**
184:      * This function do an update of current timestamp in 'online_user'
185:      *
186:      * @param string $userId
187:      *         Is the User-Id (get from auth object)
188:      * @return bool
189:      *         Returns true if successful, else false
190:      * @throws cDbException
191:      * @throws cInvalidArgumentException
192:      */
193:     public function updateUser($userId) {
194:         $oUser = new cApiOnlineUser((string) $userId);
195:         if ($oUser->isLoaded()) {
196:             $now = date('Y-m-d H:i:s');
197:             $oUser->set('lastaccessed', $now);
198:             return $oUser->store();
199:         }
200:         return false;
201:     }
202: 
203:     /**
204:      * Delete all Contains in the table 'online_user' that is older as
205:      * Backend timeout(currently is $cfg['backend']['timeout'] = 60)
206:      *
207:      * @return bool
208:      *         Returns true if successful else false
209:      * @throws cDbException
210:      * @throws cInvalidArgumentException
211:      */
212:     public function deleteInactiveUser() {
213:         global $cfg;
214:         include_once($cfg['path']['contenido_config'] . 'config.misc.php');
215:         $iSetTimeOut = (int) $cfg['backend']['timeout'];
216:         if ($iSetTimeOut <= 0) {
217:             $iSetTimeOut = 10;
218:         }
219: 
220:         // NOTE: We could delete outdated entries with one query, but deleteing
221:         // one by one
222:         // gives us the possibility to hook (CEC) into each deleted entry.
223:         $where = "DATE_SUB(NOW(), INTERVAL '$iSetTimeOut' Minute) >= `lastaccessed`";
224:         $result = $this->deleteByWhereClause($where);
225:         return ($result > 0) ? true : false;
226:     }
227: 
228:     /**
229:      * Get the number of users from the table 'online_user'
230:      *
231:      * @return int
232:      *         Returns if exists a number of users
233:      * @throws cDbException
234:      */
235:     public function getNumberOfUsers() {
236:         $sql = 'SELECT COUNT(*) AS cnt FROM `%s`';
237:         $result = $this->db->query($sql, $this->table);
238:         $this->_lastSQL = $sql;
239:         if ($result) {
240:             $this->db->nextRecord();
241:             return (int) $this->db->f('cnt');
242:         }
243:         return 0;
244:     }
245: 
246:     /**
247:      * Delete this user from 'online user' table
248:      *
249:      * @param string $userId
250:      *         Is the User-Id (get from auth object)
251:      * @return bool
252:      *         Returns true if successful, else false
253:      * 
254:      * @throws cDbException
255:      * @throws cInvalidArgumentException
256:      */
257:     public function deleteUser($userId) {
258:         return $this->delete((string) $userId);
259:     }
260: }
261: 
262: /**
263:  * Online user item
264:  *
265:  * @package Core
266:  * @subpackage GenericDB_Model
267:  */
268: class cApiOnlineUser extends Item
269: {
270:     /**
271:      * Constructor to create an instance of this class.
272:      *
273:      * @param mixed $mId [optional]
274:      *                   Specifies the ID of item to load
275:      *                   
276:      * @throws cDbException
277:      * @throws cException
278:      */
279:     public function __construct($mId = false) {
280:         global $cfg;
281:         parent::__construct($cfg['tab']['online_user'], 'user_id');
282:         $this->setFilters(array(), array());
283:         if ($mId !== false) {
284:             $this->loadByPrimaryKey($mId);
285:         }
286:     }
287: }
288: