0

I've recently managed to successfully plug the very cool Valums File Upload Plugin into an application I’m currently working on with the purpose being to upload images. I now need to modify the server side PHP scripting of this plugin to do some image manipulation (re-sizing, watermarking, thumbnail creating..etc) which I’ve been able to do before using procedural style coding, but looking at the way the upload handling is done in the valums plugin it’s all OOP.

So I’ve spent some time recently trying to get my head around OOP programing styles and I think I get the basics, but I could really use some pointers (I'm NOT asking for someone to do this for me) as to how to implement what I want to do into the existing code, things like where should my image manipulation methods go, how to get a handle on the uploaded file.

The complete code for the server side handling can be found here, but as a overview it goes a bit like this (sorry it's still quite long):

<?php

/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {

    function save($path) {
        $input = fopen("php://input", "r");
        $temp = tmpfile();
        $realSize = stream_copy_to_stream($input, $temp);
        fclose($input);

                // REMOVED VALIDATION

        $target = fopen($path, "w");
        fseek($temp, 0, SEEK_SET);
        stream_copy_to_stream($temp, $target);
        fclose($target);

        return true;
    }
    function getName() {
        return $_GET['qqfile'];
    }
    function getSize() {
            // REMOVED
    }
}

/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {

    function save($path) {
        if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
            return false;
        }
        return true;
    }
    function getName() {
        return $_FILES['qqfile']['name'];
    }
    function getSize() {
        return $_FILES['qqfile']['size'];
    }
}

class qqFileUploader {
    private $allowedExtensions = array();
    private $sizeLimit = 10485760;
    private $file;

    function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
        $allowedExtensions = array_map("strtolower", $allowedExtensions);

        $this->allowedExtensions = $allowedExtensions;
        $this->sizeLimit = $sizeLimit;

        $this->checkServerSettings();

        if (isset($_GET['qqfile'])) {
            $this->file = new qqUploadedFileXhr();
        } elseif (isset($_FILES['qqfile'])) {
            $this->file = new qqUploadedFileForm();
        } else {
            $this->file = false;
        }
    }

    private function checkServerSettings(){
            // REMOVED
    }

    private function toBytes($str){
            // REMOVED
    }

    /**
* Returns array('success'=>true) or array('error'=>'error message')
*/
    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){

        // REMOVED VALIDATION

        $pathinfo = pathinfo($this->file->getName());
        $filename = $pathinfo['filename'];
        //$filename = md5(uniqid());
        $ext = $pathinfo['extension'];

                // REMOVED VALIDATION

        if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
            return array('success'=>true);
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }

    }
}


$allowedExtensions = array("jpeg","jpg","bmp");
// max file size in bytes
$sizeLimit = 10 * 1024 * 1024;

$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

?>

To clarify, I’m not after spoon feeding, but I’m struggling to get my head around where to start and seeing as I’m on a steep learning curve I don’t really want to set off down the wrong path. I could probably turn this into procedural code but I think this is a good opportunity to learn OOP properly.

Any help is greatly appreciated.

Dan

1 Answer 1

2
+100

What I would try is extending the class qqFileUploader. So in psuedo code:

class myClass extends qqFileUploader{

    function handleUpload(){

    }

}

Then use that handleUpload function to override what's currently being done in that function (i.e. resizing, watermarking, etc).

UPDATE: As I was looking closer at the question, it occurred to me that you may not mind editing the source code. I'm used to trying not to hack the core (using joomla, wordpress, etc).

For what you're wanting to do (intercept the file before it gets saved) you'll want to insert your code in the handleUpload function between the if(!$replaceOldFile) statement and the if ($this->file->save($uploadDirectory . $filename . '.' . $ext)) statement.

The variable $this->file is the file you're wanting to edit. That's the file you want to work your magic on. You can create your own custom functions if you want just by adding the function to the qqFileUploader class, then calling it by using $this->yourFunction().

I hope this is can help you. If you have any more questions, I'll try to answer them.

SECOND UPDATE: Here's an example of how you can manipulate the data before you save it. I just used turning the image to grayscale as an example, but you can do whatever you like. This code is to be put where I mentioned earlier, between the 2 if statements.

$image = 'uploads/'.$this->file->getName();

    $im = imagecreatefrompng($image);
    if($im && imagefilter($im, IMG_FILTER_GRAYSCALE)){
        echo 'Image converted to grayscale.';
        imagepng($im, $image);
    }else{
        echo 'Conversion to grayscale failed.';
    }
    imagedestroy($im);

Then you'd change this:

if ($this->file->save($uploadDirectory . $filename . '.' . $ext))

to this:

if ($this->file->save($uploadDirectory . $im))

I just tested this, so I know it will work for you. Also, I used png instead of jpeg, but that's just because I had png's lying around :)

Sign up to request clarification or add additional context in comments.

5 Comments

Hi John, any chance of a little more nudge in the right direction? I'm not entirly sure how to get a handle on the uploaded image so I can start playing with it. I tried extending the qqFileUploader class and using $this->file with not much success.
Hi John, Thanks for your reply. As a test I added $ImageHandle = imagecreatefromjpeg($this->file); where you suggested and I get a horrible error saying "Object of class qqUploadedFileXhr could not be converted to string". I'm starting to think I've bit off more than I can chew here!
To manipulate that file, you'll probably want to use the getName() function. So instead of $ImageHandle = imagecreatefromjpeg($this->file); you'd use $ImageHandle = imagecreatefromjpeg($this->file->getName());. You'll see that in the classes above the one you're using there are functions with the name getName(), and you can use that. You could even create another function up there and call it by using $this->file->yourFunction().
Hey Dan, Check out the second update, it should make things a bit clearer.
I can't thank you enough! Worked perfectly, hopefully I can expand on this and start doing some proper OOP style code to reach my final goal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.