/** * Displays an HTML document that can be printed, ideally with line breaks. * Uses a particular view for the layout. * @param {array} $_REQUEST * @param {string} $_REQUEST.invitingUserId Required. The id of the user that generated the invitations with a call to Streams::invite. * @param {string} $_REQUEST.batch Required. The name of the batch under which invitations were saved during a call to Streams::invite. * @param {string} [$_REQUEST.limit=100] The maximum number of invitations to show on the page * @param {string} [$_REQUEST.offset=0] Used for paging * @param {string} [$_REQUEST.title='Invitations'] Override the title of the document * @param {string} [$_REQUEST.layout='default'] The name of the layout to use for the HTML document * @see Users::addLink() */ function Streams_invitations_response() { Q_Request::requireFields(array('batch', 'invitingUserId'), true); $invitingUserId = $_REQUEST['invitingUserId']; $batch = $_REQUEST['batch']; $title = Q::ifset($_REQUEST, 'layout', 'title'); $layoutKey = Q::ifset($_REQUEST, 'layout', 'default'); $limit = min(1000, Q::ifset($_REQUEST, 'limit', 100)); $offset = Q::ifset($_REQUEST, 'offset', 0); $layout = Q_Config::expect('Streams', 'invites', 'layout', $layoutKey); $app = Q_Config::expect('Q', 'app'); $pattern = Streams::invitationsPath($invitingUserId) . DS . $batch . DS . "*.html"; $filenames = glob($pattern); $parts = array(); foreach ($filenames as $f) { if (--$offset > 0) { continue; } $parts[] = file_get_contents($f); if (--$limit == 0) { break; } } $content = implode("\n\n<div class='Q_pagebreak Streams_invitations_separator'></div>\n\n", $parts); echo Q::view($layout, compact('content', 'parts')); return false; }
/** * Edits a label in the system. Fills the "label" (and possibly "icon") slot. * @param {array} $_REQUEST * @param {string} $_REQUEST.label The label * @param {string} [$_REQUEST.title] The title of the label * @param {string} [$_REQUEST.icon] Optional path to an icon * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_label_put($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('label'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $l = $req['label']; $icon = Q::ifset($req, 'icon', null); $title = Q::ifset($req, 'title', null); Users::canManageLabels($loggedInUserId, $userId, $l, true); $label = new Users_Label(); $label->userId = $userId; $label->label = $l; if (!$label->retrieve()) { throw new Q_Exception_MissingRow(array('table' => 'Label', 'criteria' => json_encode($label->fields))); } if (isset($title)) { $label->title = $title; } if (is_array($icon)) { // Process any icon data $icon['path'] = 'uploads/Users'; $icon['subpath'] = "{$userId}/label/{$label}/icon"; $data = Q::event("Q/image/post", $icon); Q_Response::setSlot('icon', $data); $label->icon = Q_Request::baseUrl() . '/' . $data['']; } $label->save(); Q_Response::setSlot('label', $label->exportArray()); }
function Q_post($params) { $uri = Q_Dispatcher::uri(); $module = $uri->module; $action = $uri->action; if (!Q::canHandle("{$module}/{$action}/post")) { throw new Q_Exception_MethodNotSupported(array('method' => 'POST')); } if (isset($_SERVER['CONTENT_LENGTH'])) { $contentLength = (int) $_SERVER['CONTENT_LENGTH']; foreach (array('upload_max_filesize', 'post_max_size') as $name) { $value = ini_get($name); switch (substr($value, -1)) { case 'K': $value *= 1024; break; case 'M': $value *= 1024 * 1024; break; case 'B': $value *= 1024 * 1024 * 1024; break; } if ($contentLength > $value) { throw new Q_Exception_ContentLength(array('contentLength' => $contentLength, 'exceeds' => $name)); } } } Q_Request::requireValidNonce(); return Q::event("{$module}/{$action}/post", $params); }
function Users_user_response_data($params) { // Get Gravatar info // WARNING: INTERNET_REQUEST $hash = md5(strtolower(trim($identifier))); $thumbnailUrl = Q_Request::baseUrl() . "/action.php/Users/thumbnail?hash={$hash}&size=80&type=" . Q_Config::get('Users', 'login', 'iconType', 'wavatar'); $json = @file_get_contents("http://www.gravatar.com/{$hash}.json"); $result = json_decode($json, true); if ($result) { if ($type === 'email') { $result['emailExists'] = !empty($exists); } else { if ($type === 'mobile') { $result['mobileExists'] = !empty($exists); } } return $result; } // otherwise, return default $email_parts = explode('@', $identifier, 2); $result = array("entry" => array(array("id" => "571", "hash" => "357a20e8c56e69d6f9734d23ef9517e8", "requestHash" => "357a20e8c56e69d6f9734d23ef9517e8", "profileUrl" => "http://gravatar.com/test", "preferredUsername" => ucfirst($email_parts[0]), "thumbnailUrl" => $thumbnailUrl, "photos" => array(), "displayName" => "", "urls" => array()))); if ($type === 'email') { $result['emailExists'] = !empty($exists); } else { $result['mobileExists'] = !empty($exists); } if ($terms_label = Users::termsLabel('register')) { $result['termsLabel'] = $terms_label; } return $result; }
/** * Adds a label to the system. Fills the "label" (and possibly "icon") slot. * @param {array} $_REQUEST * @param {string} $_REQUEST.title The title of the label * @param {string} [$_REQUEST.label] You can override the label to use * @param {string} [$_REQUEST.icon] Optional path to an icon * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_label_post($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('title'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $icon = Q::ifset($req, 'icon', null); $title = $req['title']; $l = Q::ifset($req, 'label', 'Users/' . Q_Utils::normalize($title)); Users::canManageLabels($loggedInUserId, $userId, $l, true); $label = new Users_Label(); $label->userId = $userId; $label->label = $l; if ($label->retrieve()) { throw new Users_Exception_LabelExists(); } $label->title = $title; if (is_array($icon)) { // Process any icon that was posted $icon['path'] = 'uploads/Users'; $icon['subpath'] = "{$userId}/label/{$label}/icon"; $data = Q::event("Q/image/post", $icon); Q_Response::setSlot('icon', $data); $label->icon = Q_Request::baseUrl() . '/' . $data['']; } else { $label->icon = 'default'; } $label->save(); Q_Response::setSlot('label', $label->exportArray()); }
function Streams_invite_validate() { if (Q_Request::method() === 'PUT') { return; } if (Q_Request::method() !== 'GET') { Q_Valid::nonce(true); } $fields = array('publisherId', 'streamName'); if (Q_Request::method() === 'POST') { if (Q_Valid::requireFields($fields)) { return; } foreach ($fields as $f) { if (strlen(trim($_REQUEST[$f])) === 0) { Q_Response::addError(new Q_Exception("{$f} can't be empty", $f)); } } } if (isset($_REQUEST['fullName'])) { $length_min = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMin', 5); $length_max = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMax', 30); if (strlen($_REQUEST['fullName']) < $length_min) { throw new Q_Exception("A user's full name can't be that short.", 'fullName'); } if (strlen($_REQUEST['fullName']) > $length_max) { throw new Q_Exception("A user's full name can't be that long.", 'fullName'); } } }
function Overlay_before_Q_responseExtras() { $app = Q_Config::expect('Q', 'app'); Q_Response::addStylesheet('plugins/Q/css/Q.css'); Q_Response::addStylesheet('css/Overlay.css', '@end'); Q_Response::addStylesheet('http://fonts.googleapis.com/css?family=Open+Sans:400italic,400,300,700'); if (Q_Config::get('Q', 'firebug', false)) { Q_Response::addScript("https://getfirebug.com/firebug-lite-debug.js"); } Q_Response::addScript('js/Overlay.js'); Q_Response::setMeta("title", "Customize My Pic!"); Q_Response::setMeta("description", "Make a statement on Facebook by customizing your profile picture, even from your smartphone."); Q_Response::setMeta("image", Q_Html::themedUrl('img/icon/icon.png')); if (Q_Request::isIE()) { header("X-UA-Compatible", "IE=edge"); } header('Vary: User-Agent'); // running an event for loading action-specific extras (if there are any) $uri = Q_Dispatcher::uri(); $module = $uri->module; $action = $uri->action; $event = "{$module}/{$action}/response/responseExtras"; if (Q::canHandle($event)) { Q::event($event); } }
/** * Displays an HTML document that can be printed, ideally with line breaks. * Uses a particular view for the layout. * @param {array} $_REQUEST * @param {string} $_REQUEST.invitingUserId Required. The id of the user that generated the invitations with a call to Streams::invite. * @param {string} $_REQUEST.batch Required. The name of the batch under which invitations were saved during a call to Streams::invite. * @param {string} [$_REQUEST.limit=100] The maximum number of invitations to show on the page * @param {string} [$_REQUEST.offset=0] Used for paging * @param {string} [$_REQUEST.title='Invitations'] Override the title of the document * @param {string} [$_REQUEST.layout='default'] The name of the layout to use for the HTML document * @see Users::addLink() */ function Streams_invitations_response() { Q_Request::requireFields(array('batch', 'invitingUserId'), true); $invitingUserId = $_REQUEST['invitingUserId']; $batch = $_REQUEST['batch']; $user = Users::loggedInUser(true); $stream = Streams::fetchOne(null, $invitingUserId, 'Streams/invitations', true); if (!$stream->testReadLevel('content')) { throw new Users_Exception_NotAuthorized(); } $title = Q::ifset($_REQUEST, 'layout', 'title'); $layoutKey = Q::ifset($_REQUEST, 'layout', 'default'); $limit = min(1000, Q::ifset($_REQUEST, 'limit', 100)); $offset = Q::ifset($_REQUEST, 'offset', 0); $layout = Q_Config::expect('Streams', 'invites', 'layout', $layoutKey); $pattern = Streams::invitationsPath($invitingUserId) . DS . $batch . DS . "*.html"; $filenames = glob($pattern); $parts = array(); foreach ($filenames as $f) { if (--$offset > 0) { continue; } $parts[] = file_get_contents($f); if (--$limit == 0) { break; } } $content = implode("\n\n<div class='Q_pagebreak Streams_invitations_separator'></div>\n\n", $parts); echo Q::view($layout, compact('title', 'content', 'parts')); return false; }
function Shipping_scheduled_response_content($params) { // redirect to home page if not logged in if (!Users::loggedInUser()) { header("Location: " . Q_Request::baseUrl()); exit; } // get "Shipping/shipments" stream $publisherId = Users::communityId(); $streamName = 'Shipping/shipment/' . Q_Request::uri()->shipmentStreamName; $stream = Streams::fetchOne($publisherId, $publisherId, $streamName); //$xml = simplexml_load_file(APP_DIR.'/classes/dhl/response.xml'); //$xml = simplexml_load_string(str_replace('req:', '', file_get_contents(APP_DIR.'/classes/dhl/response.xml'))); //print_r($xml); exit; // test pickup //$carrier = new Shipping_Carrier_DHL(); //$carrier->createAWBBarCode($stream, 'iVBORw0KGgoAAAANSUhEUgAAAYwAAABeAQMAAAAKdrGZAAAABlBMVEX///8AAABVwtN+AAAAaklEQVR42mNkYGBIyL8wZcutG2wTzVMZfG99eep7y1tp5oIokaMMOtabG6PuTflrnnHqVfI013vzlRYwMDAxkAxGtYxqGdUyqmVUy6iWUS2jWka1jGoZ1TKqZVTLqJZRLaNaRrWMaiEVAABqDRe8DYfcJgAAAABJRU5ErkJggg==', "AWBBarCode"); // ----------- //echo Shipping::getShipmentRelation($stream, true); //unlink("/tmp/dhl-api-autoload.php"); if (!$stream || !$stream->testReadLevel('see')) { throw new Users_Exception_NotAuthorized(); } return Q::view('Shipping/content/scheduled.php', compact('streamName')); }
function Streams_after_Q_image_save($params) { $user = Users::loggedInUser(true); $path = $subpath = $data = $save = null; extract($params, EXTR_OVERWRITE); if (isset(Users::$cache['iconUrlWasChanged']) and Users::$cache['iconUrlWasChanged'] === false) { // the logged-in user's icon was changed without the url changing $stream = Streams::fetchOne($user->id, $user->id, "Streams/user/icon"); } else { if (!empty(Streams::$cache['canWriteToStream'])) { // some stream's icon was being changed $stream = Streams::$cache['canWriteToStream']; } } if (empty($stream)) { return; } $url = $data['']; $stream->icon = Q_Valid::url($url) ? $url : Q_Request::baseUrl() . '/' . $url; $sizes = array(); foreach ($save as $k => $v) { $sizes[] = "{$k}"; } sort($sizes); $stream->setAttribute('sizes', $sizes); if (empty(Streams::$beingSavedQuery)) { $stream->changed($user->id); } else { $stream->save(); } }
function Streams_before_Q_responseExtras() { Q_Response::addScript('plugins/Streams/js/Streams.js'); $host = Q_Config::get('Streams', 'node', 'host', Q_Config::get('Q', 'node', 'host', null)); $port = Q_Config::get('Streams', 'node', 'port', Q_Config::get('Q', 'node', 'port', null)); $user = Users::loggedInUser(); if ($user) { Q_Response::setScriptData('Q.plugins.Users.loggedInUser.displayName', Streams::displayName($user)); } if (!Q_Request::isAjax()) { $invite_url = Q_Config::get('Streams', 'invite', 'url', "http://invites.to"); Q_Response::setScriptData('Q.plugins.Streams.invite.url', $invite_url); if (isset($host) && isset($port)) { Q_Response::setScriptData('Q.plugins.Streams.node', array("http://{$host}:{$port}")); } if ($sizes = Q_Config::expect('Streams', 'types', 'Streams/image', 'sizes')) { sort($sizes); Q_Response::setScriptData('Q.plugins.Streams.image.sizes', $sizes); } $defaults = array('readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['join'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']); Q_Response::setScriptData('Q.plugins.Streams.defaults', $defaults); if ($froalaKey = Q_Config::get('Streams', 'froala', 'key', null)) { Q_Response::setScriptData('Q.plugins.Streams.froala.key', $froalaKey); } } Q_Response::addStylesheet("plugins/Streams/css/Streams.css"); }
/** * Default Q/dir handler. * Just displays a simple directory listing, * and prevents further processing by returning true. */ function Q_dir() { $filename = Q_Request::filename(); // TODO: show directory listing echo Q::view('Q/dir.php', compact('filename')); return true; }
function Shipping_shipment_response_content($params) { $user = Users::loggedInUser(true); // copy from shipment $useTemplate = Q_Request::uri()->template ? "Shipping/shipment/" . Q_Request::uri()->template : false; // Check if stream "Shipping/shipments" exists for current user. If no -> create one. Shipping::shipments(); // Check if stream "Shipping/templates" exists for current user. If no -> create one. Shipping::createTemplatesStream(); // Collect streams for shipments. Relations: "describing", "scheduled", "confirmed", "shipping", "canceled", "returned" $shipment = Shipping::shipment(); //$shipment->addPreloaded($userId); // test for UPS pickup //$stream = Streams::fetchOne("Shipping", "Shipping", "Shipping/shipment/Qdqpcspny"); //$carrier = new Shipping_Carrier_UPS(); //$carrier->pickupCreate($stream); //------------------------------- // add main style Q_Response::addStylesheet('css/Shipment.css'); // set communityId Q_Response::setScriptData("Q.info.communityId", Users::communityId()); Q_Response::setScriptData("Q.info.useTemplate", $useTemplate); Q_Response::addScript('js/shipment.js'); Q_Response::addScript('js/date.js'); // add jquery UI //Q_Response::addStylesheet('//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css'); //Q_Response::addScript('//code.jquery.com/ui/1.11.4/jquery-ui.js'); // add pickadate as date picker Q_Response::addStylesheet('js/pickadate/compressed/themes/default.css'); Q_Response::addStylesheet('js/pickadate/compressed/themes/default.date.css'); Q_Response::addScript('js/pickadate/compressed/picker.js'); Q_Response::addScript('js/pickadate/compressed/picker.date.js'); return Q::view('Shipping/content/shipment.php', compact('user', 'shipment', 'useTemplate')); }
function Streams_interest_validate($params) { // Protect against CSRF attacks: if (Q_Request::method() !== 'GET') { Q_Valid::nonce(true); } }
/** * Default Q/notFound handler. * Just displays Q/notFound.php view. */ function Q_notFound($params) { header("HTTP/1.0 404 Not Found"); Q_Dispatcher::result("Nothing found"); $url = Q_Request::url(); echo Q::view('Q/notFound.php', compact('url')); }
function Streams_after_Q_file_save($params) { $user = Users::loggedInUser(true); $path = $subpath = $name = $writePath = $data = $tailUrl = null; extract($params, EXTR_OVERWRITE); if (!empty(Streams::$cache['canWriteToStream'])) { // some stream's associated file was being changed $stream = Streams::$cache['canWriteToStream']; } if (empty($stream)) { return; } $filesize = filesize($writePath . DS . $name); $url = $tailUrl; $url = Q_Valid::url($url) ? $url : Q_Request::baseUrl() . '/' . $url; $prevUrl = $stream->getAttribute('file.url'); $stream->setAttribute('file.url', $url); $stream->setAttribute('file.size', $filesize); // set the title and icon every time a new file is uploaded $stream->title = $name; $parts = explode('.', $name); $urlPrefix = Q_Request::baseUrl() . '/plugins/Streams/img/icons/files'; $dirname = STREAMS_PLUGIN_FILES_DIR . DS . 'Streams' . DS . 'icons' . DS . 'files'; $extension = end($parts); $stream->icon = file_exists($dirname . DS . $extension) ? "{$urlPrefix}/{$extension}" : "{$urlPrefix}/_blank"; if (empty(Streams::$beingSavedQuery)) { $stream->changed($user->id); } else { $stream->save(); } }
function Streams_related_validate() { switch (Q_Request::method()) { case 'POST': $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName'); break; case 'DELETE': $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName'); break; case 'PUT': $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName', 'weight'); if (isset($_REQUEST['adjustWeights'])) { if (!is_numeric($_REQUEST['adjustWeights'])) { Q_Response::addError(new Q_Exception_WrongValue(array('field' => 'adjustWeights', 'range' => 'a numeric value'), 'adjustWeights')); } } break; case 'GET': $required = array(); break; } foreach ($required as $r) { if (!isset($_REQUEST[$r])) { Q_Response::addError(new Q_Exception_RequiredField(array('field' => $r))); } } }
function Q_notice_response_data() { $method = Q_Request::method(); if ($method !== 'DELETE') { throw new Q_Exception_MethodNotSupported($method); } return Q::$cache['notice_deleted']; }
/** * Adds a device to the current user id and session. * See Users_Device::add method for more details. * @param {string} $deviceId * @return {void} */ function Users_device_post() { Q_Request::requireFields(array('deviceId')); $deviceId = $_REQUEST['deviceId']; $user = Users::loggedInUser(true); $device = Users_Device::add(array_merge($_REQUEST, array('userId' => $user->id))); Q_Response::setSlot('data', $device); }
function Users_before_Q_session_save($params) { $row = $params['row']; $row->deviceId = ""; $row->timeout = 0; $row->content = isset($_SESSION) ? Q::json_encode($_SESSION, JSON_FORCE_OBJECT) : "{}"; $row->duration = Q_Config::get('Q', 'session', 'durations', Q_Request::formFactor(), Q_Config::expect('Q', 'session', 'durations', 'session')); }
/** * Renders a user status area which displays logged in status and provides various user-related operations. * @param $options * An associative array of parameters, which can include: * "icon" => Optional. Icon for the login button. Defaults to Qbix icon. * "label" => Optional. Text for the login button. Defaults to 'log in'. * "logoutIcon" => Optional. Icon for 'Log out' item in the tool menu. * "menuItems" => Optional. Additional menu items beside 'Log out' which will be shown in user menu. * Should be an array of hashes like { 'contents': 'value', 'action': 'value' }. * "onCancel" => Optional. Function, string function name or Q.Event. Called when user was unable to login or cancelled login dialog. * "onLogin" => Optional. Function or Q.Event. Called when user successfully logged it. * "onLogout" => Optional. Function, string function name or Q.Event. Called when user successfully logged out. * "onMenuSelect" => Optional. Function, string function name or Q.Event. * Called when user selected some item from user selected some item from user menu except 'Log out'. * @return {string} */ function Users_status_tool($options) { $defaults = array('icon' => 'plugins/Q/img/ui/qbix_icon' . (Q_Request::isMobile() ? '_small' : '') . '.png', 'label' => 'log in', 'logoutIcon' => null, 'menuItems' => array(), 'onCancel' => null, 'onLogin' => null, 'onLogout' => null, 'onMenuSelect' => null); $options = array_merge($defaults, $options); Q_Response::addStylesheet('plugins/Q/css/Q.css'); Q_Response::addStylesheet('plugins/Users/css/Users.css'); Q_Response::setToolOptions($options); return Q::view('Users/tool/status/status.php', $options); }
function MyApp_notFound_response_content($params) { header("HTTP/1.0 404 Not Found"); $url = Q_Request::url(); if (Q_Request::isAjax()) { throw new Q_Exception_NotFound(compact('url')); } return Q::view("MyApp/content/notFound.php", compact('url')); }
/** * 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 Streams_participating_response() { if (!Q_Request::isAjax()) { return; } $max_limit = Q_Config::expect('Streams', 'db', 'limits', 'participating'); $user = Users::loggedInUser(true); $type = Streams::requestedType(); $limit = Streams::requestedField('limit', false, $max_limit); if ($limit > $max_limit) { throw new Q_Exception("limit is too large, must be <= {$max_limit}"); } $offset = Streams::requestedField('offset', false, 0); $order = Streams::requestedField('order', false, true); $participating = array(); $q = Streams_Participating::select('*')->where(array('userId' => $user->id)); if ($type) { $q = $q->where(array('streamName' => new Db_Range($type . '/', true, false, true))); } if ($limit) { $q = $q->limit($limit, $offset); } if ($order) { $q = $q->orderBy('updatedTime', false); } $res_participating = $q->fetchDbRows(); foreach ($res_participating as $part) { $part_safe = $part->exportArray(); if (isset($part_safe)) { $participating[] = $part_safe; } } Q_Response::setSlot('participating', $participating); if (!Q_Request::slotName('streams')) { return; } $res_streams = array(); $streamNames = array(); foreach ($res_participating as $p) { $streamNames[$p->publisherId][] = $p->streamName; } foreach ($streamNames as $p_id => $names) { $res_streams[$p_id] = Streams::fetch($user->id, $p_id, $names); } $streams = array(); $o = array('asUserId' => $user->id); foreach ($res_streams as $publisherId => $streams_array) { if (!empty($streams_array)) { $streams[$publisherId] = array(); foreach ($streams_array as $streamName => $stream) { $streams[$publisherId][$streamName] = $stream->exportArray($o); } } } Q_Response::setSlot('streams', $streams); }
/** * Removes a contact from the system. * @param {array} $_REQUEST * @param {string} $_REQUEST.label The label of the contact * @param {string} $_REQUEST.contactUserId The contactUserId of the contact * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_contact_delete($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('label', 'contactUserId'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $label = $req['label']; $contactUserId = $req['contactUserId']; return !!Users_Contact::removeContact($userId, $label, $contactUserId); }
/** * This tool contains functionality to show things in columns * @class Q columns * @constructor * @param {array} [options] Provide options for this tool * @param {array} [options.animation] For customizing animated transitions * @param {integer} [options.animation.duration] The duration of the transition in milliseconds, defaults to 500 * @param {array} [options.animation.hide] The css properties in "hide" state of animation * @param {array} [options.animation.show] The css properties in "show" state of animation * @param {array} [options.back] For customizing the back button on mobile * @param {string} [options.back.src] The src of the image to use for the back button * @param {boolean} [options.back.triggerFromTitle] Whether the whole title would be a trigger for the back button. Defaults to true. * @param {boolean} [options.back.hide] Whether to hide the back button. Defaults to false, but you can pass true on android, for example. * @param {array} [options.close] For customizing the back button on desktop and tablet * @param {string} [options.close.src] The src of the image to use for the close button * @param {string} [options.title] You can put a default title for all columns here (which is shown as they are loading) * @param {string} [options.column] You can put a default content for all columns here (which is shown as they are loading) * @param {array} [options.clickable] If not null, enables the Q/clickable tool with options from here. Defaults to null. * @param {array} [options.scrollbarsAutoHide] If not null, enables Q/scrollbarsAutoHide functionality with options from here. Enabled by default. * @param {boolean} [options.fullscreen] Whether to use fullscreen mode on mobile phones, using document to scroll instead of relying on possibly buggy "overflow" CSS implementation. Defaults to true on Android, false everywhere else. * @param {array} [options.columns] In PHP only, an array of $name => $column pairs, where $column is in the form array('title' => $html, 'content' => $html, 'close' => true) * @return {string} */ function Q_columns_tool($options) { $jsOptions = array('animation', 'back', 'close', 'title', 'scrollbarsAutoHide', 'fullscreen'); Q_Response::setToolOptions(Q::take($options, $jsOptions)); if (!isset($options['columns'])) { return ''; } Q_Response::addScript('plugins/Q/js/tools/columns.js'); Q_Response::addStylesheet('plugins/Q/css/columns.css'); $result = '<div class="Q_columns_container Q_clearfix">'; $columns = array(); $i = 0; $closeSrc = Q::ifset($options, 'close', 'src', 'plugins/Q/img/x.png'); $backSrc = Q::ifset($options, 'back', 'src', 'plugins/Q/img/back-v.png'); foreach ($options['columns'] as $name => $column) { $close = Q::ifset($column, 'close', $i > 0); $Q_close = Q_Request::isMobile() ? 'Q_close' : 'Q_close Q_back'; $closeHtml = !$close ? '' : (Q_Request::isMobile() ? '<div class="Q_close Q_back">' . Q_Html::img($backSrc, 'Back') . '</div>' : '<div class="Q_close">' . Q_Html::img($closeSrc, 'Close') . '</div>'); $n = Q_Html::text($name); $columnClass = 'Q_column_' . Q_Utils::normalize($name) . ' Q_column_' . $i; if (isset($column['html'])) { $html = $column['html']; $columns[] = <<<EOT \t<div class="Q_columns_column {$columnClass}" data-index="{$i}" data-name="{$n}"> \t\t{$html} \t</div> EOT; } else { $titleHtml = Q::ifset($column, 'title', '[title]'); $columnHtml = Q::ifset($column, 'column', '[column]'); $classes = $columnClass . ' ' . Q::ifset($column, 'class', ''); $attrs = ''; if (isset($column['data'])) { $json = Q::json_encode($column['data']); $attrs = 'data-more="' . Q_Html::text($json) . '"'; foreach ($column['data'] as $k => $v) { $attrs .= 'data-' . Q_Html::text($k) . '="' . Q_Html::text($v) . '" '; } } $data = Q::ifset($column, 'data', ''); $columns[] = <<<EOT \t<div class="Q_columns_column {$classes}" data-index="{$i}" data-name="{$n}" {$attrs}> \t\t<div class="Q_columns_title"> \t\t\t{$closeHtml} \t\t\t<h2 class="Q_title_slot">{$titleHtml}</h2> \t\t</div> \t\t<div class="Q_column_slot">{$columnHtml}</div> \t</div> EOT; } ++$i; } $result .= "\n" . implode("\n", $columns) . "\n</div>"; return $result; }
/** * Adds contacts to the system. Fills the "contacts" slot. * @param {array} $_REQUEST * @param {string} $_REQUEST.label The label of the contact * @param {string} $_REQUEST.contactUserId The contactUserId of the contact * @param {string} [$_REQUEST.nickname] The nickname of the contact * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_contact_post($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('label', 'contactUserId'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $contactUserId = $req['contactUserId']; $nickname = Q::ifset($req, 'nickname', null); $contacts = Users_Contact::addContact($userId, $req['label'], $contactUserId, $nickname); Q_Response::setSlot('contacts', Db::exportArray($contacts)); }
function Q_delete($params) { $uri = Q_Dispatcher::uri(); $module = $uri->module; $action = $uri->action; if (!Q::canHandle("{$module}/{$action}/delete")) { throw new Q_Exception_MethodNotSupported(array('method' => 'DELETE')); } Q_Request::requireValidNonce(); return Q::event("{$module}/{$action}/delete", $params); }
function Users_user_response_data($params) { $identifier = Users::requestedIdentifier($type); // check our db if ($user = Users::userFromContactInfo($type, $identifier)) { $verified = !!Users::identify($type, $identifier); return array('exists' => $user->id, 'verified' => $verified, 'username' => $user->username, 'icon' => $user->icon, 'passphrase_set' => !empty($user->passphraseHash), 'fb_uid' => $user->fb_uid ? $user->fb_uid : null); } if ($type === 'email') { $email = new Users_Email(); Q_Valid::email($identifier, $normalized); $email->address = $normalized; $exists = $email->retrieve(); } else { if ($type === 'mobile') { $mobile = new Users_Mobile(); Q_Valid::phone($identifier, $normalized); $mobile->number = $normalized; $exists = $mobile->retrieve(); } } if (empty($exists) and Q_Config::get('Users', 'login', 'noRegister', false)) { $nicetype = $type === 'email' ? 'email address' : 'mobile number'; throw new Q_Exception("This {$nicetype} was not registered", array('identifier')); } // Get Gravatar info // WARNING: INTERNET_REQUEST $hash = md5(strtolower(trim($identifier))); $thumbnailUrl = Q_Request::baseUrl() . "/action.php/Users/thumbnail?hash={$hash}&size=80&type=" . Q_Config::get('Users', 'login', 'iconType', 'wavatar'); $json = @file_get_contents("http://www.gravatar.com/{$hash}.json"); $result = json_decode($json, true); if ($result) { if ($type === 'email') { $result['emailExists'] = !empty($exists); } else { if ($type === 'mobile') { $result['mobileExists'] = !empty($exists); } } return $result; } // otherwise, return default $email_parts = explode('@', $identifier, 2); $result = array("entry" => array(array("id" => "571", "hash" => "357a20e8c56e69d6f9734d23ef9517e8", "requestHash" => "357a20e8c56e69d6f9734d23ef9517e8", "profileUrl" => "http://gravatar.com/test", "preferredUsername" => ucfirst($email_parts[0]), "thumbnailUrl" => $thumbnailUrl, "photos" => array(), "displayName" => "", "urls" => array()))); if ($type === 'email') { $result['emailExists'] = !empty($exists); } else { $result['mobileExists'] = !empty($exists); } if ($terms_label = Users::termsLabel('register')) { $result['termsLabel'] = $terms_label; } return $result; }
function Streams_stream_validate($params) { // Protect against CSRF attacks: if (Q_Request::method() !== 'GET') { Q_Valid::nonce(true); } $type = Streams::requestedType(); if ($type && Q::canHandle("Streams/validate/{$type}")) { return Q::event("Streams/validate/{$type}", $params); } }