diff --git a/dibi/dibi.php b/dibi/dibi.php index 081dba46..c200674c 100644 --- a/dibi/dibi.php +++ b/dibi/dibi.php @@ -134,7 +134,7 @@ class dibi public static $substs = array(); /** @var callback Substitution fallback */ - public static $substFallBack; + public static $substFallBack = array(__CLASS__, 'defaultSubstFallback'); /** @var array @see addHandler */ private static $handlers = array(); @@ -647,6 +647,18 @@ class dibi + /** + * Default substitution fallback handler. + * @param string + * @return mixed + */ + public static function defaultSubstFallback($expr) + { + throw new InvalidStateException("Missing substitution for '$expr' expression."); + } + + + /********************* misc tools ****************d*g**/ diff --git a/dibi/libs/DibiTranslator.php b/dibi/libs/DibiTranslator.php index 2a61ed12..5d5c8711 100644 --- a/dibi/libs/DibiTranslator.php +++ b/dibi/libs/DibiTranslator.php @@ -121,14 +121,14 @@ final class DibiTranslator extends DibiObject (?: `(.+?)`| ## 1) `identifier` \[(.+?)\]| ## 2) [identifier] - (\')((?:\'\'|[^\'])*)\'| ## 3,4) string + (\')((?:\'\'|[^\'])*)\'| ## 3,4) 'string' (")((?:""|[^"])*)"| ## 5,6) "string" (\'|")| ## 7) lone quote - :(\S*?:)| ## 8) substitution - %([a-zA-Z]{1,4})(?![a-zA-Z]) ## 9) modifier + :(\S*?:)([a-zA-Z0-9._]?)| ## 8,9) substitution + %([a-zA-Z]{1,4})(?![a-zA-Z]) ## 10) modifier )/xs', */ // note: this can change $this->args & $this->cursor & ... - . preg_replace_callback('/(?=[`[\'":%])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)|%([a-zA-Z]{1,4})(?![a-zA-Z]))/s', + . preg_replace_callback('/(?=[`[\'":%])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z]{1,4})(?![a-zA-Z]))/s', array($this, 'cb'), substr($arg, $toSkip) ); @@ -357,7 +357,7 @@ final class DibiTranslator extends DibiObject } else { return substr($value, 0, $toSkip) . preg_replace_callback( - '/(?=[`[\'":])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:))/s', + '/(?=[`[\'":])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?))/s', array($this, 'cb'), substr($value, $toSkip) ); @@ -418,10 +418,11 @@ final class DibiTranslator extends DibiObject // [6] => string // [7] => lone-quote // [8] => substitution - // [9] => modifier (when called from self::translate()) + // [9] => substitution flag + // [10] => modifier (when called from self::translate()) - if (!empty($matches[9])) { // modifier - $mod = $matches[9]; + if (!empty($matches[10])) { // modifier + $mod = $matches[10]; $cursor = & $this->cursor; if ($cursor >= count($this->args) && $mod !== 'else' && $mod !== 'end') { @@ -501,7 +502,9 @@ final class DibiTranslator extends DibiObject } if ($matches[8]) { // SQL identifier substitution - return $this->subCb(array(1 => substr($matches[8], 0, -1))); + $m = substr($matches[8], 0, -1); + $m = isset(dibi::$substs[$m]) ? dibi::$substs[$m] : call_user_func(dibi::$substFallBack, $m); + return $matches[9] == '' ? $this->formatValue($m, FALSE) : $m . $matches[9]; // value or identifier } die('this should be never executed'); @@ -536,15 +539,7 @@ final class DibiTranslator extends DibiObject private static function subCb($m) { $m = $m[1]; - if (isset(dibi::$substs[$m])) { - return dibi::$substs[$m]; - - } elseif (dibi::$substFallBack) { - return dibi::$substs[$m] = call_user_func(dibi::$substFallBack, $m); - - } else { - return $m; - } + return isset(dibi::$substs[$m]) ? dibi::$substs[$m] : call_user_func(dibi::$substFallBack, $m); } } diff --git a/examples/table-prefix.php b/examples/substitutions.php similarity index 75% rename from examples/table-prefix.php rename to examples/substitutions.php index 5e09243a..d50a2ff3 100644 --- a/examples/table-prefix.php +++ b/examples/substitutions.php @@ -36,10 +36,14 @@ dibi::test("UPDATE [database.::table] SET [text]='Hello World'"); // create substitution fallback function substFallBack($expr) { - return 'the_' . $expr; + if (defined($expr)) { + return constant($expr); + } else { + return 'the_' . $expr; + } } dibi::setSubstFallBack('substFallBack'); -dibi::test("UPDATE [:account:user] SET [name]='John Doe'"); -// -> UPDATE [the_accountuser] SET [name]='John Doe' +dibi::test("UPDATE [:account:user] SET [name]='John Doe', [active]=:true:"); +// -> UPDATE [the_accountuser] SET [name]='John Doe', [active]=1