2 namespace sfjp\Wiki\Processor;
3 use sfjp\Wiki\Exception;
8 public $formatted_text;
12 public $args = array();
14 protected static $reserved = array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');
16 protected static $context_key_rename_rules = array(
17 'plugin_include_path' => 'extension.additional_include_path',
18 'plugin.order' => 'extension.acl_order',
19 'plugin.allow' => 'extension.allow',
20 'plugin.deny' => 'extension.deny',
21 'supress_plugin_error' => 'extension.hide_error',
24 function __construct($args = null) {
25 $default_ctx = array("wiki_baseurl" => ".",
26 "site_root_url" => (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://" . (empty($_SERVER['HTTP_HOST']) ? 'localhost.localdomain' : $_SERVER['HTTP_HOST']),
27 "svn_base_url" => "http://svn.sourceforge.jp/view",
28 "cvs_base_url" => "http://cvs.sourceforge.jp/view",
29 "sfjp.group_name" => null,
30 "sfjp.group_id" => null,
31 "extension.additional_include_path" => null,
32 "extension.acl_order" => "deny,allow",
33 "extension.allow" => array(),
34 "extension.deny" => array(),
35 "extension.hide_error" => false,
36 "self_url" => array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : '',
37 "cache_manager" => null,
38 "cache_depends" => array(),
39 "whole_page_cachable" => true,
41 "gen_head_id" => true,
42 "internal_url_regex" => null,
43 "nofollow_on_external_links" => true,
45 $this->context = $default_ctx;
46 $this->clearPreProc();
47 $this->clearPostProc();
50 function __destruct() {
51 unset($this->formatter);
54 public function setArgs($args) {
60 public function getArgs($pos = null) {
63 return $this->args[$pos];
66 public function getContext($key = null) {
68 $key = static::renameContextKey($key);
69 return array_key_exists($key, $this->context) ? $this->context[$key] : null;
71 return $this->context;
75 static public function renameContextKey($key) {
76 if (!array_key_exists($key, static::$context_key_rename_rules))
78 return static::$context_key_rename_rules[$key];
82 public function hasContext($key) {
83 return array_key_exists(static::renameContextKey($key), $this->context);
86 public function setContext($c) {
87 foreach ($c as $key => $val) {
88 $key = static::renameContextKey($key);
89 $this->context[$key] = $val;
91 $this->context = array_merge($this->context, $c);
94 public function removeContext($key) {
95 unset($this->context[static::renameContextKey($key)]);
98 public function clearContext() {
99 $this->context = array();
102 public function incrementCounter($name) {
103 $c = &$this->getCounter($name);
107 public function &getCounter($name) {
108 $c = &$this->context["counters"];
109 if (!isset($c[$name])) {
115 public function setCounter($name, $val) {
116 $c = &$this->context["counters"];
120 public function clearCounter($name = null) {
122 $this->setCounter($name, 0);
124 $this->setContext(array("counters" => array()));
128 public function &getCacheDepends() {
129 return $this->context["cache_depends"];
132 public function addCacheDepends($deps) {
133 if (empty($deps)) return;
134 if (!is_array($deps)) $deps = array($deps);
135 $c = &$this->context["cache_depends"];
136 foreach ($deps as $dep) {
141 public function clearCacheDepends() {
142 $this->context["cache_depends"] = array();
145 public function reset() {
146 $this->is_vary = false;
148 $this->formatted_text = "";
149 $this->clearCounter();
150 $this->clearPreProc();
151 $this->clearPostProc();
152 $this->clearCacheDepends();
153 if ($this->getFormatter())
154 $this->getFormatter()->reset();
157 public function isVary() {
158 return $this->is_vary;
161 public function setText($text) {
167 public function getText() {
171 public function getFormattedText() {
173 foreach ($this->preproc as $p) {
174 $ret .= $p->process();
176 $ret .= $this->formatted_text;
177 foreach ($this->postproc as $p) {
178 $ret .= $p->process();
183 public function get_plugin_instance($class_name) {
184 $check_name = str_replace('\\', '/', $class_name);
185 $name = basename($check_name);
187 if (!$this->check_plugin_allowed($check_name))
188 throw new Exception\Plugin_Error("Load Denied: $name");
189 if (!preg_match('/^[A-Za-z0-9._-]+$/', $name))
190 throw new Exception\Plugin_error("Wrong Plugin Name: $name");
192 if (in_array(strtolower($name), self::$reserved)) {
193 $class_name = substr($class_name, 0, strlen($class_name) - strlen($name)) . "_{$name}";
197 $orig_include_path = null;
198 if ($this->getContext('extension.additional_include_path')) {
199 $orig_include_path = ini_get('include_path');
200 ini_set('include_path', $this->getContext('extension.additional_include_path').":$orig_include_path");
202 $class = new \ReflectionClass("\\sfjp\\Wiki\\{$class_name}");
203 if ($orig_include_path)
204 ini_set('include_path', $orig_include_path);
205 $instance = $class->newInstance($this);
206 if (!is_callable(array($instance, "process")))
207 throw new \ReflectionException();
208 } catch (\ReflectionException $e) {
209 ini_set('include_path', $orig_include_path);
210 error_log("Plugin '$name' load failed.");
211 throw new Exception\Plugin_Error("Not Found: {$name}");
218 protected function check_plugin_allowed($name) {
219 $order = $this->getContext("plugin.order");
220 $allow = $this->getContext("plugin.allow");
221 $deny = $this->getContext("plugin.deny");
223 if (!$order) $order = "deny,allow";
224 $order = strtolower($order);
225 if (!is_array($allow)) $allow = array($allow);
226 if (!is_array($deny)) $deny = array($deny);
227 $deny = array_map('strtolower', $deny);
228 $allow = array_map('strtolower', $allow);
229 $name = strtolower($name);
231 if ($order === "deny,allow") {
233 if (in_array('all', $deny)) $ret = false;
234 if (in_array($name, $deny)) $ret = false;
235 if (in_array('all', $allow)) return true;
236 if (in_array($name, $allow)) return true;
237 } else { # "allow,deny"
239 if (in_array('all', $allow)) $ret = true;
240 if (in_array($name, $allow)) $ret = true;
241 if (in_array('all', $deny)) return false;
242 if (in_array($name, $deny)) return false;
247 public function addPreProc($obj) {
248 $this->preproc[] = $obj;
251 public function clearPreProc() {
252 $this->preproc = array();
255 public function addPostProc($obj) {
256 $this->postproc[] = $obj;
259 public function clearPostProc() {
260 $this->postproc = array();
263 public function getFormatter() {
264 return $this->formatter;
267 public function setFormatter($f) {
268 $this->formatter = $f;
269 if (!$this->formatter->getProcessor())
270 $this->formatter->setProcessor($this);
273 public function __($text, $args=array()) {
274 if (!$this->hasContext('i18n')) {
277 return $this->getContext('i18n')->__($text, $args);