[8] tempnam(): file created in the system's temporary directory /home/xs4/d-staging.com/public_html/st01/cws/core/sub/template.class.php 97 output
| 1 : | <?php
|
|---|---|
| 2 : | //+--------------------------------------------------------+
|
| 3 : | /*
|
| 4 : | <NAME>cws3 テンプレート</NAME>
|
| 5 : | <USAGE>
|
| 6 : | [ PHPコードとの差 ]
|
| 7 : | {code} -> <?php echo (code); ?>
|
| 8 : | %('method:/comname/path/path?key=value'[, $params])
|
| 9 : |
|
| 10 : | [ フィルター ]
|
| 11 : | {code|filter|filter:arg1:arg2} -> <?php echo (filter (filter (code))); ?>
|
| 12 : | フィルターは「|」で区切って何個でも実行可能
|
| 13 : | 右から実行される
|
| 14 : | パラメータに「:」が含まれる場合は変数等で渡すこと。
|
| 15 : | html : htmlspecialchars
|
| 16 : | nl2br : nl2br
|
| 17 : | strip_tags : strip_tags
|
| 18 : | date : date
|
| 19 : | number : number_format
|
| 20 : | addslashes : addslashes
|
| 21 : | url : urlencode
|
| 22 : | sprintf : sprintf
|
| 23 : | substr : (mb_strlen ($value) > $arg1) ? mb_substr ($value, 0, $arg1) . $arg2 : $value;
|
| 24 : | exists : isset ($value) ? $value : 'default';
|
| 25 : | or : ($value) ? $value : 'alternate';
|
| 26 : |
|
| 27 : | [ 制御構文 ]
|
| 28 : | {if [code]}{elseif [code]}{else}{/if}
|
| 29 : | {foreach [code]}{continue}{break}{/foreach}
|
| 30 : | {for [code]}{continue}{break}{/for}
|
| 31 : | {while [code]}{continue}{break}{/while}
|
| 32 : | {switch}{case [code]}{break}{default}{/switch}
|
| 33 : | {increment}
|
| 34 : |
|
| 35 : | [ エスケープ ]
|
| 36 : | 下記コード内は処理されない。<cdata>はタグも削除される。
|
| 37 : | この中では<?php print(); ?>等で処理する。
|
| 38 : | <cdata></cdata>
|
| 39 : | <script></script>
|
| 40 : | <style></style>
|
| 41 : |
|
| 42 : | [ キャッシュ ]
|
| 43 : | 無効なキャッシュディレクトリを渡すと、
|
| 44 : | tmpnam()で一時領域にファイルを作成して読み込む。
|
| 45 : |
|
| 46 : | [ メソッド ]
|
| 47 : | display () - 出力
|
| 48 : | contents () - 出力を取得
|
| 49 : | path () - 有効なパスを返す (キャッシュが無効の場合一時ファイルのパスを返す)
|
| 50 : | code () - PHPコードを取得 (常にテンプレートからコンパイルした結果を返す)
|
| 51 : |
|
| 52 : | </USAGE>
|
| 53 : |
|
| 54 : | <VERSION>1.0.0</VERSION>
|
| 55 : | <UPDATE>
|
| 56 : | - 2013.12.03 ver 1.0.0
|
| 57 : | </UPDATE>
|
| 58 : |
|
| 59 : | <EXTEND></EXTEND>
|
| 60 : | */
|
| 61 : | //+--------------------------------------------------------+
|
| 62 : | class cws_template {
|
| 63 : |
|
| 64 : |
|
| 65 : | //
|
| 66 : | // Properties
|
| 67 : | //
|
| 68 : | private $templatePath;
|
| 69 : | private $cacheDir;
|
| 70 : | private $cacheFile;
|
| 71 : | private $vars = array ();
|
| 72 : |
|
| 73 : |
|
| 74 : |
|
| 75 : | //
|
| 76 : | // Constructor
|
| 77 : | //
|
| 78 : | public function __construct($_template_path, $_cache_dir = False) {
|
| 79 : |
|
| 80 : | // ローカル変数初期化
|
| 81 : | $this->templatePath = $_template_path;
|
| 82 : | $this->cacheDir = ($_cache_dir and is_writable ($_cache_dir)) ? $_cache_dir : '';
|
| 83 : |
|
| 84 : | // ファイル存在確認
|
| 85 : | if (!file_exists ($_template_path) or !is_readable ($_template_path)) {
|
| 86 : | return;
|
| 87 : | }
|
| 88 : |
|
| 89 : | // キャッシュファイル名セット
|
| 90 : | if ($_cache_dir) {
|
| 91 : | $filename = realpath ($this->templatePath);
|
| 92 : | if (False !== strpos ($filename, '@')) { trigger_error ('File name not allowed.', E_USER_ERROR);}
|
| 93 : | $filename = str_replace ('/', '@', $filename);
|
| 94 : | $this->cacheFile = $this->cacheDir . "/" . $filename;
|
| 95 : | if (strlen ($this->cacheFile) > 254) { trigger_error ("[" . __CLASS__ . "] Filename overflow.", E_USER_ERROR);}
|
| 96 : | } else {
|
| 97 : | $this->cacheFile = @tempnam ("dev/null", "");
|
| 98 : | }
|
| 99 : |
|
| 100 : | }
|
| 101 : |
|
| 102 : |
|
| 103 : |
|
| 104 : |
|
| 105 : |
|
| 106 : | //
|
| 107 : | // -
|
| 108 : | //
|
| 109 : | // [ Public ]
|
| 110 : | //
|
| 111 : | //
|
| 112 : | // display () - 出力
|
| 113 : | //
|
| 114 : | public function display() {
|
| 115 : | require ($this->path());
|
| 116 : | }
|
| 117 : |
|
| 118 : |
|
| 119 : |
|
| 120 : |
|
| 121 : |
|
| 122 : | //
|
| 123 : | // contents () - 出力を取得
|
| 124 : | //
|
| 125 : | public function contents() {
|
| 126 : | ob_start();
|
| 127 : | $this->display();
|
| 128 : | $contents = ob_get_contents();
|
| 129 : | ob_end_clean();
|
| 130 : | return $contents;
|
| 131 : | }
|
| 132 : |
|
| 133 : |
|
| 134 : |
|
| 135 : |
|
| 136 : |
|
| 137 : | //
|
| 138 : | // path () - 有効なパスを返す
|
| 139 : | //
|
| 140 : | public function path() {
|
| 141 : | if (!file_exists ($this->cacheFile) or !filesize ($this->cacheFile)) {
|
| 142 : | $this->save();
|
| 143 : | }
|
| 144 : | return $this->cacheFile;
|
| 145 : | }
|
| 146 : |
|
| 147 : |
|
| 148 : |
|
| 149 : |
|
| 150 : |
|
| 151 : | //
|
| 152 : | // code () - PHPコードを取得 (キャッシュファイルは保存されない)
|
| 153 : | //
|
| 154 : | public function code() {
|
| 155 : | return $this->compile();
|
| 156 : | }
|
| 157 : |
|
| 158 : |
|
| 159 : |
|
| 160 : |
|
| 161 : |
|
| 162 : |
|
| 163 : | //
|
| 164 : | // -
|
| 165 : | //
|
| 166 : | // [ Local ]
|
| 167 : | //
|
| 168 : | // save () - キャッシュに保存
|
| 169 : | //
|
| 170 : | private function save() {
|
| 171 : | if ($this->cacheFile) {
|
| 172 : | $code = $this->compile();
|
| 173 : | file_put_contents ($this->cacheFile, $code, LOCK_EX);
|
| 174 : | }
|
| 175 : | }
|
| 176 : |
|
| 177 : |
|
| 178 : |
|
| 179 : |
|
| 180 : |
|
| 181 : | //
|
| 182 : | // compile () - テンプレートをPHPコードに変換
|
| 183 : | //
|
| 184 : | private function compile() {
|
| 185 : |
|
| 186 : | // 開始
|
| 187 : | if (!file_exists ($this->templatePath)) {
|
| 188 : | return 'File not found. (' . $this->templatePath . ')';
|
| 189 : | }
|
| 190 : | $code = file_get_contents($this->templatePath);
|
| 191 : |
|
| 192 : | // cws call
|
| 193 : | $code = str_replace('%(', '$cws->call(', $code);
|
| 194 : |
|
| 195 : | // コメントアウト
|
| 196 : | $code = preg_replace ('|/\*.*?\*/|s', '', $code);
|
| 197 : | $code = preg_replace ('|{\*.*?\*}|s', '', $code);
|
| 198 : |
|
| 199 : | // PHPコードをエスケープ
|
| 200 : | if (preg_match_all ('/(<\?php.*?\?>)/s', $code, $matches)) {
|
| 201 : | $phpcodes = $matches[0];
|
| 202 : | foreach ($phpcodes as $i => $phpcode) {
|
| 203 : | $code = str_replace ($phpcode, "<!-- PHP CODE $i -->", $code);
|
| 204 : | }
|
| 205 : | }
|
| 206 : |
|
| 207 : | // <cdata>エスケープ
|
| 208 : | if (preg_match_all ('/<cdata>(.*?)<\/cdata>/s', $code, $matches)) {
|
| 209 : | $cdatacodes = $matches[1];
|
| 210 : | foreach ($matches[0] as $i => $cdatacode) {
|
| 211 : | $code = str_replace ($cdatacode, "<!-- CDATA $i -->", $code);
|
| 212 : | }
|
| 213 : | }
|
| 214 : |
|
| 215 : | // <script>エスケープ
|
| 216 : | if (preg_match_all ('/<script(.*?)>.*?<\/script>/s', $code, $matches)) {
|
| 217 : | $scriptcodes = $matches[0];
|
| 218 : | foreach ($scriptcodes as $i => $scriptcode) {
|
| 219 : | $sub = preg_replace_callback ('/{([^}]*?)}/s', array ($this, 'brace'), $matches[1][$i]);
|
| 220 : | $scriptcodes[$i] = str_replace ($matches[1][$i], $sub, $scriptcode);
|
| 221 : | $code = str_replace ($scriptcode, "<!-- SCRIPT CODE $i -->", $code);
|
| 222 : | }
|
| 223 : | }
|
| 224 : |
|
| 225 : | // <style>エスケープ
|
| 226 : | if (preg_match_all ('/<style(.*?)>.*?<\/style>/s', $code, $matches)) {
|
| 227 : | $stylecodes = $matches[0];
|
| 228 : | foreach ($stylecodes as $i => $stylecode) {
|
| 229 : | $sub = preg_replace_callback ('/{([^}]*?)}/s', array ($this, 'brace'), $matches[1][$i]);
|
| 230 : | $stylecodes[$i] = str_replace ($matches[1][$i], $sub, $stylecode);
|
| 231 : | $code = str_replace ($stylecode, "<!-- STYLE CODE $i -->", $code);
|
| 232 : | }
|
| 233 : | }
|
| 234 : |
|
| 235 : | // {}部分
|
| 236 : | $code = str_replace ('\{', '{', $code);
|
| 237 : | $code = str_replace ('\}', '}', $code);
|
| 238 : | $code = preg_replace_callback ('/{([^}]*?)}/s', array ($this, 'brace'), $code);
|
| 239 : | $code = str_replace ('{', '{', $code);
|
| 240 : | $code = str_replace ('}', '}', $code);
|
| 241 : |
|
| 242 : | // <style>戻す
|
| 243 : | if (isset ($stylecodes)) {
|
| 244 : | foreach ($stylecodes as $i => $stylecode) {
|
| 245 : | $code = str_replace ("<!-- STYLE CODE $i -->", $stylecode, $code);
|
| 246 : | }
|
| 247 : | }
|
| 248 : |
|
| 249 : | // <script>戻す
|
| 250 : | if (isset ($scriptcodes)) {
|
| 251 : | foreach ($scriptcodes as $i => $scriptcode) {
|
| 252 : | $code = str_replace ("<!-- SCRIPT CODE $i -->", $scriptcode, $code);
|
| 253 : | }
|
| 254 : | }
|
| 255 : |
|
| 256 : | // {CDATA}戻す
|
| 257 : | if (isset ($cdatacodes)) {
|
| 258 : | foreach ($cdatacodes as $i => $cdatacode) {
|
| 259 : | $code = str_replace ("<!-- CDATA $i -->", $cdatacode, $code);
|
| 260 : | }
|
| 261 : | }
|
| 262 : |
|
| 263 : | // PHPコードを戻す
|
| 264 : | if (isset ($phpcodes)) {
|
| 265 : | foreach ($phpcodes as $i => $phpcode) {
|
| 266 : | $code = str_replace ("<!-- PHP CODE $i -->", $phpcode, $code);
|
| 267 : | }
|
| 268 : | }
|
| 269 : |
|
| 270 : | // 終了
|
| 271 : | return '<?php /*'. str_replace (cws::ROOT, '', $this->templatePath) . '*/ global $cws; ?>' . "\n" . $code;
|
| 272 : |
|
| 273 : | }
|
| 274 : |
|
| 275 : |
|
| 276 : |
|
| 277 : |
|
| 278 : |
|
| 279 : | //
|
| 280 : | // brace () - {}の処理
|
| 281 : | //
|
| 282 : | private function brace($_matches) {
|
| 283 : |
|
| 284 : | // 準備
|
| 285 : | $code = $_matches[1];
|
| 286 : |
|
| 287 : | // 制御構文
|
| 288 : | $pattern = 'if|elseif|else|foreach|for|while|switch|case|default|break|continue|increment';
|
| 289 : | if (preg_match ('/^([\/]?)('.$pattern.')(.*?)$/s', $code, $matches)) {
|
| 290 : | if ('/' == $matches[1]) {
|
| 291 : | return "<?php end{$matches[2]}; ?>";
|
| 292 : | } elseif ('else' == $matches[2]) {
|
| 293 : | return "<?php {$matches[2]}: ?>";
|
| 294 : | } elseif ('switch' == $matches[2]) {
|
| 295 : | return "<?php switch ({$matches[3]}): case {$matches[3]} != {$matches[3]}:break; ?>";
|
| 296 : | } elseif ('case' == $matches[2]) {
|
| 297 : | return "<?php case ({$matches[3]}): ?>";
|
| 298 : | } elseif ('default' == $matches[2]) {
|
| 299 : | return "<?php default: ?>";
|
| 300 : | } elseif ('break' == $matches[2]) {
|
| 301 : | return "<?php break; ?>";
|
| 302 : | } elseif ('continue' == $matches[2]) {
|
| 303 : | return "<?php continue; ?>";
|
| 304 : | } elseif ('increment' == $matches[2]) {
|
| 305 : | return "<?php {$matches[3]}++; ?>";
|
| 306 : | } else {
|
| 307 : | return "<?php {$matches[2]} ({$matches[3]}): ?>";
|
| 308 : | }
|
| 309 : | }
|
| 310 : |
|
| 311 : | // フィルターとコードに分割
|
| 312 : | $filters = explode ('|', $code);
|
| 313 : | $code = array_shift ($filters);
|
| 314 : |
|
| 315 : | // フィルタを追加
|
| 316 : | $filters = array_reverse ($filters);
|
| 317 : | foreach ($filters as $filter) {
|
| 318 : | $filter = explode (':', $filter);
|
| 319 : | $func = array_shift ($filter);
|
| 320 : | $func = array ($this, 'filter_' . $func);
|
| 321 : | if (is_callable ($func)) {
|
| 322 : | $code = call_user_func_array ($func, array_merge (array ($code), $filter));
|
| 323 : | }
|
| 324 : | }
|
| 325 : |
|
| 326 : | // コードを返す
|
| 327 : | return "<?php echo ($code); ?>";
|
| 328 : |
|
| 329 : | }
|
| 330 : |
|
| 331 : |
|
| 332 : |
|
| 333 : |
|
| 334 : |
|
| 335 : | //
|
| 336 : | // -
|
| 337 : | //
|
| 338 : | // [ Filters ]
|
| 339 : | //
|
| 340 : | // filter_html () - htmlspecialchars
|
| 341 : | // filter_nl2br () - nl2br
|
| 342 : | // filter_strip_tags () - strip_tags
|
| 343 : | // filter_date () - date
|
| 344 : | // filter_number () - number_format
|
| 345 : | // filter_addslashes () - addslashes
|
| 346 : | // filter_url () - urlencode
|
| 347 : | // filter_sprintf () - sprintf
|
| 348 : | // filter_substr () - substr
|
| 349 : | // filter_exists () - isset
|
| 350 : | // filter_or () - or 'alternate'
|
| 351 : | //
|
| 352 : | private function filter_html($_code, $_ent_no_quotes = False) {
|
| 353 : | return "htmlspecialchars ((string)$_code" . ($_ent_no_quotes ? '' : ', ENT_QUOTES') . ")";
|
| 354 : | }
|
| 355 : | private function filter_nl2br($_code) {
|
| 356 : | return "nl2br ((string)$_code)";
|
| 357 : | }
|
| 358 : | private function filter_strip_tags($_code, $_allowable_tags = "''") {
|
| 359 : | return "strip_tags ((string)$_code, $_allowable_tags)";
|
| 360 : | }
|
| 361 : | private function filter_date($_code, $_format = "'Y-m-d H:i:s'") {
|
| 362 : | return "date ($_format, (float)$_code)";
|
| 363 : | }
|
| 364 : | private function filter_number($_code) {
|
| 365 : | return "number_format ((float)$_code)";
|
| 366 : | }
|
| 367 : | private function filter_addslashes($_code) {
|
| 368 : | return "addslashes ((string)$_code)";
|
| 369 : | }
|
| 370 : | private function filter_url($_code) {
|
| 371 : | return "urlencode ((string)$_code)";
|
| 372 : | }
|
| 373 : | private function filter_sprintf($_code, $_format) {
|
| 374 : | return "sprintf ($_format, $_code)";
|
| 375 : | }
|
| 376 : | private function filter_substr($_code, $_length, $_after = "'...'") {
|
| 377 : | return "(mb_strlen ((string)$_code) > $_length) ? mb_substr ((string)$_code, 0, $_length) . $_after : (string)$_code";
|
| 378 : | }
|
| 379 : | private function filter_exists($_code, $_default = "''") {
|
| 380 : | return "isset ($_code) ? $_code : $_default";
|
| 381 : | }
|
| 382 : | private function filter_or($_code, $_alternate) {
|
| 383 : | return "($_code ? $_code : $_alternate)";
|
| 384 : | }
|
| 385 : |
|
| 386 : | }
|
| 387 : | ?> |