3
votes

I'm following a Lynda.com course for CakePHP 2.4.0 and per the material the following code should work but fails with the latter error message:

    public $validate = array(
        'publication_name' => array(
            'words' => array(
                'rule' => array('custom', '/([\w.-]+ )+[\w+.-]/'),
                'message' => 'The publication name can only contain letters, numbers and spaces.',
            )
        ),
    );

"preg_match(): Delimiter must not be alphanumeric or backslash [CORE/Cake/Model/Validator/CakeValidationRule.php, line 281]".

Per my searching, the regex should work as it is using a non-alphanumeric delimiter (/). I'm quite perplexed to say the least.

The only way I have been able to get it to successfully save the record is by removing the custom validation rule (which is not the desired result for a variety of reasons).

Any insight on why this is failing validation? I've diff'd my code against that of the author's exercise files and am not sure what I'm (most likely) over looking...

Thank you in advance for your time and insight. I truly appreciate it.

Source Code for Model, View and Controllers: http://tny.cz/0a995577

1
And you are using CakePHP 2.4.0? In that case, the rule you are showing there would normally never be processed on Line 281 of CakeValidationRule.php, that's were rules like 'words' => 'string value' are processed. The regex is totally fine (syntax wise), it must be something else. You'll need to show some more of the involved code, controller action, model, etc...ndm
I'm going to diff my project files against that of the author's code now. I've been using cake bake, which shows that it's using the app/Console/bake for 2.4.0, but I also have an installation of 2.4.1 so I may have accidentally baked some code using the wrong bake console... I will update this shortly. Thanks for the quick response.DroBuddy
Pastebin is currently offline due to load, so here is an alternative that shows the full source for the Model, App Controller and Publications Controller, and Add View. tny.cz/0a995577 I'm more than glad to provide any other source code as necessary in order to determine why the rule is failing. Thanks again.DroBuddy
Oddly enough, the validation was failing due to isUnique being spelled incorrectly. However, due to the regex directly above the isUnique rule I had assumed it was the custom rule the was failing. With that error being fixed, it no longer shows the preg_match error message. Although, the custom rule is still providing the validation error message and is failing to save to the DB.DroBuddy
I used Meld to diff the entire project files against the author's source code and there is no difference between either of them. Furthermore, I did the diff from the root directory structure (including app/lib/vendors/plugins, et al) in the diff to ensure that there wasn't a version difference due to accidentally using the wrong cake bake console and it still fails validation. I'm sure this is something incredibly simple that I'm overlooking (as it has happened all too often in the past) but I'm not sure what the next step would be in the debug process. :(DroBuddy

1 Answers

2
votes

As pointed out in the comments, the regex itself is syntactically correct, so it won't cause such an error. As you figured it was a typo in a different rule causing the problem.

However the rule also won't validate as expected (http://regex101.com/r/dA0pH9), as the regex matches one or more words (including . and -) separated by a single space, followed by a single word char (again including . and -). Also it allows to prepend and append arbitrary chars, as it doesn't make use of ^ and $.

To make it match your requirements

one word, multiple words, including numbers and spaces

try something like this:

/^(\w ?)+(?<! )$/

That would match one or more words (which may consist of numbers only, and may be only 1 char in length), separated by a space, not allowing a trailing space.

Though it would also match something like 1 2 3 4 5 (http://regex101.com/r/kK3jG9/), which might not be applicable, so you may want to refine it, for example by requiring at least 1 letter per word, with a minimum length of 3 chars:

/^((?=\d*[a-z])\w{3,} ?)+(?<! )$/i

A quick breakdown:

(
  (?=\d*[a-z])  # the word must contain at least one letter
  \w{3,} ?      # a word with at least 3 chars, optionally followed by a space
)+              # one or more times
(?<! )          # no trailing space allowed