Problem with preg_match in custom validator

I have an ajax validator with a preg_match that matches a google drive video url.

    ['drive_url', function ($attribute, $params, $validator) {
        $pattern = '%https:\/\/drive\.google\.com\/file\/d\/([a-zA-Z0-9_-]+)\/view\?usp=sharing%';
        if (preg_match($pattern, $this->$attribute) != 1) {
            $this->addError($attribute, 'Incorrect format for a Google Drive video url. Ensure you copied the link from the video preview window in your Google Drive account.');
        }
    }],

The validator works fine, but the new record will not save. If I replace $this->$attribute in the preg_match with the actual input string, then it will save. But as written it doesn’t save, as if it’s failing validation, although it’s actually passing validation.

Are you sure that the value of $this->$attribute matches the actual input string?

Yes. I’m copying and pasting the same url. And the validation will display the error message if it’s not in the right format. I’ve tried many different things to get this to work. Very strange behavior…

It seems like preg_match is changing $attribute somehow. It also works if I just remove the preg_match.

Incidentallyl, I have another preg_match after post and before save to put it into the right format. This one isn’t giving any trouble at all.

    $this->drive_url = 
        preg_match('%https:\/\/drive\.google\.com\/file\/d\/([a-zA-Z0-9_-]+)%', $this->drive_url, $match) ? $match[0] . '/preview' : 
        NULL;

The initial code cannot change the value. It is a match, not replace. The condition is a bit weird though. Should be if !preg_match instead of comparing with -1.

Thanks. I changed it to if(!preg_match…)

I think I figured this out. I’m checking the validation prior to the second preg_match listed above. Then the preg_match changes $this->drive_url so it no longer matches the validation. Then $this-save() is checking the validation again, causing it to fail. I changed it to $this->save(false), and it works.

I would be embarrassed to say how much time I’ve spent on this…