/** * This tool renders all user sessions opened. * * @param {array} $options An associative array of parameters, containing: * @param {string} [$options.userId] * The user's id. Defaults to id of the logged-in user, if any. * @param {bool} [$options.editable=true] * Whether user can delete sessions * @param {bool} [$options.devices=true] * Whether to show devices info */ function Users_sessions_tool($options) { $options = array_merge(array('editable' => true, 'devices' => true), $options); if (empty($options['userId'])) { $options['userId'] = Users::loggedInUser(true)->id; } Q_Response::addStylesheet('plugins/Users/css/tools/sessions.css'); Q_Response::setToolOptions($options); $sessions = Users_Session::select("us.*, ud.deviceId, ud.platform, ud.version, ud.formFactor", "us")->join(Users_Device::table() . ' ud', array('us.userId' => 'ud.userId', 'us.id' => 'ud.sessionId'), "LEFT")->where(array('us.userId' => $options['userId']))->fetchDbRows(); $noDevicesClass = $options['devices'] ? '' : "Users_sessions_noDevices"; $html = "<table class='Users_sessions_container {$noDevicesClass}'><tr><th>Session Id</th><th class='Users_sessions_devicesData'>Platform</th><th class='Users_sessions_devicesData'>Version</th><th>Last Updated</th>"; if ($options["editable"]) { $html .= '<th class="Users_sessions_actions"></th>'; } $html .= '</tr>'; foreach ($sessions as $session) { $updatedTime = date("M j, Y g:i A", strtotime($session->updatedTime)); $html .= "<tr><td class='Users_sessions_sessionId'>{$session->id}</td>" . "<td class='Users_sessions_devicesData'>{$session->platform}</td>" . "<td class='Users_sessions_devicesData'>{$session->version}</td>" . "<td>{$updatedTime}</td>"; if ($options["editable"]) { $html .= "<td class='Users_sessions_actions'><button name='delete'>Delete</button></td>"; } $html .= '</tr>'; } $html .= "</table>"; return $html; }
function Users_0_9_2_Users_mysql() { $app = Q_Config::expect('Q', 'app'); $communityId = Users::communityId(); $rows = Users_Session::select('COUNT(1)')->where($criteria)->fetchAll(PDO::FETCH_NUM); $count = $rows[0][0]; $limit = 100; $offset = 0; $sessions = Users_Session::select('*')->orderBy('id')->limit($limit, $offset)->caching(false)->fetchDbRows(); echo "Adding userId to sessions..."; while ($sessions) { foreach ($sessions as $s) { $parsed = Q::json_decode($s->content, true); if (empty($parsed['Users']['loggedInUser']['id'])) { continue; } $s->userId = $parsed['Users']['loggedInUser']['id']; } Users_Session::insertManyAndExecute($sessions, array('onDuplicateKeyUpdate' => array('userId' => new Db_Expression("VALUES(userId)")))); $min = min($offset + $limit, $count); echo "[100D"; echo "Updated {$min} of {$count} sessions"; $offset += $limit; if ($offset > $count) { break; } $sessions = Users_Session::select('*')->orderBy('id')->limit($limit, $offset)->caching(false)->fetchDbRows(); } echo "\n"; }
/** * Adds a device to the system, after sending a test notification to it * @param {array} $device * @param {string} $device.userId * @param {string} $device.deviceId * @param {string} [$device.formFactor] * @param {string} [$device.platform] * @param {string} [$device.version] * @param {string} [$device.sessionId] * @param {boolean} [$device.sandbox] * @param {string} [$device.passphrase] * @param {boolean} [$skipNotification=false] if true, skips sending notification * @return {Users_Device} */ static function add($device, $skipNotification = false) { Q_Valid::requireFields(array('userId', 'deviceId'), $device, true); $userId = $device['userId']; $deviceId = $device['deviceId']; if (!$skipNotification) { $app = Q::app(); $sandbox = Q::ifset($device, 'sandbox', null); if (!isset($sandbox)) { $sandbox = Q_Config::get($app, "cordova", "ios", "sandbox", false); } $env = $sandbox ? ApnsPHP_Abstract::ENVIRONMENT_SANDBOX : ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION; $s = $sandbox ? 'sandbox' : 'production'; $cert = APP_LOCAL_DIR . DS . 'Users' . DS . 'certs' . DS . $app . DS . $s . DS . 'bundle.pem'; $authority = USERS_PLUGIN_FILES_DIR . DS . 'Users' . DS . 'certs' . DS . 'EntrustRootCA.pem'; $logger = new Users_ApnsPHP_Logger(); $push = new ApnsPHP_Push($env, $cert); $push->setLogger($logger); $push->setRootCertificationAuthority($authority); if (isset($device['passphrase'])) { $push->setProviderCertificatePassphrase($device['passphrase']); } $push->connect(); $message = new ApnsPHP_Message($deviceId); $message->setCustomIdentifier('Users_Device-adding'); $message->setBadge(0); $message->setText(Q_Config::get($app, "cordova", "ios", "device", "text", "Notifications have been enabled")); $message->setCustomProperty('userId', $userId); $message->setExpiry(5); $push->add($message); $push->send(); $push->disconnect(); $errors = $push->getErrors(); if (!empty($errors)) { $result = reset($errors); throw new Users_Exception_DeviceNotification($result['ERRORS'][0]); } } $sessionId = Q_Session::id(); $user = Users::loggedInUser(); $info = array_merge(Q_Request::userAgentInfo(), array('sessionId' => $sessionId, 'userId' => $user ? $user->id : null, 'deviceId' => null)); $device2 = Q::take($device, $info); $d = new Users_Device($device2); $d->save(true); if ($sessionId) { $s = new Users_Session(); $s->id = $sessionId; if (!$s->retrieve()) { $s->deviceId = $deviceId; } } $_SESSION['Users']['deviceId'] = $deviceId; $device2['Q/method'] = 'Users/device'; Q_Utils::sendToNode($device2); return $d; }
function Users_sessions_delete() { if (empty($_REQUEST["sessionId"])) { throw new Q_Exceptions_RequiredField(array('field' => 'sessionId')); } $session = new Users_Session(); $session->id = $_REQUEST['sessionId']; $session->retrieve(true); $content = Q::json_decode($session->content); $userId = Q::ifset($content, 'Users', 'loggedInUser', 'id', null); $loggedInUserId = Users::loggedInUser(true)->id; if ($userId == $loggedInUserId) { $authorized = true; } else { $app = Q::app(); $roles = Users::roles(); $authorized = !empty($roles["{$app}/admins"]); } if (!$authorized) { throw new Users_Exception_NotAuthorized(); } $session->remove(); Q_Response::setSlot('success', true); }
/** * Saves a new Users_Session row with a copy of all the content from the current session. * @param {string|integer} $duration The key in the Q / session / durations config field or number of seconds * @return {string} the id of the new session */ static function copyToNewSession($duration = 'year') { $id = Q_Session::id(); if (!$id) { return null; } $seconds = is_string($duration) ? Q_Config::expect('Q', 'session', 'durations', $duration) : $duration; session_write_close(); // close current session $us = new Users_Session(); $us->id = $id; $us->retrieve(null, null, array('lock' => 'FOR UPDATE')); $us2 = new Users_Session(); if ($us->wasRetrieved()) { $us2->copyFromRow($us, null, false, true); $us2->wasRetrieved(false); } else { $us2->content = "{}"; $us2->php = ""; $us2->deviceId = ""; $us2->timeout = 0; } $us2->id = Q_Session::generateId(); $us2->duration = $seconds; $us2->save(false, true); $new_id = $us2->id; session_start(); // reopen current session Q::event("Users/copyToNewSession", array('duration' => $duration, 'from_sessionId' => $id, 'to_sessionId' => $us2->id), 'after'); return $us2->id; }