phpCF - Rules ------------- How do the rules work? ---------------------- The rule system introduced in version 0.5 is very powerful, while still being simple and elegant. The rules reside in rules/ by default and ar regular text files with the extension ".rules". phpCF scans the rules dir for files with that extension and parses those. This allows for the creation of rule sets that are split up into different files. This structure allows for future implementation of rule repositories that are automatically updated by phpCF. Syntax of a .rules file ----------------------- The rule definitions have a special syntax. The rules are defined by 5 fields separated by ' ;; ' (the spaces around the semi-colons must be included). The fields that make up a rule are: - label: A unique name for the rule (used in logs). - type: Rule type. As of version 0.5 it can be 'regex', 'regex_count' or 'php'. For an explanation of these types see below. - applies to: What part of a post the rule is applied to. As of version 0.5 it can be 'body', 'email' and 'ip'. - score: Score this many points if the rule matches (and in the case of regex_count, score this many points per match). - rule: A PHP PCRE (see: http://php.net/pcre) or, in the case of the type of rule being 'php', the name of the support function to call. The Rule Types: --------------- The rule types (regex, regex_count and php) are easilly explained. The regex type is a rule that is looking for a match defined by a regex pattern. If the match is found a fixed score is added to the total score. The regex_count type works like the regex type, but scores per match found instead of just scoring once. This is great when checking for e.g. the number of URLs in a post. The php type is by far the most powerful and uses a custom written php function to do the checking. (More on this later.) An example of a rule could be: urls_light ;; regex_count ;; body ;; 0.5 ;; /(ht|f)tp(s?)\:\/\//msi This rule is an actual rule from the default rule set and it simply counts the number of occurences of the pattern described in the rule field (the last field) and scores 0.5 points per match. In this case we're checking the message body for occurences of 'http', 'https', 'ftp' and 'ftps' - i.e. URLs. Had the rule type been 'regex' a post containing 4 URLs would score only 0.5 points, since 'regex' is just applying the score once in case of a match. 'regex_count' however would award 2.0 points for 4 URLs. Support Files ------------- The rule type 'php' is special, in that it allows (requires!) the rule author to write a custom PHP function to support the rule. Such support functions are put in a separate file and placed in support/ inside the rules dir. A support file should ALWAYS be named after the rule set it's supporting, so the support file for the main set (main.rules) is placed in support/ and named main.support.php. The double extension (.support.php) is required by phpCF - omitting either extension will result in the file not being read. Support files (like rule sets) can hold multiple definitions (e.g. see rules/support/main.support.php). Creating a supported rule is easy. Here's an example of a dummy rule that uses PHP to check the body for any occurence of the word 'hamock' and scores 7.5 points if it occurs. First, add a 'php' type rule in your rule set (eg. personal.rules): hamock ;; php ;; body ;; 7.5 ;; hamock Then create a support file for your rule set (personal.support.php) and put it in support/ in the rules dir. Now add a PHP function called 'hamock' in the support file: function hamock ($score, $target, $parent) { if stristr($target, "hamock") { return $score; } else { return 0; } } You may notice that your custom function MUST take 3 arguments. These arguments are: $score, $target and $parent. $score is the number of points you gave this rule in the rule set (i.e. 7.5 points), and $target is the part of the post the rule should be applied to (in this case the $target holds the content of the body of the post). $parent is a bit more tricky - this is a reference to the instance of the phpCF-class that is calling this function, hence we can do stuff like: $parent->debug("This is a debug message from my custom function."); And since we're developing, we like debugging, so let's add that to the hamock check: function hamock ($score, $target, $parent) { if (stristr($target, "hamock")) { $parent->debug("hamock: Found hamock! (+{$score})") return $score; } else { return 0; } } This supported rule is of course a bit stupid, since it could be done way easier with a simple "regex" rule: hamock ;; regex ;; body ;; 7.5 ;; /hamock/msi But still, the example should provide enough explanation to start writing support rules. Questions and feedback: ----------------------- Anders K. Madsen http://lillesvin.net