How are you all working round the fact that pics uploaded from an iphone are 90 degrees rotated on elgg?

Hi - after a couple of days' researching I can see that anyone who runs blogs/social sites has dealt with the fact that most iphones, most of the time, do not upload images that show with the correct orientation when posted on the site. The workarounds can be backend (I've read about Drupal solutions - too complicated for me), I've read about solutions written into apps (such as Poster for Wordpress and the mobile solutions for PHPfox), and I've read about on-site solutions - where you can rotate the image once it has been uploaded. But there is nothing in elgg that I can find that deals with this - at a plugin or an app level (I can only find one iOS app for elgg). So there must be a workaround that you are all using that I am missing - could you please share it? Or perhaps explain why it isn't a natural inclusion in the core, in TinyMCE or tidypics etc? Thanks so much. P

  • 1.7 is extremely outdated at this point. Efforts would be better spent migrating to 1.8.

    You can try to merge the PR's diff into 1.7, but it will probably require manually resolving conflicts.

  • I missed that changes in filestore.php are part of the PR. The link Pawel posted points to the PR I was referring to. It should be possible to backport the image orientation fix to Elgg 1.7. There hasn't changed that much in filestore.php and I think in the file plugin file the changes to be made are also quite the same. Modifying core files is surely not the recommended way - and trying to make an update to Elgg 1.8 as soon as possible is surely the better way (but I'm working since two years on this task for my site already and I'm also not yet done).

    It would also be possible to include the whole image orientation correction directly into the file plugin upload action. But the advantage of modiying filestore.php is that the image orientation correction will also work for user profile images and group profile images and not only for images uploaded with the files plugin.

  • I used that method in the PR to fix the file plugin in a custom site in 1.8 prior to pushing for it to be in core - so it can be done.  It's just much cleaner in core as it works for all fields.

    Going back to 1.7, should still be doable, but I agree with the assertion that effort should be put into upgrading instead.

  • @Matt Beckett I completely agree I should've made the jump to 1.8 a longtime ago but I've spent a great deal of time developing for 1.7 and to make all the necessary changes would take me forever. I'm a team of one right now and I'm trying to make this ELGG site into an android app (pretty excited about it). This orientation problem is the last piece of dev for ELGG, the rest is in android (android dev sucks BTW. if anyone has done it before you know what I'm taking about). Anyway can I just Copy n Paste the work you've done for image orientation in the filestore? Knowing what I need to change from 1.8/1.9 to 1.7 is the difficult part.

  • Yeah if you want to implement it in 1.7 core (and understand the implications) it is most likely just a copy/paste job - maybe some compatibility tweaks (I haven't looked at 1.7 code in a long time)

    If it's just the file plugin you're concerned about then you can do it a little more locally in a plugin - hooking into the action and rotating the images in the $_FILES global before the action does its thing

  • Thanks! Ill give it a shot and Let you know how it goes. Im going to try it in the core first because if I can get it to work there then great but if not ill just try it in the action of the file plugin.

  • ok so Ive been working on this and I keep getting

    "Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 13056 bytes) in ...engine/lib/filestore.php on line 867"

  • @stuartsloan You have to small amount of memory allowed for php to load image of resolution that you're uploading. Try increasing limit in .htaccess file.

  • @Pawel That was it! if anyone else wants to know wthat I did I just modified mod/file/actions/upload.php

    <?php
        /**
         * Elgg file browser uploader/edit action
         *
         * @package ElggFile
         */

        global $CONFIG;
        
        gatekeeper();
        
        $exif = exif_read_data($_FILES['upload']['tmp_name'], 'IFDO', true);
    $orientation = $exif['IFD0']['Orientation'];;
    if($orientation != 0) {
          $image = imagecreatefromstring(file_get_contents($_FILES['upload']['tmp_name']));
          switch($orientation) {
               case 8:
                  $image = imagerotate($image,90,0);
                  break;
              case 3:
                 $image = imagerotate($image,180,0);
                 break;
              case 6:
                 $image = imagerotate($image,-90,0);
                 break;
           }
           imagejpeg($image, $_FILES['upload']['tmp_name']);
    }
        
        // Get variables
        $title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8');
        $desc = get_input("description");
        $access_id = (int) get_input("access_id");
        $container_guid = (int) get_input('container_guid', 0);
        if ($container_guid == 0) {
            $container_guid = get_loggedin_userid();
        }
        $guid = (int) get_input('file_guid');
        $tags = get_input("tags");
        
        // check if upload failed
        if (!empty($_FILES['upload']['name']) && $_FILES['upload']['error'] != 0) {
            // cache information in session
            $_SESSION['uploadtitle'] = $title;
            $_SESSION['uploaddesc'] = $desc;
            $_SESSION['uploadtags'] = $tags;
            $_SESSION['uploadaccessid'] = $access_id;
            register_error(elgg_echo('file:cannotload'));
            forward($_SERVER['HTTP_REFERER']);
        }
        
        // check whether this is a new file or an edit
        $new_file = true;
        if ($guid > 0) {
            $new_file = false;
        }
        
        if ($new_file) {

            // must have a file if a new file upload
            if (empty($_FILES['upload']['name'])) {
                // cache information in session
                $_SESSION['uploadtitle'] = $title;
                $_SESSION['uploaddesc'] = $desc;
                $_SESSION['uploadtags'] = $tags;
                $_SESSION['uploadaccessid'] = $access_id;
                
                register_error(elgg_echo('file:nofile'));
                forward($_SERVER['HTTP_REFERER']);
            }
            
            $file = new FilePluginFile();
            $file->subtype = "file";
            
            // if no title on new upload, grab filename
            if (empty($title)) {
                $title = htmlspecialchars($_FILES['upload']['name'], ENT_QUOTES, 'UTF-8');
            }
        
        } else {
            // load original file object
            $file = get_entity($guid);
            if (!$file) {
                register_error(elgg_echo('file:cannotload'));
                forward($_SERVER['HTTP_REFERER']);
            }
            
            // user must be able to edit file
            if (!$file->canEdit()) {
                register_error(elgg_echo('file:noaccess'));
                forward($_SERVER['HTTP_REFERER']);
            }
        }
        
        $file->title = $title;
        $file->description = $desc;
        $file->access_id = $access_id;
        $file->container_guid = $container_guid;
        
        $tags = explode(",", $tags);
        $file->tags = $tags;
        
        // we have a file upload, so process it
        

        
        if (isset($_FILES['upload']['name']) && !empty($_FILES['upload']['name'])) {
            
            $prefix = "file/";
            
            // if previous file, delete it
            if ($new_file == false) {
                $filename = $file->getFilenameOnFilestore();
                if (file_exists($filename)) {
                    unlink($filename);
                }

                // use same filename on the disk - ensures thumbnails are overwritten
                $filestorename = $file->getFilename();
                $filestorename = elgg_substr($filestorename, elgg_strlen($prefix));
            } else {
                $filestorename = elgg_strtolower(time().$_FILES['upload']['name']);
            }
            
            $file->setFilename($prefix.$filestorename);

            $mime_type = $file->detectMimeType($_FILES['upload']['tmp_name'], $_FILES['upload']['type']);

            $file->setMimeType($mime_type);
            $file->originalfilename = $_FILES['upload']['name'];
            $file->simpletype = get_general_file_type($mime_type);

            // Open the file to guarantee the directory exists
            $file->open("write");
            $file->close();
            // move using built in function to allow large files to be uploaded
            move_uploaded_file($_FILES['upload']['tmp_name'], $file->getFilenameOnFilestore());
            
            $guid = $file->save();
            
            // if image, we need to create thumbnails (this should be moved into a function)
            
            
        
            if ($guid && $file->simpletype == "image") {
                $thumbnail = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),60,60, true);
                if ($thumbnail) {
                    $thumb = new ElggFile();
                    $thumb->setMimeType($mime_type);
                    
                    $thumb->setFilename($prefix."thumb".$filestorename);
                    $thumb->open("write");
                    $thumb->write($thumbnail);
                    $thumb->close();
                    
                    $file->thumbnail = $prefix."thumb".$filestorename;
                    unset($thumbnail);
                }
                
                $thumbsmall = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),153,153, true);
                if ($thumbsmall) {
                    $thumb->setFilename($prefix."smallthumb".$filestorename);
                    $thumb->open("write");
                    $thumb->write($thumbsmall);
                    $thumb->close();
                    $file->smallthumb = $prefix."smallthumb".$filestorename;
                    unset($thumbsmall);
                }
                
                $thumblarge = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),600,600, false);
                if ($thumblarge) {
                    $thumb->setFilename($prefix."largethumb".$filestorename);
                    $thumb->open("write");
                    $thumb->write($thumblarge);
                    $thumb->close();
                    $file->largethumb = $prefix."largethumb".$filestorename;
                    unset($thumblarge);
                }
            }
        } else {
            // not saving a file but still need to save the entity to push attributes to database
            $file->save();
        }
        
        // make sure session cache is cleared
        unset($_SESSION['uploadtitle']);
        unset($_SESSION['uploaddesc']);
        unset($_SESSION['uploadtags']);
        unset($_SESSION['uploadaccessid']);
        
        // handle results differently for new files and file updates
        if ($new_file) {
            if ($guid) {
                system_message(elgg_echo("file:saved"));
                add_to_river('river/object/file/create', 'create', get_loggedin_userid(), $file->guid);
            } else {
                // failed to save file object - nothing we can do about this
                register_error(elgg_echo("file:uploadfailed"));
            }
        
            $container_user = get_entity($container_guid);
            forward($CONFIG->wwwroot . "pg/file/owner/" . $container_user->username);
        
        } else {
            if ($guid) {
                system_message(elgg_echo("file:saved"));
            } else {
                register_error(elgg_echo("file:uploadfailed"));
            }
            
            forward($file->getURL());
        }    

  • Just need to make this code also work in the mod/profile/actions/iconupload.php

    Cant seem to make this happen. anyone know why?