Calvin
Calvin

Reputation: 4619

Trying to understand the code for the MeioUpload behavior for CakePHP

I was reading through the source code for MeioUpload to make sure I understand what it's doing, and for the most part the code is pretty easy to understand. However, I came upon a section of code which I just can't seem to figure out, and so I'm trying to determine if it's a mistake on the author's part or if I'm just missing something.

Essentially, this function is passed the filename of a default image, and adds that filename to a list of reserved words (and generates a replacement string for it). I have put an arrow and question marks (in comments) next to the line of code I can't figure out:

/**
 * Include a pattern of reserved word based on a filename, 
 * and it's replacement.
 * @author Vinicius Mendes
 * @return null
 * @param $default String
 */
function _includeDefaultReplacement($default){
    $replacements = $this->replacements;
    list($newPattern, $ext) = $this->splitFilenameAndExt($default);
    if(!in_array($newPattern, $this->patterns)){
        $this->patterns[] = $newPattern;
        $newReplacement = $newPattern;
        if(isset($newReplacement[1])){ // <--- ???
            if($newReplacement[1] != '_'){
                $newReplacement[1] = '_';
            } else {
                $newReplacement[1] = 'a';
            }
        } elseif($newReplacement != '_') {
            $newReplacement = '_';
        } else {
            $newReplacement = 'a';
        }
        $this->replacements[] = $newReplacement;
    }
}

As I understand it, $newReplacement should always be a string, not an array. That is because ultimately it gets its value from the first element of the array returned from this function:

function splitFilenameAndExt($filename){
    $parts = explode('.',$filename);
    $ext = $parts[count($parts)-1];
    unset($parts[count($parts)-1]);
    $filename = implode('.',$parts);
    return array($filename,$ext);
}

So that if() statement makes no sense to me. It seems to be trying to catch a condition which could never occur. Or am I wrong and that section of code does serve a purpose?

Upvotes: 0

Views: 1004

Answers (2)

Calvin
Calvin

Reputation: 4619

Chad Birch has already answered my question (my original confusion was due to not understanding that $var[n] can be used to find the nth character of a string.), but just in case others are wondering, here's an explanation of what these functions are trying to accomplish:

MeioUpload is a file/image upload behavior for CakePHP. Using it, you can set any field in your model to behave as an upload field, like so:

var $actsAs = array(
    'MeioUpload' => array(
        'picture' => array(
            'dir' => 'img{DS}{model}{DS}{field}',
            'create_directory' => true,
            'allowed_mime' => array('image/jpeg', 'image/pjpeg', 'image/png'),
            'allowed_ext' => array('.jpg', '.jpeg', '.png'),
            'thumbsizes' => array(
                'normal' => array('width'=>180, 'height'=>180),
                'small' => array('width'=>72, 'height'=>72)
            ),
            'default' => 'default.png'
        )
    )
);

In the above example, MeioUpload will treat the field named "picture" as an upload field. This model happens to be named "product," so the upload directory would be "/img/product/picture/." The above configurations also specify that 2 thumbnails should be generated. So if I were to upload an image named "foo.png", the following files would be saved on the server:

/img/product/picture/foo.png
/img/product/picture/thumb.foo.png *
/img/product/picture/thumb.small.foo.png

* - thumbsizes labeled 'normal' do not have their key appended to their filenames

Additionally, the default images are also stored in the same directory:

/img/product/picture/default.png
/img/product/picture/thumb.default.png
/img/product/picture/thumb.small.default.png

But since we don't want the user-uploaded images, default images, or auto-generated thumbnails to overwrite one another, the author has created the following pair of arrays:

var $patterns = array(
    "thumb",
    "default"
);

var $replacements = array(
    "t_umb",
    "d_fault"
);

which are used to prevent filename conflicts when saving uploaded files:

$filename = str_replace($this->patterns,$this->replacements,$filename);

_includeDefaultReplacement() is used to add new reserved words when the default image is named something else.

Upvotes: 0

Chad Birch
Chad Birch

Reputation: 74518

Well, I can't explain the actual reasoning behind why it's doing it, but when you use a particular index on a string value like that, you're accessing a particular character of the string. That is, it's checking whether the filename has a second character, which it then replaces with either '_' or 'a'. If the filename is only one character long, it replaces the whole thing with either '_' or 'a'.

I can explain in more detail what that function does if you like, but I don't really have any understanding of what it's trying to accomplish.

Upvotes: 1

Related Questions