From 9e817943acfb4c8a8b5824cd7a87a21a654a7fb1 Mon Sep 17 00:00:00 2001 From: Aaron Parecki Date: Thu, 7 Apr 2016 15:57:42 -0700 Subject: [PATCH] integrates photo uploading in the main note interface Quill corrects the photo rotation based on exif data since iOS tends to take landscape photos and set the rotation bit when holding it in portrait mode. --- controllers/auth.php | 32 +++++++------ controllers/controllers.php | 89 +++++++++++++++++-------------------- lib/helpers.php | 23 ++++++++++ public/js/script.js | 6 ++- views/dashboard.php | 1 - views/layout.php | 1 - views/new-post.php | 85 ++++++++++++++++++++++++++++++++--- views/photo.php | 56 ----------------------- 8 files changed, 162 insertions(+), 131 deletions(-) delete mode 100644 views/photo.php diff --git a/controllers/auth.php b/controllers/auth.php index 0237c59..748f7ad 100644 --- a/controllers/auth.php +++ b/controllers/auth.php @@ -4,18 +4,18 @@ function buildRedirectURI() { return Config::$base_url . 'auth/callback'; } -function build_url($parsed_url) { - $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; - $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; - $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; - $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; - $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; - $pass = ($user || $pass) ? "$pass@" : ''; - $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; - $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; - $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; - return "$scheme$user$pass$host$port$path$query$fragment"; -} +function build_url($parsed_url) { + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; + $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; + $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; + $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + return "$scheme$user$pass$host$port$path$query$fragment"; +} $app->get('/', function($format='html') use($app) { $res = $app->response(); @@ -38,7 +38,6 @@ $app->get('/auth/start', function() use($app) { // the "me" parameter is user input, and may be in a couple of different forms: // aaronparecki.com http://aaronparecki.com http://aaronparecki.com/ - // Normlize the value now (move this into a function in IndieAuth\Client later) if(!array_key_exists('me', $params) || !($me = IndieAuth\Client::normalizeMeURL($params['me']))) { $html = render('auth_error', array( 'title' => 'Sign In', @@ -68,12 +67,12 @@ $app->get('/auth/start', function() use($app) { $authorizationURL = false; } - // If the user has already signed in before and has a micropub access token, - // and the endpoints are all the same, skip the debugging screens and redirect + // If the user has already signed in before and has a micropub access token, + // and the endpoints are all the same, skip the debugging screens and redirect // immediately to the auth endpoint. // This will still generate a new access token when they finish logging in. $user = ORM::for_table('users')->where('url', $me)->find_one(); - if($user && $user->micropub_access_token + if($user && $user->micropub_access_token && $user->micropub_endpoint == $micropubEndpoint && $user->token_endpoint == $tokenEndpoint && $user->authorization_endpoint == $authorizationEndpoint @@ -251,4 +250,3 @@ $app->get('/signout', function() use($app) { unset($_SESSION['user_id']); $app->redirect('/', 301); }); - diff --git a/controllers/controllers.php b/controllers/controllers.php index 95d3aa5..b27c73e 100644 --- a/controllers/controllers.php +++ b/controllers/controllers.php @@ -384,20 +384,6 @@ function create_favorite(&$user, $url) { return $r; } -function create_photo(&$user, $params, $file) { - $error = validate_photo($file); - - if(!$error) { - $file_path = $file['tmp_name']; - $micropub_request = array('content' => $params['note_content']); - $r = micropub_post_for_user($user, $micropub_request, $file_path); - } else { - $r = array('error' => $error); - } - - return $r; -} - function create_repost(&$user, $url) { $micropub_request = array( 'repost-of' => $url @@ -452,40 +438,6 @@ $app->post('/favorite', function() use($app) { } }); -$app->post('/photo', function() use($app) { - if($user=require_login($app)) { - - // var_dump($app->request()->post()); - // - // Since $app->request()->post() with multipart is always - // empty (bug in Slim?) We're using the raw $_POST here - // until this gets fixed. - // PHP empties everything in $_POST if the file upload size exceeds - // that is why we have to test if the variables exist first. - - $note_content = isset($_POST['note_content']) ? $_POST['note_content'] : null; - $params = array('note_content' => $note_content); - $file = isset($_FILES['note_photo']) ? $_FILES['note_photo'] : null; - - $r = create_photo($user, $params, $file); - - // Populate the error if there was no location header. - if(empty($r['location']) && empty($r['error'])) { - $r['error'] = "No 'Location' header in response."; - } - - $html = render('photo', array( - 'title' => 'Photo posted', - 'note_content' => $params['note_content'], - 'location' => (isset($r['location']) ? $r['location'] : null), - 'error' => (isset($r['error']) ? $r['error'] : null), - 'response' => (isset($r['response']) ? htmlspecialchars($r['response']) : null), - 'authorizing' => false - )); - $app->response()->body($html); - } -}); - $app->post('/repost', function() use($app) { if($user=require_login($app)) { $params = $app->request()->params(); @@ -530,6 +482,47 @@ $app->post('/micropub/post', function() use($app) { } }); +$app->post('/micropub/multipart', function() use($app) { + if($user=require_login($app)) { + // var_dump($app->request()->post()); + // + // Since $app->request()->post() with multipart is always + // empty (bug in Slim?) We're using the raw $_POST here. + // PHP empties everything in $_POST if the file upload size exceeds + // that is why we have to test if the variables exist first. + + $file = isset($_FILES['photo']) ? $_FILES['photo'] : null; + + if($file) { + $error = validate_photo($file); + + unset($_POST['null']); + + if(!$error) { + $file_path = $file['tmp_name']; + correct_photo_rotation($file_path); + $r = micropub_post_for_user($user, $_POST, $file_path); + } else { + $r = array('error' => $error); + } + } else { + unset($_POST['null']); + $r = micropub_post_for_user($user, $_POST); + } + + // Populate the error if there was no location header. + if(empty($r['location']) && empty($r['error'])) { + $r['error'] = "No 'Location' header in response."; + } + + $app->response()->body(json_encode(array( + 'response' => (isset($r['response']) ? htmlspecialchars($r['response']) : null), + 'location' => (isset($r['location']) ? $r['location'] : null), + 'error' => (isset($r['error']) ? $r['error'] : null), + ))); + } +}); + $app->post('/micropub/postjson', function() use($app) { if($user=require_login($app)) { $params = $app->request()->params(); diff --git a/lib/helpers.php b/lib/helpers.php index c606dab..3939708 100644 --- a/lib/helpers.php +++ b/lib/helpers.php @@ -323,3 +323,26 @@ function validate_photo(&$file) { return $e->getMessage(); } } + +// Reads the exif rotation data and actually rotates the photo. +// Only does anything if the exif library is loaded, otherwise is a noop. +function correct_photo_rotation($filename) { + if(class_exists('IMagick')) { + $image = new IMagick($filename); + $orientation = $image->getImageOrientation(); + switch($orientation) { + case IMagick::ORIENTATION_BOTTOMRIGHT: + $image->rotateImage(new ImagickPixel('#00000000'), 180); + break; + case IMagick::ORIENTATION_RIGHTTOP: + $image->rotateImage(new ImagickPixel('#00000000'), 90); + break; + case IMagick::ORIENTATION_LEFTBOTTOM: + $image->rotateImage(new ImagickPixel('#00000000'), -90); + break; + } + $image->setImageOrientation(IMagick::ORIENTATION_TOPLEFT); + $image->writeImage($filename); + } +} + diff --git a/public/js/script.js b/public/js/script.js index ea86931..50496d3 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -15,7 +15,11 @@ } function csv_to_array(val) { - return val.split(/[, ]+/); + if(val.length > 0) { + return val.split(/[, ]+/); + } else { + return []; + } } diff --git a/views/dashboard.php b/views/dashboard.php index b5c4aa3..a20a44b 100644 --- a/views/dashboard.php +++ b/views/dashboard.php @@ -8,7 +8,6 @@
  • -
  • diff --git a/views/layout.php b/views/layout.php index f853edd..da97687 100644 --- a/views/layout.php +++ b/views/layout.php @@ -69,7 +69,6 @@ if(property_exists($this, 'include_facebook')) {
  • Note
  • Bookmark
  • Favorite
  • -
  • Photo
  • Docs
  • diff --git a/views/new-post.php b/views/new-post.php index 532a5ca..6c76f51 100644 --- a/views/new-post.php +++ b/views/new-post.php @@ -10,20 +10,27 @@
    - +
    - +
    - +
    +
    + + +
    + +
    +
    @@ -72,7 +79,7 @@ test_response): ?>

    Last response from your Micropub endpoint (response_date) ?>)

    -
    test_response) ?>
    +
    test_response) ?>
    @@ -105,13 +112,13 @@
    \ No newline at end of file