/** * Used by HTTP clients to upload a new image to the server * @class Q/image * @method post * @param {array} [$params] Parameters that can come from the request * @param {string} [$params.icon.data] Required if $_FILES is empty. Base64-encoded data URI - see RFC 2397 * @param {string} [$params.icon.path="uploads"] parent path under web dir (see subpath) * @param {string} [$params.icon.subpath=""] subpath that should follow the path, to save the image under * @param {string} [$params.icon.merge=""] path under web dir for an optional image to use as a background * @param {string} [$params.icon.crop] array with keys "x", "y", "w", "h" to crop the original image * @param {string} [$params.icon.save=array("x" => "")] array of $size => $basename pairs * where the size is of the format "WxH", and either W or H can be empty. */ function Q_image_post($params = null) { $p = $params ? $params : Q::take($_REQUEST, array('data', 'path', 'subpath', 'merge', 'crop', 'save')); if (!empty($_FILES)) { $file = reset($_FILES); $tmp = $file['tmp_name']; if (empty($p['data'])) { $p['data'] = file_get_contents($tmp); } unlink($tmp); } else { if (empty($p['data'])) { throw new Q_Exception_RequiredField(array('field' => 'data'), 'data'); } $p['data'] = base64_decode(chunk_split(substr($p['data'], strpos($p['data'], ',') + 1))); } $timeLimit = Q_Config::get('Q', 'uploads', 'limits', 'image', 'time', 5 * 60 * 60); set_time_limit($timeLimit); // default is 5 min $data = Q_Image::save($p); if (empty($params)) { Q_Response::setSlot('data', $data); } return $data; }
function Users_thumbnail_response() { $slots = Q_Response::slots(true); if (isset($slots['data'])) { return; } if (!isset($_REQUEST['hash'])) { throw new Q_Exception_WrongValue(array('field' => 'hash', 'range' => "identifier hash")); } $hash = $_REQUEST['hash']; header("Content-type: image/png"); $gravatar = isset($_REQUEST['gravatar']) ? $_REQUEST['gravatar'] : Q_Config::get('Users', 'login', 'gravatar', false); $result = Q_Image::avatar($hash, isset($_REQUEST['size']) ? $_REQUEST['size'] : null, isset($_REQUEST['type']) ? $_REQUEST['type'] : null, $gravatar); if ($gravatar) { echo $result; } else { imagepng($result); } return false; }
/** * Imports an icon and sets $user->icon to the url. * @method importIcon * @static * @param {array} $user The user for whom the icon should be downloaded * @param {array} [$urls=array()] Array of urls * @param {string} [$directory=null] Defaults to APP/files/APP/uploads/Users/USERID/icon/imported * @return {string} the path to the icon directory */ static function importIcon($user, $urls = array(), $directory = null) { if (empty($directory)) { $app = Q_Config::expect('Q', 'app'); $directory = APP_FILES_DIR . DS . $app . DS . 'uploads' . DS . 'Users' . DS . Q_Utils::splitId($user->id) . DS . 'icon' . DS . 'imported'; } if (empty($urls)) { return $directory; } Q_Utils::canWriteToPath($directory, false, true); $type = Q_Config::get('Users', 'login', 'iconType', 'wavatar'); $largestSize = 0; $largestUrl = null; $largestImage = null; foreach ($urls as $basename => $url) { if (!is_string($url)) { continue; } $filename = $directory . DS . $basename; $info = pathinfo($filename); $size = $info['filename']; if ((string) (int) $size !== $size) { continue; } if ($largestSize < (int) $size) { $largestSize = (int) $size; $largestUrl = $url; } } if ($largestSize) { $largestImage = imagecreatefromstring(file_get_contents($largestUrl)); } foreach ($urls as $basename => $url) { if (is_string($url)) { $filename = $directory . DS . $basename; $info = pathinfo($filename); $size = $info['filename']; $success = false; if ($largestImage and (string) (int) $size === $size) { if ($size == $largestSize) { $image = $largestImage; $success = true; } else { $image = imagecreatetruecolor($size, $size); imagealphablending($image, false); $success = imagecopyresampled($image, $largestImage, 0, 0, 0, 0, $size, $size, $largestSize, $largestSize); } } if (!$success) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); curl_close($ch); $image = imagecreatefromstring($data); } $info = pathinfo($filename); switch ($info['extension']) { case 'png': $func = 'imagepng'; imagesavealpha($image, true); imagealphablending($image, true); break; case 'jpeg': case 'jpeg': $func = 'imagejpeg'; break; case 'gif': $func = 'imagegif'; break; } call_user_func($func, $image, $directory . DS . $info['filename'] . '.png'); } else { Q_Image::put($directory . DS . $basename, $url['hash'], $url['size'], $type, Q_Config::get('Users', 'login', 'gravatar', false)); } } $head = APP_FILES_DIR . DS . $app . DS . 'uploads'; $tail = str_replace(DS, '/', substr($directory, strlen($head))); $user->icon = '{{baseUrl}}/uploads' . $tail; return $directory; }
/** * Used to create a new stream * * @param {array} $_REQUEST * @param {String} [$_REQUEST.title] Required. The title of the interest. * @param {String} [$_REQUEST.publisherId] Optional. Defaults to the app name. * @param {String} [$_REQUEST.subscribe] Optional. Defauls to false. Whether to subscribe rather than just join the interest stream. * @return {void} */ function Streams_interest_post() { $user = Users::loggedInUser(true); $title = Q::ifset($_REQUEST, 'title', null); if (!isset($title)) { throw new Q_Exception_RequiredField(array('field' => 'title')); } $app = Q_Config::expect('Q', 'app'); $publisherId = Q::ifset($_REQUEST, 'publisherId', $app); $name = 'Streams/interest/' . Q_Utils::normalize($title); $stream = Streams::fetchOne(null, $publisherId, $name); if (!$stream) { $stream = Streams::create($publisherId, $publisherId, 'Streams/interest', array('name' => $name, 'title' => $title)); $parts = explode(': ', $title, 2); $keywords = implode(' ', $parts); try { $data = Q_Image::pixabay($keywords, array('orientation' => 'horizontal', 'min_width' => '500', 'safesearch' => 'true', 'image_type' => 'photo'), true); } catch (Exception $e) { Q::log("Exception during Streams/interest post: " . $e->getMessage()); $data = null; } if (!empty($data)) { $sizes = Q_Config::expect('Streams', 'icons', 'sizes'); ksort($sizes); $params = array('data' => $data, 'path' => "plugins/Streams/img/icons", 'subpath' => $name, 'save' => $sizes, 'skipAccess' => true); Q_Image::save($params); $stream->icon = $name; } $stream->save(); } $subscribe = !!Q::ifset($_REQUEST, 'subscribe', false); if ($subscribe) { if (!$stream->subscription($user->id)) { $stream->subscribe(); } } else { $stream->join(); } $myInterestsName = 'Streams/user/interests'; $myInterests = Streams::fetchOne($user->id, $user->id, $myInterestsName); if (!$myInterests) { $myInterests = new Streams_Stream(); $myInterests->publisherId = $user->id; $myInterests->name = $myInterestsName; $myInterests->type = 'Streams/category'; $myInterests->title = 'My Interests'; $myInterests->save(); } Streams::relate($user->id, $user->id, 'Streams/user/interests', 'Streams/interest', $publisherId, $name, array('weight' => '+1')); Q_Response::setSlot('publisherId', $publisherId); Q_Response::setSlot('streamName', $name); /** * Occurs when the logged-in user has successfully added an interest via HTTP * @event Streams/interest/post {after} * @param {string} publisherId The publisher of the interest stream * @param {string} title The title of the interest * @param {boolean} subscribe Whether the user subscribed to the interest stream * @param {Users_User} user The logged-in user * @param {Streams_Stream} stream The interest stream * @param {Streams_Stream} myInterests The user's "Streams/user/interests" stream */ Q::event("Streams/interest/add", compact('publisherId', 'title', 'subscribe', 'user', 'stream', 'myInterests'), 'after'); }