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 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_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_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(); } }
/** * 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 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_message_tool($options) { extract($options); $user = Users::loggedInUser(); if (!$user) { throw new Users_Exception_NotLoggedIn(); } if (empty($publisherId)) { $publisherId = Streams::requestedPublisherId(); } if (empty($publisherId)) { $publisherId = $_REQUEST['publisherId'] = $user->id; } if (empty($name)) { $name = Streams::requestedName(true); } $stream = Streams::fetch($user->id, $publisherId, $name); $stream = !empty($stream) ? reset($stream) : null; if (!$stream) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName'); } if (!$stream->testReadLevel('messages') || !$stream->testWriteLevel('post')) { throw new Users_Exception_NotAuthorized(); } $hidden = array('publisherId' => $publisherId, 'streamName' => $name); $fields = array('stream' => array('label' => 'Stream', 'type' => 'static', 'value' => $stream->title)); $type = Streams::requestedType(); // check if stream has messages $types = Q_Config::get('Streams', 'messages', $stream->type, array()); if (count($types) === 0) { throw new Q_Exception("Stream of type '{$stream->type}' does not support messages"); } if (!empty($type) && !in_array($type, $types)) { throw new Q_Exception("Requested message type '{$type}' is not alowed for streams of type '{$stream->type}'"); } if (!empty($type)) { $hidden['type'] = $type; $fields['type'] = array('label' => 'Message type', 'type' => 'static', 'value' => $type); } else { $fields['type'] = array('label' => 'Message type', 'type' => 'select', 'options' => array_merge(array('' => 'Select type'), array_combine($types, $types)), 'value' => ''); } $fields['content'] = array('label' => 'Content', 'type' => 'textarea'); $fields['submit'] = array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => 'Post')); return Q_Html::tag('h3', array(), 'Post a message') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/message', 'post', array(), Q_Html::hidden($hidden) . Q::tool('Q/form', array('fields' => $fields, 'onSuccess' => 'function (data) { if (data.errors) alert(data.errors); else { alert("Message posted"); var message = Q.getObject(["slots", "form", "fields"], data); Q.handle(Q.info.baseUrl+"/plugins/Streams/message?publisherId="+message.publisherId+"&name="+message.streamName); } }'))); }
function Platform_api_response() { $result = array(); if ($_REQUEST['discover']) { $discover = $_REQUEST['discover']; if (is_string($discover)) { $discover = explode(',', $_REQUEST['discover']); } $discover = array_flip($discover); if (isset($discover['user'])) { $result['user'] = '******'; } if (isset($discover['contacts'])) { $result['contacts'] = array('bhbsneuc' => array('labels' => array(1, 4)), 'bgeoekat' => array('labels' => array(1, 7))); } } $json = Q::json_encode($result); $referer = $_SERVER['HTTP_REFERER']; $parts = parse_url($referer); $origin = Q::json_encode($parts['scheme'] . '://' . $parts['host']); $appUrl = Q::json_encode(Q_Request::baseUrl()); echo <<<EOT <!doctype html> <html> <head> <title>Qbix Platform</title> \t\t<script type="text/javascript"> \t\twindow.addEventListener("message", receiveMessage, false); \t\tfunction receiveMessage(event) { \t\t\tvar request = event.data; \t\t\tvar response = ''; \t\t\tif (!request.method) { \t\t\t\tresponse = {"error": "Missing method"}; \t\t\t} \t\t\tif (request.appUrl.substr(0, event.origin.length) !== event.origin) { \t\t\t\tresponse = {"error": "Origin doesn't match"}; \t\t\t} else { \t\t\t\tresponse = {$json}; \t\t\t} \t\t\twindow.parent.postMessage(response, {$origin}); \t\t} \t\tvar ExposedMethods = function () { \t \t\t}; \t\t</script> </head> <body> </body> </html> EOT; return false; }
/** * This is the default handler for the Q/responseExtras event. * It should not be invoked during AJAX requests, and especially * not during JSONP requests. It will output things like the nonce, * which prevents CSRF attacks, but is only supposed to be printed * on our webpages and not also given to anyone who does a JSONP request. */ function Q_before_Q_responseExtras() { $app = Q_Config::expect('Q', 'app'); $uri = Q_Dispatcher::uri(); $url = Q_Request::url(true); $base_url = Q_Request::baseUrl(); $ajax = Q_Request::isAjax(); if (!$uri) { return; } $info = array('url' => $url, 'uriString' => (string) $uri); if ($uri) { $info['uri'] = $uri->toArray(); } if (!$ajax) { $info = array_merge(array('app' => Q_Config::expect('Q', 'app')), $info, array('proxies' => Q_Config::get('Q', 'proxies', array()), 'baseUrl' => $base_url, 'proxyBaseUrl' => Q_Uri::url($base_url), 'proxyUrl' => Q_Uri::url($url), 'sessionName' => Q_Session::name(), 'nodeUrl' => Q_Utils::nodeUrl(), 'slotNames' => Q_Config::get("Q", "response", "slotNames", array('content', 'dashboard', 'title', 'notices')))); } foreach ($info as $k => $v) { Q_Response::setScriptData("Q.info.{$k}", $v); } if (!$ajax) { $uris = Q_Config::get('Q', 'javascript', 'uris', array()); $urls = array(); foreach ($uris as $u) { $urls["{$u}"] = Q_Uri::url("{$u}"); } Q_Response::setScriptData('Q.urls', $urls); } // Export more variables to inline js $nonce = isset($_SESSION['Q']['nonce']) ? $_SESSION['Q']['nonce'] : null; if ($nonce) { Q_Response::setScriptData('Q.nonce', $nonce); } // Attach stylesheets and scripts foreach (Q_Config::get('Q', 'javascript', 'responseExtras', array()) as $src => $b) { if (!$b) { continue; } Q_Response::addScript($src); } foreach (Q_Config::get('Q', 'stylesheets', 'responseExtras', array()) as $src => $media) { if (!$media) { continue; } if ($media === true) { $media = 'screen,print'; } Q_Response::addStylesheet($src, null, $media); } }
/** * Excecute web request * @method execute * @static */ static function execute() { // Fixes for different platforms: if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // ISAPI 3.0 $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL']; } // Get the base URL $base_url = Q_Request::baseUrl(); if (Q::$controller === 'Q_ActionController') { // we detected action.php in the URL, but // a misconfigured web server executed index.php instead return Q_ActionController::execute(); } // Set the controller that is being used if (!isset(Q::$controller)) { Q::$controller = 'Q_WebController'; } try { $slots = Q_Request::slotNames(false); $slots = $slots ? ' slots: (' . implode(',', $slots) . ') from' : ''; $method = Q_Request::method(); Q::log("{$method}{$slots} url: " . Q_Request::url(true), null, null, array('maxLength' => 10000)); Q_Dispatcher::dispatch(); $dispatchResult = Q_Dispatcher::result(); if (!isset($dispatchResult)) { $dispatchResult = 'Ran dispatcher'; } $uri = Q_Request::uri(); $module = $uri->module; $action = $uri->action; if ($module and $action) { $slotNames = Q_Request::slotNames(); $returned_slots = empty($slotNames) ? '' : implode(',', $slotNames); Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} for {$module}/{$action}" . " ({$returned_slots})", null, null, array('maxLength' => 10000)); } else { Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} No route for " . $_SERVER['REQUEST_URI'], null, null, array('maxLength' => 10000)); } } catch (Exception $exception) { /** * @event Q/exception * @param {Exception} exception */ Q::event('Q/exception', compact('exception')); } }
function Streams_after_Q_file_save($params) { $path = $subpath = $name = $writePath = $data = $tailUrl = $size = $audio = 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; } $url = Q_Valid::url($tailUrl) ? $tailUrl : '{{baseUrl}}/' . $tailUrl; $stream->setAttribute('Q.file.url', $url); $stream->setAttribute('Q.file.size', $size); if ($audio) { include_once Q_CLASSES_DIR . DS . 'Audio' . DS . 'getid3' . DS . 'getid3.php'; $getID3 = new getID3(); $meta = $getID3->analyze($writePath . $name); $bitrate = $meta['audio']['bitrate']; $bits = $size * 8; $duration = $bits / $bitrate; $stream->setAttribute('Q.audio.bitrate', $bitrate); $stream->setAttribute('Q.audio.duration', $duration); } if (Streams_Stream::getConfigField($stream->type, 'updateTitle', false)) { // set the title every time a new file is uploaded $stream->title = $name; } if (Streams_Stream::getConfigField($stream->type, 'updateIcon', false)) { // set the icon every time a new file is uploaded $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(); } else { $stream->save(); } }
function Streams_user_response_data($params) { $identifier = Users::requestedIdentifier($type); $hash = md5(strtolower(trim($identifier))); $icon = Q_Config::get('Users', 'register', 'icon', 'leaveDefault', false) ? $url = "plugins/Users/img/icons/default/80.png" : Q_Request::baseUrl() . "/action.php/Users/thumbnail?hash={$hash}&size=80&type=" . Q_Config::get('Users', 'login', 'iconType', 'wavatar'); // check our db if ($user = Users::userFromContactInfo($type, $identifier)) { $displayname = Streams::displayName($user); $verified = !!Users::identify($type, $identifier); return array('exists' => $user->id, 'verified' => $verified, 'username' => $user->username, 'displayName' => $displayname, 'icon' => $verified ? $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')); } $result = array("entry" => array(array("thumbnailUrl" => $icon))); 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 Overlay_home_response_content($params) { $countries = array(); $files = glob(APP_WEB_DIR . DS . 'img' . DS . 'squareflags' . DS . '*'); foreach ($files as $file) { $basename = basename($file); $src = Q_Request::baseUrl() . "/img/squareflags/{$basename}"; $src = str_replace(' ', '%20', $src); if (empty($firstCountrySrc)) { $firstCountrySrc = $src; } $parts = explode('.', $basename); $parts2 = explode('_', $parts[0]); foreach ($parts2 as &$v) { $v = strtoupper($v[0]) . substr($v, 1); } $countries[$src] = implode(' ', $parts2); } $counter = Overlay::counter(); $proxyHost = 'http://' . $_SERVER['HTTP_HOST'] . ':' . Q_Config::get('Q', 'node', 'port', '80'); Q_Response::setScriptData('Overlay.proxyHost', $proxyHost); return Q::view('Overlay/content/home.php', compact('countries', 'firstCountrySrc', 'counter')); }
function resendActivationMessage($view = null, $fields = array(), $options = array()) { if (!isset($view)) { $view = Q_Config::get('Users', 'transactional', 'resend', 'sms', Q_Config::get('Users', 'transactional', 'resend', 'sms', 'Users/sms/activation.php')); } $user = $this->get('user', null); if (!$user) { $user = new Users_User(); $user->id = $this->userId; if (!$user->retrieve()) { throw new Q_Exception_NotVerified(array('type' => 'mobile number'), 'mobileNumber'); } } $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7); $this->activationCode = strtolower(Q_Utils::unique(5)); $this->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE"); $this->authCode = md5(microtime() + mt_rand()); $number = $this->number; if (substr($number, 0, 2) == '+1') { $number = substr($number, 2); } $link = 'Users/activate?p=1&code=' . urlencode($this->activationCode) . ' mobileNumber=' . urlencode($number); /** * @event Users/resend {before} * @param {string} user * @param {string} mobile */ Q::event('Users/resend', compact('user', 'mobile', 'link'), 'before'); $this->save(); $fields2 = array_merge($fields, array('user' => $user, 'mobile' => $this, 'app' => Q_Config::expect('Q', 'app'), 'baseUrl' => Q_Request::baseUrl(), 'link' => $link)); $this->sendMessage($view, $fields2, $options); // may throw exception if badly configured /** * @event Users/resend {after} * @param {string} user * @param {string} mobile */ Q::event('Users/resend', compact('user', 'mobile'), 'after'); }
/** * This function is very useful to use with clients like PhoneGap which can * intercept URLs and load whatever locally cached files are stored in their bundle. * The urls for these files will be relative to the cache base url. * (See Q_Uri::cacheBaseUrl function). * In this case, the client is supposed to send the timestamp of when the * cache it is using was generated. * This function checks the current contents of the Q/config/Q/urls.php file, * generated by scripts/Q/urls.php script. * If the url's timestamp there is newer than the Q_Request::cacheTimestamp() * (which the client can set by setting the 'Q_ct' field in the querystring) * then that means the server has a newer version of the file, so the passed * $url is used instead. * Otherwise, the url relative to cacheBaseUrl is used, making the client * load the locally cached version. */ static function cachedUrl($url) { $timestamp = Q_Request::cacheTimestamp(); if (empty($timestamp)) { return $url; } $urlRelativeToBase = substr($url, strlen(Q_Request::baseUrl())); $fileTimestamp = isset(Q_Uri::$urls[$urlRelativeToBase]) ? Q_Uri::$urls[$urlRelativeToBase] : null; if (isset($fileTimestamp) and $fileTimestamp <= $timestamp and self::$cacheBaseUrl) { return self::$cacheBaseUrl . $urlRelativeToBase; } return $url; }
/** * Get the url of the stream's icon * @param {string} [$basename=""] The last part after the slash, such as "50.png" * @return {string} The stream's icon url */ function iconUrl($basename = null) { if (empty($this->icon)) { return null; } $url = Q::interpolate($this->icon, array('baseUrl' => Q_Request::baseUrl())); $url = Q_Valid::url($url) ? $url : "plugins/Streams/img/icons/{$url}"; if ($basename) { if (strpos($basename, '.') === false) { $basename = "{$basename}.png"; } $url .= "/{$basename}"; } return Q_Html::themedUrl($url); }
/** * Invites a user (or a future user) to a stream . * @method invite * @static * @param {string} $publisherId The id of the stream publisher * @param {string} $streamName The name of the stream the user will be invited to * @param {array} $who Array that can contain the following keys: * @param {string|array} [$who.userId] user id or an array of user ids * @param {string|array} [$who.fb_uid] fb user id or array of fb user ids * @param {string|array} [$who.label] label or an array of labels, or tab-delimited string * @param {string|array} [$who.identifier] identifier or an array of identifiers, or tab-delimited string * @param {integer} [$who.newFutureUsers] the number of new Users_User objects to create via Users::futureUser in order to invite them to this stream. This typically is used in conjunction with passing the "html" option to this function. * @param {array} [$options=array()] * @param {string|array} [$options.label] label or an array of labels for adding publisher's contacts * @param {string|array} [$options.myLabel] label or an array of labels for adding logged-in user's contacts * @param {integer} [$options.readLevel] => the read level to grant those who are invited * @param {integer} [$options.writeLevel] => the write level to grant those who are invited * @param {integer} [$options.adminLevel] => the admin level to grant those who are invited * @param {string} [$options.displayName] => the display name to use to represent the inviting user * @param {string} [$options.appUrl] => Can be used to override the URL to which the invited user will be redirected and receive "Q.Streams.token" in the querystring. * @param {array} [$options.html] => an array of ($template, $batchName) such as ("MyApp/foo.handlebars", "foo") for generating html snippets which can then be viewed from and printed via the action Streams/invitations?batchName=$batchName * @param {array} [$options.asUserId=null] Invite as this user id * @see Users::addLink() * @return {array} returns array with keys "success", "invited", "statuses", "identifierTypes", "alreadyParticipating" */ static function invite($publisherId, $streamName, $who, $options = array()) { if (isset($options['asUserId'])) { $asUserId = $options['asUserId']; $asUser = Users_User::fetch($asUserId); } else { $asUser = Users::loggedInUser(true); $asUserId = $asUser->id; } // Fetch the stream as the logged-in user $stream = Streams::fetch($asUserId, $publisherId, $streamName); if (!$stream) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName'); } $stream = reset($stream); // Do we have enough admin rights to invite others to this stream? if (!$stream->testAdminLevel('invite') || !$stream->testWriteLevel('join')) { throw new Users_Exception_NotAuthorized(); } if (isset($options['html'])) { $html = $options['html']; if (!is_array($html) or count($html) < 2) { throw new Q_Exception_WrongType(array('field' => "options.html", 'type' => 'array of 2 strings')); } list($template, $batchName) = $html; // validate these paths $filename = APP_VIEWS_DIR . DS . $template; if (!Q::realPath($filename)) { throw new Q_Exception_MissingFile(compact('filename')); } $ext = $pathinfo = pathinfo($template, PATHINFO_EXTENSION); if ($ext !== 'handlebars') { throw new Q_Exception_WrongValue(array('field' => 'options.html[0]', 'range' => 'a filename with extension .handlebars')); } $path = Streams::invitationsPath($asUserId) . DS . $batchName; Q_Utils::canWriteToPath($path, true, true); } // get user ids if any to array, throw if user not found $raw_userIds = isset($who['userId']) ? Users_User::verifyUserIds($who['userId'], true) : array(); // merge labels if any if (isset($who['label'])) { $label = $who['label']; if (is_string($label)) { $label = array_map('trim', explode("\t", $labels)); } $raw_userIds = array_merge($raw_userIds, Users_User::labelsToIds($asUserId, $label)); } // merge identifiers if any $identifierType = null; $statuses = null; if (isset($who['identifier'])) { $identifier = $who['identifier']; if (is_string($identifier)) { if (Q_Valid::email($who['identifier'])) { $identifierType = 'email'; } else { if (Q_Valid::phone($who['identifier'])) { $identifierType = 'mobile'; } } $identifier = array_map('trim', explode("\t", $identifier)); } $statuses = array(); $identifier_ids = Users_User::idsFromIdentifiers($identifier, $statuses); $raw_userIds = array_merge($raw_userIds, $identifier_ids); } // merge fb uids if any if (isset($who['fb_uid'])) { $fb_uids = $who['fb_uid']; if (is_string($fb_uids)) { $fb_uids = array_map('trim', explode("\t", $fb_uids)); } $raw_userIds = array_merge($raw_userIds, Users_User::idsFromFacebook($fb_uids)); } if (!empty($who['newFutureUsers'])) { $nfu = $who['newFutureUsers']; for ($i = 0; $i < $nfu; ++$i) { $raw_userIds[] = Users::futureUser('none', null)->id; } } // ensure that each userId is included only once // and remove already participating users $raw_userIds = array_unique($raw_userIds); $total = count($raw_userIds); $userIds = Streams_Participant::filter($raw_userIds, $stream); $to_invite = count($userIds); $appUrl = !empty($options['appUrl']) ? $options['appUrl'] : Q_Request::baseUrl() . '/' . Q_Config::get("Streams", "types", $stream->type, "invite", "url", "plugins/Streams/stream"); // now check and define levels for invited user $readLevel = isset($options['readLevel']) ? $options['readLevel'] : null; if (isset($readLevel)) { if (!$stream->testReadLevel($readLevel)) { // We can't assign greater read level to other people than we have ourselves! throw new Users_Exception_NotAuthorized(); } } $writeLevel = isset($options['writeLevel']) ? $options['writeLevel'] : null; if (isset($writeLevel)) { if (!$stream->testWriteLevel($writeLevel)) { // We can't assign greater write level to other people than we have ourselves! throw new Users_Exception_NotAuthorized(); } } $adminLevel = isset($options['adminLevel']) ? $options['adminLevel'] : null; if (isset($adminLevel)) { if (!$stream->testAdminLevel($adminLevel + 1)) { // We can't assign an admin level greater, or equal, to our own! // A stream's publisher can assign owners. Owners can assign admins. // Admins can confer powers to invite others, to some people. // Those people can confer the privilege to publish a message re this stream. // But admins can't assign other admins, and even stream owners // can't assign other owners. throw new Users_Exception_NotAuthorized(); } } // calculate expiry time $duration = Q_Config::get("Streams", "types", $stream->type, "invite", "duration", false); $expiry = $duration ? strtotime($duration) : null; // let node handle the rest, and get the result $params = array("Q/method" => "Streams/Stream/invite", "invitingUserId" => $asUserId, "username" => $asUser->username, "userIds" => Q::json_encode($userIds), "stream" => Q::json_encode($stream->toArray()), "appUrl" => $appUrl, "label" => Q::ifset($options, 'label', null), "myLabel" => Q::ifset($options, 'myLabel', null), "readLevel" => $readLevel, "writeLevel" => $writeLevel, "adminLevel" => $adminLevel, "displayName" => isset($options['displayName']) ? $options['displayName'] : Streams::displayName($asUser), "expiry" => $expiry); if ($template) { $params['template'] = $template; $params['batchName'] = $batchName; } $result = Q_Utils::queryInternal('Q/node', $params); return array('success' => $result, 'invited' => $userIds, 'statuses' => $statuses, 'identifierType' => $identifierType, 'alreadyParticipating' => $total - $to_invite); }
/** * Starts the process of adding a mobile to a saved user object. * Also modifies and saves this user object back to the database. * @method addMobile * @param {string} $mobileNumber * The mobile number to add. * @param {string} [$activationMessageView=null] * The view to use for the body of the activation message to send. * @param {array} [$fields=array()] * An array of additional fields to pass to the mobile view. * @param {array} $options=array() * Array of options. Can include:<br/> * "delay" => A delay, in milliseconds, to wait until sending email. Only works if Node server is listening. * @return {boolean} * Returns true on success. * Returns false if this mobile number is already verified for this user. * @throws {Q_Exception_WrongValue} * If the mobile number is in an invalid format, this is thrown. * @throws {Users_Exception_AlreadyVerified} * If the mobile number already exists and has been verified for * another user, then this exception is thrown. */ function addMobile($mobileNumber, $activationMessageView = null, $fields = array(), $options = array()) { if (!Q_Valid::phone($mobileNumber, $normalized)) { throw new Q_Exception_WrongValue(array('field' => 'Mobile phone', 'range' => 'a valid number'), 'mobileNumber'); } $mobile = new Users_Mobile(); $mobile->number = $normalized; if ($mobile->retrieve('*', array('ignoreCache' => true)) and $mobile->state !== 'unverified') { if ($mobile->userId === $this->id) { $mobile->set('user', $this); return $mobile; } // Otherwise, say it's verified for another user, // even if it unsubscribed or was suspended. throw new Users_Exception_AlreadyVerified(array('key' => 'mobile number', 'userId' => $mobile->userId), 'mobileNumber'); } $user = $this; // If we are here, then the mobile record either // doesn't exist, or hasn't been verified yet. // In either event, update the record in the database, // and re-send the mobile. $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7); $mobile->state = 'unverified'; $mobile->userId = $this->id; $mobile->activationCode = strtolower(Q_Utils::unique(7)); $mobile->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE"); $number = $mobile->number; if (substr($number, 0, 2) == '+1') { $number = substr($number, 2); } $mobile->authCode = md5(microtime() + mt_rand()); $link = 'Users/activate?code=' . urlencode($mobile->activationCode) . ' mobileNumber=' . urlencode($number); /** * @event Users/addIdentifier {before} * @param {string} user * @param {string} mobile */ Q::event('Users/addIdentifier', compact('user', 'mobile', 'link'), 'before'); $mobile->save(); $this->mobileNumberPending = $normalized; $this->save(); if (!isset($activationMessageView)) { $activationMessageView = Q_Config::get('Users', 'transactional', 'activation', 'sms', 'Users/sms/activation.php'); } $fields2 = array_merge($fields, array('user' => $this, 'mobile' => $mobile, 'app' => Q_Config::expect('Q', 'app'), 'baseUrl' => Q_Request::baseUrl(), 'link' => $link)); $mobile->sendMessage($activationMessageView, $fields2, $options); Q_Response::removeNotice('Users/mobile'); /** * @event Users/addIdentifier {after} * @param {string} user * @param {string} mobile */ Q::event('Users/addIdentifier', compact('user', 'mobile', 'link'), 'after'); }
echo Q_Html::img($byUser->iconUrl('80.png'), $byDisplayName, array('class' => 'item_icon')); ?> </td> <td> <h2><?php echo $byDisplayName; ?> invited you to:</h2> <div class='stream_title'><?php echo $stream->title; ?> </div> </td> </tr> </table> <h3>Let your friends recognize you:</h3> <div class='Q_login Q_big_prompt'> <?php echo Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/basic', 'post'); ?> <?php echo Q_Html::hidden(array('token' => $token, 'userId' => $user->id)); ?> <?php echo Q::tool('Q/form', array('fields' => array('name' => array('placeholder' => "", 'label' => 'Enter your name:'), '' => array('type' => 'submit', 'value' => 'Get Started')), 'onSuccess' => Q_Request::baseUrl() . "/plugins/Streams/stream?publisherId={$stream->publisherId}&streamName={$stream->name}"), array('id' => 'Streams_Register')); ?> </form> </div> </div> </div>
/** * The current theme url applied to all "src" attributes (except for iframes) * rendered by Q_Html. * @method themeUrl * @static * @return {string|null} The theme url that is currently at the end of the cascade, i.e. was pushed last. */ static function themeUrl() { return isset(self::$theme) ? self::$theme : Q_Request::baseUrl(); }
<meta name="msapplication-square310x310logo" content="<?php echo Q_Html::themedUrl('img/icon/150.png'); ?> "> <meta name="msapplication-TileColor" content="#ffffff"> <meta name="msapplication-TileImage" content="<?php echo Q_Html::themedUrl('img/icon/144.png'); ?> "> <title><?php echo $title; ?> </title> <link rel="shortcut icon" href="<?php echo Q_Request::baseUrl(); ?> /favicon.ico" type="image/x-icon"> <script type="text/javascript"> document.getElementsByTagName('html')[0].className += ' Q_js'; // better than noscript </script> <!-- scripts have been moved to the bottom of the body --> <?php echo Q_Response::stylesheets(true, "\n\t"); ?> <?php echo Q_Response::styles(true, "\n\t"); ?>
function Streams_invite_tool($options) { extract($options); $form_tool = Q::tool('Q/form', array('fields' => array('displayName' => array('label' => "Display name", 'type' => 'text', 'value' => Streams::displayName(Users::loggedInUser(), array('fullAccess' => true))), 'userId' => array('label' => "User id to invite", 'type' => 'textarea'), 'identifier' => array('label' => 'Mobile Number or Email Address', 'type' => 'textarea'), 'label' => array('label' => 'Group label', 'type' => 'textarea'), 'readLevel' => array('label' => 'Read level', 'type' => 'select', 'value' => Streams::$READ_LEVEL['content'], 'options' => array_flip(Streams::$READ_LEVEL)), 'writeLevel' => array('label' => 'Write level', 'type' => 'select', 'value' => Streams::$WRITE_LEVEL['post'], 'options' => array_flip(Streams::$WRITE_LEVEL)), 'adminLevel' => array('label' => 'Admin level', 'type' => 'select', 'options' => array_flip(Streams::$ADMIN_LEVEL)), 'submit' => array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => 'Send Invite'))))) . Q_Html::hidden(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name)); return Q_Html::tag('h3', array(), 'Invite to stream "' . $options['stream']->name . '"') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/invite', 'post', array(), $form_tool); }
?> <?php echo Q_Html::hidden(array('emailAddress' => $user->emailAddress)); ?> <button type="submit" class="Users_login_start Q_main_button">Re-send activation message</button> </form> </div> <?php } ?> <?php } else { ?> <div class="Q_register Q_big_prompt"> <?php echo Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/invited'); ?> <?php echo Q_Html::formInfo($stream_uri); ?> <?php echo Q_Html::hidden(array('token' => $invite->token, 'icon' => $thumbnail_url)); ?> <?php echo Q::tool('Q/form', array('fields' => $fields)); ?> </form> </div> <?php } ?>
/** * Get the url of a user's icon * @param {string} [$icon] The contents of a user row's icon field * @param {string} [$basename=""] The last part after the slash, such as "50.png" * @return {string} The stream's icon url */ static function iconUrl($icon, $basename = null) { if (empty($icon)) { return null; } $url = Q::interpolate($icon, array('baseUrl' => Q_Request::baseUrl())); $url = Q_Valid::url($url) ? $url : "plugins/Users/img/icons/{$url}"; if ($basename) { $url .= "/{$basename}"; } return Q_Html::themedUrl($url); }
/** * @method setCookie * @static * @param {string} $name * @param {string} $value * @param {string} [$expires=0] * @param {string} [$path=false] * @return {string} */ static function setCookie($name, $value, $expires = 0, $path = false) { if (empty($_SERVER['HTTP_HOST'])) { Q::log('Warning: Ignoring call to Q_Response::setCookie() without $_SERVER["HTTP_HOST"]' . PHP_EOL); return false; } if (isset($_COOKIE[$name]) and $_COOKIE[$name] === $value) { return; } $parts = parse_url(Q_Request::baseUrl()); $path = $path ? $path : !empty($parts['path']) ? $parts['path'] : '/'; $domain = '.' . $parts['host']; setcookie($name, $value, $expires, $path, $domain); $_COOKIE[$name] = $value; $header = 'P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"'; $header = Q::event('Q/Response/setCookie', compact('name', 'value', 'expires', 'path', 'header'), 'before', false, $header); header($header); return $value; }
function resendActivationMessage($subject = null, $view = null, $fields = array(), $options = array()) { if (!isset($subject)) { $subject = Q_Config::get('Users', 'transactional', 'resend', 'subject', Q_Config::get('Users', 'transactional', 'activation', 'subject', 'Did you forget your passphrase?')); } if (!isset($view)) { $view = Q_Config::get('Users', 'transactional', 'resend', 'body', Q_Config::get('Users', 'transactional', 'activation', 'body', 'Users/email/activation.php')); } if (!isset($options['html'])) { $options['html'] = true; } $user = $this->get('user', null); if (!$user) { $user = new Users_User(); $user->id = $this->userId; if (!$user->retrieve()) { throw new Q_Exception_NotVerified(array('type' => 'email address'), 'emailAddress'); } } $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7); $this->activationCode = strtolower(Q_Utils::unique(7)); $this->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE"); $this->authCode = md5(microtime() + mt_rand()); $link = 'Users/activate?p=1&code=' . urlencode($this->activationCode) . ' emailAddress=' . urlencode($this->address); /** * @event Users/resend {before} * @param {string} user * @param {string} email */ Q::event('Users/resend', compact('user', 'email', 'link'), 'before'); $this->save(); $email = $this; $fields2 = array_merge($fields, array('user' => $user, 'email' => $this, 'app' => Q_Config::expect('Q', 'app'), 'baseUrl' => Q_Request::baseUrl(), 'link' => $link)); $this->sendMessage($subject, $view, $fields2, $options); // may throw exception if badly configured /** * @event Users/resend {after} * @param {string} user * @param {string} email */ Q::event('Users/resend', compact('user', 'email'), 'after'); }
/** * This function is very useful to use with clients like PhoneGap which can * intercept URLs and load whatever locally cached files are stored in their bundle. * The urls for these files will be relative to the cache base url. * (See Q_Uri::cacheBaseUrl function). * In this case, the client is supposed to send the timestamp of when the * cache it is using was generated. * This function checks the current contents of the Q/config/Q/urls.php file, * generated by scripts/Q/urls.php script. * If the url's timestamp there is newer than the Q_Request::cacheTimestamp() * (which the client can set by setting the 'Q_ct' field in the querystring) * then that means the server has a newer version of the file, so the passed * $url is used instead. * Otherwise, the url relative to cacheBaseUrl is used, making the client * load the locally cached version. */ static function cachedUrl($url) { $timestamp = Q_Request::cacheTimestamp(); if (empty($timestamp)) { return $url; } $urlRelativeToBase = substr($url, strlen(Q_Request::baseUrl(false, true))); $parts = explode('/', $urlRelativeToBase); $parts[] = null; $tree = new Q_Tree(Q_Uri::$urls); $fileTimestamp = call_user_func_array(array($tree, 'get'), $parts); if (isset($fileTimestamp) and $fileTimestamp <= $timestamp and self::$cacheBaseUrl) { return self::$cacheBaseUrl . $urlRelativeToBase; } return $url; }
/** * The standard action front controller * @method execute * @static * @throws {Q_Exception_BadUrl} * @throws {Q_Exception} * @throws {Q_Exception_MissingConfig} */ static function execute($url = null) { // Fixes for different platforms: if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // ISAPI 3.0 $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL']; } // Set the controller that is being used if (!isset(Q::$controller)) { Q::$controller = 'Q_ActionController'; } try { $slots = Q_Request::slotNames(false); $slots = $slots ? ' slots: (' . implode(',', $slots) . ') from' : ''; $method = Q_Request::method(); Q::log("{$method}{$slots} url: " . Q_Request::url(true)); $tail = Q_Request::tail($url); if (!isset($tail)) { // Bad url was requested somehow $url = Q_Request::url(true); $base_url = Q_Request::baseUrl(true); throw new Q_Exception_BadUrl(compact('base_url', 'url')); } $parts = explode('/', $tail); $parts_len = count($parts); if ($parts_len >= 1) { $module = $parts[0]; } if ($parts_len >= 2) { $action = $parts[1]; } if (empty($module) or empty($action)) { throw new Q_Exception("Not implemented"); } // Make sure the 'Q'/'web' config fields are set, // otherwise URLs will be formed pointing to the wrong // controller script. $ar = Q_Config::get('Q', 'web', 'appRootUrl', null); if (!isset($ar)) { throw new Q_Exception_MissingConfig(array('fieldpath' => 'Q/web/appRootUrl')); } // Dispatch the request $uri = Q_Uri::from(compact('module', 'action')); Q_Dispatcher::dispatch($uri); $dispatchResult = Q_Dispatcher::result(); if (!isset($dispatchResult)) { $dispatchResult = 'Ran dispatcher'; } if ($module and $action) { $slotNames = Q_Request::slotNames(); $requestedSlots = empty($slotNames) ? '' : implode(',', $slotNames); Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} for {$module}/{$action}" . " ({$requestedSlots})"); } else { Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " No route for " . $_SERVER['REQUEST_URI']); } } catch (Exception $exception) { /** * @event Q/exception * @param {Exception} exception */ Q::event('Q/exception', compact('exception')); } }
static function destroy() { session_destroy(); self::clear(); if (ini_get("session.use_cookies")) { $params = session_get_cookie_params(); $parts = parse_url(Q_Request::baseUrl()); $domain = '.' . $parts['host']; setcookie(self::name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]); } }