private function push($rule, array $args, $comment = '', $ref = '') { $s = strpos($rule, 's'); $p = strpos($rule, 'p'); $c = strpos($rule, 'c'); foreach ($args as $i => $tokens) { if (1 === count($tokens) && is_array($tokens[0]) && T_CONSTANT_ENCAPSED_STRING === $tokens[0][0]) { $args[$i] = decapse_string($tokens[0][1]); } else { $args[$i] = null; } } $key = $msgid = $args[$s]; if (!$msgid) { return null; } $entry = array('id' => '', 'source' => $msgid, 'target' => ''); if ($c && isset($args[$c])) { $entry['context'] = $args[$c]; $key .= "" . $args[$c]; } if ($ref) { $entry['refs'] = $ref; } $parse_printf = true; if ($comment) { if (preg_match('/xgettext:\\s*((?:no-)?\\w+)-format/', $comment, $r)) { if ('no-' === substr($r[1], 0, 3)) { $entry['format'] = false; } else { $entry['format'] = $r[1]; } $comment = str_replace($r[0], '', $comment); $parse_printf = false; } $entry['notes'] = loco_parse_comment($comment); } if ($parse_printf && loco_sniff_printf($msgid)) { $entry['format'] = 'php'; $parse_printf = false; } if (isset($this->reg[$key])) { $index = $this->reg[$key]; $a = array(); isset($this->exp[$index]['refs']) and $a[] = $this->exp[$index]['refs']; isset($entry['refs']) and $a[] = $entry['refs']; $a && ($this->exp[$index]['refs'] = implode(" ", $a)); $a = array(); isset($this->exp[$index]['notes']) and $a[] = $this->exp[$index]['notes']; isset($entry['notes']) and $a[] = $entry['notes']; $a && ($this->exp[$index]['notes'] = implode("\n", $a)); } else { $index = count($this->exp); $this->reg[$key] = $index; $this->exp[] = $entry; } if ($p && isset($args[$p])) { $msgid_plural = $args[$p]; $entry = array('id' => '', 'source' => $msgid_plural, 'target' => '', 'plural' => 1, 'parent' => $index); if ($parse_printf && loco_sniff_printf($msgid_plural)) { $this->exp[$index]['format'] = 'php'; } $key = $msgid_plural . ""; if (isset($this->reg[$key])) { $plural_index = $this->reg[$key]; $this->exp[$plural_index] = $entry; } else { $plural_index = count($this->exp); $this->reg[$key] = $plural_index; $this->exp[] = $entry; } } return $index; }
/** * @override */ function compile_string(array $consts, array $vars) { $value = ''; do { $Child = $this->current(); // Significant nodes are strings, and concatenators // brackets will be ignored, and all assumed to have parsed successfully, so no point validating switch ($Child->scalar_symbol()) { case NT_STRING: $StrNode = $Child->current(); $t = $StrNode->scalar_symbol(); $s = $StrNode->__toString(); switch ($t) { // generic string reference case T_STRING: // should be a constant if (isset($consts[$s])) { // set from registry of constants $value .= (string) $consts[$s]; } else { if (defined($s)) { // else is a built-in constant trigger_error("Constant not registered ({$s}), using current value", E_USER_NOTICE); $value .= (string) constant($s); } else { trigger_error("Spurious T_STRING ({$s}) in argument", E_USER_WARNING); $value .= $s; } } continue 2; // string literal // string literal case T_CONSTANT_ENCAPSED_STRING: $value .= decapse_string($s); continue 2; // scalar variable, can only be global. // dodgy - best avoided // scalar variable, can only be global. // dodgy - best avoided case T_VARIABLE: $v = substr($s, 1); if (array_key_exists($v, $vars)) { $value .= (string) $vars[$v]; } else { if (array_key_exists($v, $GLOBALS)) { $value .= (string) $GLOBALS[$v]; } else { trigger_error("Unknown variable {$s}", E_USER_WARNING); } } continue 2; // special proccessing of array access vars // special proccessing of array access vars case NT_ARRAY_ACCESS: $v = $StrNode->reset()->__toString(); $v = substr($v, 1); if (isset($vars[$v]) && is_array($vars[$v])) { $a = $vars[$v]; } else { if (isset($GLOBALS[$v]) && is_array($GLOBALS[$v])) { trigger_error("Variable not registered (\${$v}), using global", E_USER_NOTICE); $a = $GLOBALS[$v]; } else { trigger_error("Unknown variable {$v}", E_USER_WARNING); continue 2; } } $StrNode->next(); $StrNode = $StrNode->next(); $k = $StrNode->__toString(); if (is_numeric($k)) { $k = (int) $k; } else { $k = decapse_string($k); } if (array_key_exists($k, $a)) { $value .= (string) $a[$k]; } else { trigger_error("Spurious array access (no index {$k} in {$v})", E_USER_WARNING); } continue 2; // sandboxed function calls // sandboxed function calls case NT_FUNC_CALL: $funcname = $StrNode->current()->__toString(); switch ($funcname) { case 'dirname': case 'basename': break; default: trigger_error("function '{$funcname}' not supported, sorry", E_USER_WARNING); continue 2; } if (!function_exists($funcname)) { trigger_error("Spurious function '{$funcname}'", E_USER_WARNING); continue 2; } // collect function arguments $args = array(); $argnodes = $StrNode->get_nodes_by_symbol(NT_ARG, 2); foreach ($argnodes as $i => $arg) { $args[] = $arg->compile_string($consts, $vars); } // ok to call function $value .= (string) call_user_func_array($funcname, $args); continue 2; // special constants need to be passing in via the $consts argument // special constants need to be passing in via the $consts argument case T_FILE: if (!isset($consts[$s])) { trigger_error("{$s} not passed as a registered constant", E_USER_WARNING); } else { $value .= $consts[$s]; } continue 2; // else warn that this is unsupported // else warn that this is unsupported default: trigger_error("Unexpected node ({$t}) with value `{$StrNode}'", E_USER_WARNING); continue 2; } // end strNode switch } // end child switch } while ($this->next()); return $value; }