Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Shane McC
Shane McC
3,005 Points

Validation to upload photo isn't working

I've created a form using primary regular HTML (syntax below). When I use the laravel 4 built in function fails(), it works. When I use the laravel 4 built in function passes(). My app is saying no file chosen. My syntax is below, what am I doing wrong? Thanks

<?php

// the syntax below won't allow the image to upload. Its giving me an error     
$rules = array(
            /*'title' => 'required|max:90|min:3'*/
            /*'image' => 'required|image|mimes:jpg, jpeg, bmp, png'*/
        );

        $validator = Validator::make(Input::all(), $rules);

        if($validator->passes()){
            return Redirect::route('upload-image-post')
                ->withErrors($validator)
                ->withInput();
        } 
<?php

// the syntax below will let the image upload
        $rules = array(
            /*'title' => 'required|max:90|min:3'*/
            /*'image' => 'required|image|mimes:jpg, jpeg, bmp, png'*/
        );

        $validator = Validator::make(Input::all(), $rules);

        if($validator->fails()){
            return Redirect::route('upload-image-post')
                ->withErrors($validator)
                ->withInput();
        } 

Image upload form

 <form action="{{ URL::route('upload-image-post') }}" method="post" enctype="multipart/form-data">

        <div class="field">
            <label>Title:</label>
            <input type="text" name="title"{{ (Input::old('title')) ? ' value="' . e(Input::old('title')) . '"' : '' }}>
            @if($errors->has('title'))
                {{ $errors->first('title') }}
            @endif
        </div>


        <div class="field">
            <label>Select image to upload:</label>
            <input type="file" name="image" >
            <input type="submit" value="Upload Image" name="submit">
            @if($errors->has('image'))
                {{ $errors->first('image') }}
            @endif
        </div>

        {{ Form::token() }}

    </form>

1 Answer

Just to be sure - in the code you've commented out your validation rules within your array. Is this on purpose?

I've copied in the code from the Laravel validator class below. You can find it at:

vendor/laravel/framework/src/illuminate/Validation/Validator.php

<?php

    /**
     * Determine if the data passes the validation rules.
     *
     * @return bool
     */
    public function passes()
    {
        $this->messages = new MessageBag;

        // We'll spin through each rule, validating the attributes attached to that
        // rule. Any error messages will be added to the containers with each of
        // the other error messages, returning true if we don't have messages.
        foreach ($this->rules as $attribute => $rules)
        {
            foreach ($rules as $rule)
            {
                $this->validate($attribute, $rule);
            }
        }

        return count($this->messages->all()) === 0;
    }

    /**
     * Determine if the data fails the validation rules.
     *
     * @return bool
     */
    public function fails()
    {
        return ! $this->passes();
    }

As you can see, the fails() method calls passes() - so there shoudn't be any difference in Laravel behavior. Right now you're saying "If validation fails, redirect back to the form with input and errors". But you're also saying the same thing if the validation passes:

<?php

        if($validator->passes()){
            return Redirect::route('upload-image-post')
                ->withErrors($validator)
                ->withInput();
        } 

Surely if the validation passes, there are no errors (because it's passed!) and it wouldn't make sense to redirect back to the form with errors because this is the same behavior you have for failure... You're hitting your redirect back to the form because the validator has passed, and this qualifies for the 'if' block.

You could try:

<?php

        if ( ! $validator->passes()) {

        // which is the same as 

        if ($validator->fails()) {

            return Redirect::route('upload-image-post')
                ->withErrors($validator)
                ->withInput();

       }


        // and then

        if($validator->passes()){
            return Redirect::route('somewhere.totally.valid');
        } 

If your rules are commented out in your actual code and you didn't enter a file to submit the form, this would be why you're getting back the message "no file chosen". I.e. you haven't entered any input for the file upload AND you rules are commented out so not choosing a file is not invalid. In other words, Laravel said "Oh hey, this file is missing, but this person doesn't require this file in the set of rules. I'll add it to the messages object but won't mark this validation as invalid".

If you uncomment your rules, you should hit the 'required' validation. When you upload a file, you should be redirected to your success page.

Hope that solves it!

Shane McC
Shane McC
3,005 Points

Tom Cawthorn

If you uncomment your rules, you should hit the 'required' validation. When you upload a file, you should be redirected to your success page.

Thanks, I appreciate your help. I see what you've done there. I should have figured that out by myself but I had a brain fart.

Just to be sure - in the code you've commented out your validation rules within your array. Is this on purpose?

I did do that on purpose because I was having trouble with the validation rules, more specifically the mimes types. I'll try and figure these rules out as I move forward but if I run into some headwinds I'll post my question here. Thanks again

No worries! Glad it helped.