On Thu, Feb 24, 2011 at 3:43 AM, Greg Skerman <[email protected]> wrote:
> Hi,
>
> I've been working on a very simple app to upload and resize some images, and
> name the file in accordance with some information that has been provided in
> a form.
>
> To do this, my model has a public method "createFilename", which relies on
> $this->data to build the filename in accordance with the provided business
> rules.
>
> It was all working fine, until I connected the model to a database table and
> started also saving the meta-data.... now it appears $this->data is being
> unset for subsequent calls to the method.
>
> The method is simple enough:
>
> public function createFilename() {
>
>         CakeLog::write('debug', 'photo name is '.
> $this->data['Photo']['name']);
>
>         $name = $this->data['Photo']['name'];
>
>         $level = $this->data['Photo']['level'];
>
>         $category = $this->data['Photo']['category'];
>
>         $month = strtoupper($this->data['Photo']['month']);
>
>
>         return $level . $category . $month . $name . '.jpg';
>
> }
>
>
> According to the information that I log, in the 4 times this method is
> called during the processing of the image, the first time
> $this->data['Photo']['name']  contains data, and then each subsequent call
> is empty.
>
> The first time the method is called is at validation to prevent duplicate
> files with the same metadata being created, and this seems to be working
> fine, but then the following times (which are used for naming the file after
> it has been manipulated, moving the file out of the TMP directory into the
> uploaded images directory, and including the filename in an email
> attachment, $this->data appears to be empty.

I realise, from your other post, that you're not doing calling that
method repeatedly anymore. It's really inefficient to do that.

The way I've approached this is to use a FileHandlerComponent and
ImageHandlerComponent. Any controller that deals with an upload calls
__handleUpload() after saving the record. The first component deals
with moving the file to the correct location and the second with
resizing. I split them into separate components because I deal with a
lot of non-image uploads.

Example from FilesController:

private function __handleImageUpload()
{
        $this->FileHandler->setModelName('Link');
        $this->FileHandler->setBase(WWW_ROOT);
        $this->FileHandler->setSubDirectory('files/links');
        
        if ($this->FileHandler->upload('upload', false))
        {
                $upload_data = $this->FileHandler->getUploadData();
                
                /* create a reasonably-sized image
                 */
                if (!empty($upload_data))
                {                               
                        /* resize if necessary
                         */
                        $img_data = $this->ImageHandler->apply(
                                array_merge($this->Link->image_settings, 
array('basename' =>
$upload_data['basename'])),
                                
$this->FileHandler->getBase().$upload_data['directory'].DS.$upload_data['basename'],
                                
$upload_data['directory'].DS.$upload_data[0]['basename']
                        );

                        /* Save image details
                         */
                        if (is_array($img_data) && !empty($img_data))
                        {
                                $data = array(
                                        'Link' => array(
                                                'id' => $this->Link->id,
                                                'directory' => 
$upload_data[0]['directory'],
                                                'basename' => 
$img_data['basename'],
                                                'extension' => 
$img_data['extension'],
                                                'type' => $img_data['type'],
                                                'size' => $img_data['size'],
                                                'width' => $img_data['width'],
                                                'height' => $img_data['height']
                                        )
                                );
                                
                                /* see if there's already an image
                                 */
                                $old_image = $this->Link->find(
                                        'first',
                                        array(
                                                'conditions' => array('id' => 
$this->Link->id),
                                                'recursive' => -1
                                        )
                                );
                                
                                if ($this->Link->save($data, false))
                                {
                                        if 
(isset($old_image['Link']['basename']))
                                        {
                                                
unlink(WWW_ROOT.$old_image['Link']['directory'].DS.$old_image['Link']['basename']);
                                        }
                                }


The model var $image_settings contains things like the maximum width &
height, etc.

Dealing with existing images (whether to overwrite, how to re-name)
could also be done within the component, as long as the model save is
also done there (because you don't want to unlink a file if the new
record didn't save).


> Does the act of saving a record to the database automatically unset the
> $this->data variable or is there something else going on here?

Only for the model. The controller's data is still available.

-- 
Our newest site for the community: CakePHP Video Tutorials 
http://tv.cakephp.org 
Check out the new CakePHP Questions site http://ask.cakephp.org and help others 
with their CakePHP related questions.


To unsubscribe from this group, send email to
[email protected] For more options, visit this group at 
http://groups.google.com/group/cake-php

Reply via email to