/** * Allows the user to set their profile picture from a URL. * This is a very useful method because users can then easily use * their profile pictures from other sites, etc. * It's separate from the update() action so it can be called * from a variety of places. Namely, from libraries that make * use of social media networks. This would allow a user to use * their Facebook profile picture for example by going to a Facebook * library of some sort. * * This is a JSON method, meant for use with JavaScript on the front-end. * * Note: The user must be logged in to do this, but this may make * for a good API method in the future - allowing other apps/sites * to set the user's profile picture on this one. */ public function set_profile_picture_from_url() { $response = array('success' => false, 'result' => null); if (!$this->request->is('json')) { return json_encode($response); } if (!$this->request->user || !isset($this->request->data['url'])) { return $response; } // Don't allow the URL to be used if it returns a 404. $ch = curl_init($this->request->data['url']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 404) { return $response; } $conditions = array('_id' => new MongoId($this->request->user['_id'])); // Remove the existing image from the database (keep things tidy). $document = User::find('first', array('conditions' => $conditions)); $existingProfilePicId = false; if (isset($document->profilePicture) && substr($document->profilePicture, 0, 4) != 'http') { $existingProfilePicId = substr($document->profilePicture, 0, -strlen(strrchr($document->profilePicture, '.'))); } // Update the user document. if (User::update(array('$set' => array('profilePicture' => $this->request->data['url'])), $conditions, array('atomic' => false))) { // A final check to ensure there actually is an id. if (!empty($existingProfilePicId)) { Asset::remove(array('_id' => $existingProfilePicId)); } $response = array('success' => true, 'result' => $this->request->data['url']); } return $response; }
<?php use li3b_users\models\Asset; use lithium\net\http\Router; use lithium\core\Environment; use lithium\action\Dispatcher; use lithium\action\Response; Router::connect("/login", array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'login', 'admin' => null)); Router::connect("/logout", array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'logout', 'admin' => null)); Router::connect("/register", array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'register', 'admin' => null)); Router::connect("/settings", array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'update', 'admin' => null)); Router::connect("/profile/{:args}", array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'read', 'args' => array(), 'admin' => null)); // Route for images stored in GridFS. Router::connect('/profilepic/{:args}.(jpe?g|png|gif)', array(), function ($request) { $possibleErrors = array('TOO_LARGE', 'INVALID_FILE_TYPE'); if (!in_array($request->params['args'][0], $possibleErrors)) { $image = Asset::find('first', array('conditions' => array('_id' => $request->params['args'][0]))); if (!$image || !$image->file) { header("Status: 404 Not Found"); header("HTTP/1.0 404 Not Found"); die; } return new Response(array('headers' => array('Content-type' => $image->contentType), 'body' => $image->file->getBytes())); } return new Response(array('location' => '/li3b_users/img/default-profile-picture.png')); });
* */ Asset::applyFilter('save', function ($self, $params, $chain) { // Set the mime-type based on file extension. // This is used in the Content-Type header later on. // Doing this here in a filter saves some work in other places and all // that's required is a file extension. $ext = isset($params['entity']->fileExt) ? strtolower($params['entity']->fileExt) : null; switch ($ext) { default: $mimeType = 'text/plain'; break; case 'jpg': case 'jpeg': $mimeType = 'image/jpeg'; break; case 'png': $mimeType = 'image/png'; break; case 'gif': $mimeType = 'image/gif'; break; } $params['data']['contentType'] = $mimeType; return $chain->next($self, $params, $chain); }); // Second, let's get the validation rules picked up from our $validate property Asset::applyFilter('validates', function ($self, $params, $chain) { $params['options']['rules'] = Asset::$validate; return $chain->next($self, $params, $chain); });