/** * @param string $name * @param string $host * @param number $port * @param string $user * @param string $password * @param string $sock * @param boolean $autocommit */ public function connect($name, $host, $port, $user, $password, $sock, $autocommit) { unset($port, $user, $password, $sock); if (!extension_loaded('pdo_sqlite')) { throw new \ebi\exception\ConnectionException('pdo_sqlite not supported'); } $con = null; if (empty($name)) { $name = getcwd() . '/data.sqlite3'; } if ($host != ':memory:') { if (strpos($name, '.') === false) { $name = $name . '.sqlite3'; } $host = str_replace('\\', '/', $host); if (substr($host, -1) != '/') { $host = $host . '/'; } $path = \ebi\Util::path_absolute($host, $name); \ebi\Util::mkdir(dirname($path)); } try { $con = new \PDO(sprintf('sqlite:%s', $host == ':memory:' ? ':memory:' : $path)); $con->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); } catch (\PDOException $e) { throw new \ebi\exception\ConnectionException($e->getMessage()); } if (!empty($this->timezone)) { $this->timezone_offset = (new \DateTimeZone($this->timezone))->getOffset(new \DateTime('now', new \DateTimeZone('UTC'))); } return $con; }
/** * pharのパスを通す * @param string $path * @param string $namespace */ public static function phar($path, $namespace = null) { /** * @param string $arg1 pahrが格納されているディレクトリ */ $base = \ebi\Conf::get('path', getcwd()); $path = realpath(\ebi\Util::path_absolute($base, $path)); if (isset(self::$read[$path])) { return true; } if ($path === false) { throw new \ebi\exception\InvalidArgumentException($path . ' not found'); } if (!empty($namespace)) { $namespace = str_replace("\\", '/', $namespace); if ($namespace[0] == '/') { $namespace = substr($namespace, 1); } } $package_dir = 'phar://' . (is_dir('phar://' . $path . '/src/') ? $path . '/src' : $path); spl_autoload_register(function ($c) use($package_dir, $namespace) { $c = str_replace(array('\\', '_'), '/', $c); if ((empty($namespace) || strpos($c, $namespace) === 0) && is_file($f = $package_dir . '/' . $c . '.php')) { require_once $f; } return false; }, true, false); self::$read[$path] = true; return true; }
/** * @plugin ebi.Temaplte * @param string $src * @return Ambigous <string, string, mixed>|string */ public function before_template($src) { /** * @param string $path テンプレートパーツのファイルがあるディレクトリ */ $path = \ebi\Util::path_slash(\ebi\Conf::get('path', \ebi\Conf::resource_path('parts')), null, true); return \ebi\Xml::find_replace($src, 'rt:parts', function ($xml) use($path) { $href = \ebi\Util::path_absolute($path, $xml->in_attr('href')); if (!is_file($href)) { throw new \ebi\exception\InvalidArgumentException($href . ' not found'); } return file_get_contents($href); }); }
private static function parse($html, $url) { $forms = []; try { foreach (\ebi\Xml::extract($html, 'body')->find('form') as $key => $formtag) { $form = new \stdClass(); $form->name = $formtag->in_attr('name', $formtag->in_attr('id', $key)); $form->action = \ebi\Util::path_absolute($url, $formtag->in_attr('action', $url)); $form->method = strtolower($formtag->in_attr('method', 'get')); $form->multiple = false; $form->element = []; foreach ($formtag->find('input') as $count => $input) { $obj = new \stdClass(); $obj->name = $input->in_attr('name', $input->in_attr('id', 'input_' . $count)); $obj->type = strtolower($input->in_attr('type', 'text')); $obj->value = self::htmldecode($input->in_attr('value')); $obj->selected = 'selected' === strtolower($input->in_attr('checked', $input->in_attr('checked'))); $obj->multiple = false; $form->element[] = $obj; } foreach ($formtag->find('textarea') as $count => $input) { $obj = new \stdClass(); $obj->name = $input->in_attr('name', $input->in_attr('id', 'textarea_' . $count)); $obj->type = 'textarea'; $obj->value = self::htmldecode($input->value()); $obj->selected = true; $obj->multiple = false; $form->element[] = $obj; } foreach ($formtag->find('select') as $count => $input) { $obj = new \stdClass(); $obj->name = $input->in_attr('name', $input->in_attr('id', 'select_' . $count)); $obj->type = 'select'; $obj->value = []; $obj->selected = true; $obj->multiple = 'multiple' == strtolower($input->param('multiple', $input->attr('multiple'))); foreach ($input->find('option') as $count => $option) { $op = new \stdClass(); $op->value = self::htmldecode($option->in_attr('value', $option->value())); $op->selected = 'selected' == strtolower($option->in_attr('selected', $option->in_attr('selected'))); $obj->value[] = $op; } $form->element[] = $obj; } $forms[] = $form; } } catch (\ebi\exception\NotFoundException $e) { } return $forms; }
/** * アプリケーションのURLを返す * @param string $url ベースのURLに続く相対パス * @retunr string */ public function app_url($url = null) { return \ebi\Util::path_absolute(\ebi\Flow::app_url(), $url); }
/** * アプリケーションを実行する * @param mixed{} $map */ public static function app($map = []) { if (empty($map)) { $map = ['patterns' => ['' => ['action' => 'ebi.Dt', 'mode' => 'local']]]; } else { if (is_string($map)) { $map = ['patterns' => ['' => ['action' => $map]]]; } else { if (is_array($map) && !isset($map['patterns'])) { $map = ['patterns' => $map]; } } } if (!isset($map['patterns']) || !is_array($map['patterns'])) { throw new \ebi\exception\InvalidArgumentException('patterns not found'); } $entry_file = null; foreach (debug_backtrace(false) as $d) { if ($d['file'] !== __FILE__) { $entry_file = basename($d['file']); break; } } /** * @param string $val アプリケーションURL、末尾が * = 実行エントリ, ** = エントリファイル名(*.php) */ $app_url = \ebi\Conf::get('app_url'); if (is_array($app_url)) { if (isset($app_url[$entry_file])) { $app_url = $app_url[$entry_file]; } else { if (isset($app_url['*'])) { $app_url = $app_url['*']; } else { $app_url = null; } } } self::$app_url = $app_url; /** * @param string $val メディアファイルのベースURL * http://localhost:8000/resources/media */ self::$media_url = \ebi\Conf::get('media_url'); if (empty(self::$app_url)) { $host = \ebi\Request::host(); self::$app_url = (empty($host) ? 'http://localhost:8000/' : $host . '/') . $entry_file; } else { if (substr(self::$app_url, -1) == '*') { self::$app_url = substr(self::$app_url, 0, -1); self::$app_url = substr(self::$app_url, -1) == '*' ? substr(self::$app_url, 0, -1) . $entry_file : self::$app_url . substr($entry_file, 0, -4); } } self::$app_url = \ebi\Util::path_slash(str_replace('https://', 'http://', self::$app_url), null, true); if (empty(self::$media_url)) { $media_path = preg_replace('/\\/[^\\/]+\\.php[\\/]$/', '/', self::$app_url); self::$media_url = $media_path . 'resources/media/'; } self::$media_url = \ebi\Util::path_slash(self::$media_url, null, true); /** * @param string $val テンプレートファイルのディレクトリ */ self::$template_path = \ebi\Util::path_slash(\ebi\Conf::get('template_path', \ebi\Conf::resource_path('templates')), null, true); $automap_idx = 1; $selfmap = ['patterns' => self::expand_patterns('', $map['patterns'], [], $automap_idx)]; unset($map['patterns']); $selfmap = array_merge($selfmap, $map); self::$workgroup = array_key_exists('workgroup', $selfmap) ? $selfmap['workgroup'] : basename($entry_file, '.php'); /** * @param boolean $val HTTPSを有効にするか,falseの場合、mapのsecureフラグもすべてfalseとなる */ $conf_secure = \ebi\Conf::get('secure'); $map_secure = array_key_exists('secure', $selfmap) && $selfmap['secure'] === true; $is_secure_pattern_func = function ($pattern) use($conf_secure, $map_secure) { if ($conf_secure === false) { return false; } if (array_key_exists('secure', $pattern)) { return $pattern['secure'] === true; } return $map_secure == true; }; $https = str_replace('http://', 'https://', self::$app_url); $url_format_func = function ($url, $pattern) use($https, $is_secure_pattern_func) { $num = 0; $format = \ebi\Util::path_absolute($is_secure_pattern_func($pattern) ? $https : self::$app_url, empty($url) ? '' : substr(preg_replace_callback("/([^\\\\])(\\(.*?[^\\\\]\\))/", function ($n) { return $n[1] . '%s'; }, ' ' . $url, -1, $num), 1)); return [str_replace(['\\\\', '\\.', '_ESC_'], ['_ESC_', '.', '\\'], $format), $num]; }; foreach ($selfmap['patterns'] as $k => $v) { list($selfmap['patterns'][$k]['format'], $selfmap['patterns'][$k]['num']) = $url_format_func($k, $v); } krsort($selfmap['patterns']); if (self::$is_get_map) { self::$is_get_map = false; self::$map = $selfmap; return; } $pathinfo = preg_replace("/(.*?)\\?.*/", "\\1", isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''); if (preg_match('/^\\/' . preg_quote(self::$package_media_url, '/') . '\\/(\\d+)\\/(.+)$/', $pathinfo, $m)) { foreach ($selfmap['patterns'] as $p) { if (isset($p['@']) && isset($p['idx']) && (int) $p['idx'] === (int) $m[1] && is_file($file = $p['@'] . '/resources/media/' . $m[2])) { \ebi\HttpFile::attach($file); } } \ebi\HttpHeader::send_status(404); return self::terminate(); } foreach ($selfmap['patterns'] as $k => $pattern) { if (preg_match('/^' . (empty($k) ? '' : '\\/') . str_replace(['\\/', '/', '@#S'], ['@#S', '\\/', '\\/'], $k) . '[\\/]{0,1}$/', $pathinfo, $param_arr)) { if ($is_secure_pattern_func($pattern)) { if (substr(\ebi\Request::current_url(), 0, 5) === 'http:' && (!isset($_SERVER['HTTP_X_FORWARDED_HOST']) || isset($_SERVER['HTTP_X_FORWARDED_PORT']) && $_SERVER['HTTP_X_FORWARDED_PORT'] != 443 || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] != 'https')) { header('Location: ' . preg_replace('/^.+(:\\/\\/.+)$/', 'https\\1', \ebi\Request::current_url())); exit; } self::$media_url = str_replace('http://', 'https://', self::$media_url); } self::$template = new \ebi\Template(); try { $funcs = $class = $method = $template = $ins = null; $exception = null; $has_flow_plugin = false; $result_vars = $plugins = []; $accept_debug = \ebi\Conf::get('accept_debug', false) && strpos(strtolower((new \ebi\Env())->get('HTTP_ACCEPT')), 'application/debug') !== false; array_shift($param_arr); if (array_key_exists('action', $pattern)) { if (is_string($pattern['action'])) { list($class, $method) = explode('::', $pattern['action']); } else { if (is_callable($pattern['action'])) { $funcs = $pattern['action']; } else { throw new \ebi\exception\InvalidArgumentException($pattern['name'] . ' action invalid'); } } } foreach ($selfmap['patterns'] as $m) { self::$url_pattern[$m['name']][$m['num']] = $m['format']; if (array_key_exists('@', $pattern) && array_key_exists('@', $m) && $pattern['idx'] == $m['idx']) { list(, $mm) = explode('::', $m['action']); self::$selected_class_pattern[$mm][$m['num']] = ['format' => $m['format'], 'name' => $m['name']]; } } if (array_key_exists('vars', $selfmap) && is_array($selfmap['vars'])) { $result_vars = $selfmap['vars']; } if (array_key_exists('vars', $pattern) && is_array($pattern['vars'])) { $result_vars = array_merge($result_vars, $pattern['vars']); } if (array_key_exists('redirect', $pattern)) { self::map_redirect($pattern['redirect'], $result_vars, $pattern); } foreach (array_merge(array_key_exists('plugins', $selfmap) ? is_array($selfmap['plugins']) ? $selfmap['plugins'] : [$selfmap['plugins']] : [], array_key_exists('plugins', $pattern) ? is_array($pattern['plugins']) ? $pattern['plugins'] : [$pattern['plugins']] : []) as $m) { $o = \ebi\Util::strtoinstance($m); self::set_class_plugin($o); $plugins[] = $o; } if (!isset($funcs) && isset($class)) { $ins = \ebi\Util::strtoinstance($class); $traits = \ebi\Util::get_class_traits(get_class($ins)); if ($has_flow_plugin = in_array('ebi\\FlowPlugin', $traits)) { foreach ($ins->get_flow_plugins() as $m) { $o = \ebi\Util::strtoinstance($m); $plugins[] = $o; self::set_class_plugin($o); } $ins->set_pattern($pattern); } if (in_array('ebi\\Plugin', $traits)) { foreach ($plugins as $o) { $ins->set_object_plugin($o); } } $funcs = [$ins, $method]; } foreach ($plugins as $o) { self::$template->set_object_plugin($o); } if (self::has_class_plugin('before_flow_action')) { /** * 前処理 */ self::call_class_plugin_funcs('before_flow_action'); } if ($has_flow_plugin) { $ins->before(); $before_redirect = $ins->get_before_redirect(); if (isset($before_redirect)) { self::map_redirect($before_redirect, $result_vars, $pattern); } } if (isset($funcs)) { try { $action_result_vars = call_user_func_array($funcs, $param_arr); if (is_array($action_result_vars)) { $result_vars = array_merge($result_vars, $action_result_vars); } } catch (\Exception $exception) { } } if ($has_flow_plugin) { $ins->after(); $template_block = $ins->get_template_block(); if (!empty($template_block)) { self::$template->put_block(\ebi\Util::path_absolute(self::$template_path, $ins->get_template_block())); } $template = $ins->get_template(); if (!empty($template)) { $pattern['template'] = $template; } $result_vars = array_merge($result_vars, $ins->get_after_vars()); $after_redirect = $ins->get_after_redirect(); if (isset($after_redirect) && !array_key_exists('after', $pattern) && !array_key_exists('cond_after', $pattern)) { $pattern['after'] = $after_redirect; } } if (self::has_class_plugin('after_flow_action')) { /** * 後処理 */ self::call_class_plugin_funcs('after_flow_action'); } if (isset($exception)) { throw $exception; } \ebi\Exceptions::throw_over(); if (!$accept_debug) { if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') { if (array_key_exists('post_cond_after', $pattern) && is_array($pattern['post_cond_after'])) { foreach ($pattern['post_cond_after'] as $cak => $cav) { if (isset($result_vars[$cak])) { self::map_redirect($cav, $result_vars, $pattern); } } } if (array_key_exists('post_after', $pattern)) { self::map_redirect($pattern['post_after'], $result_vars, $pattern); } } if (array_key_exists('cond_after', $pattern) && is_array($pattern['cond_after'])) { foreach ($pattern['cond_after'] as $cak => $cav) { if (isset($result_vars[$cak])) { self::map_redirect($cav, $result_vars, $pattern); } } } if (array_key_exists('after', $pattern)) { self::map_redirect($pattern['after'], $result_vars, $pattern); } if (array_key_exists('template', $pattern)) { if (array_key_exists('template_super', $pattern)) { self::$template->template_super(\ebi\Util::path_absolute(self::$template_path, $pattern['template_super'])); } return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $pattern['template'])); } else { if (isset($template)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $template)); } else { if (array_key_exists('@', $pattern) && is_file($t = \ebi\Util::path_absolute(self::$template_path, $pattern['name']) . '.html')) { return self::template($result_vars, $pattern, $ins, $t); } else { if (array_key_exists('@', $pattern) && is_file($t = $pattern['@'] . '/resources/templates/' . preg_replace('/^.+::/', '', $pattern['action'] . '.html'))) { $app_url = $is_secure_pattern_func($pattern) ? str_replace('http://', 'https://', self::$app_url) : self::$app_url; return self::template($result_vars, $pattern, $ins, $t, $app_url . self::$package_media_url . '/' . $pattern['idx']); } else { if (array_key_exists('find_template', $selfmap) && $selfmap['find_template'] === true && is_file($t = \ebi\Util::path_absolute(self::$template_path, $pattern['name'] . '.html'))) { return self::template($result_vars, $pattern, $ins, $t); } else { if (self::has_class_plugin('flow_output')) { /** * 結果を出力する * @param mixed{} $result_vars actionで返却された変数 */ self::call_class_plugin_funcs('flow_output', $result_vars); return self::terminate(); } } } } } } } \ebi\HttpHeader::send('Content-Type', 'application/json'); print \ebi\Json::encode(['result' => \ebi\Util::to_primitive($result_vars)]); return self::terminate(); } catch (\Exception $e) { \ebi\FlowInvalid::set($e); \ebi\Dao::rollback_all(); /** * @param string[] $val ログに記録しない例外クラス名 */ if (!in_array(get_class($e), \ebi\Conf::gets('ignore_exceptions'))) { \ebi\Log::warning($e); } if (isset($pattern['error_status'])) { \ebi\HttpHeader::send_status($pattern['error_status']); } else { if (isset($selfmap['error_status'])) { \ebi\HttpHeader::send_status($selfmap['error_status']); } } if (isset($pattern['vars']) && !empty($pattern['vars']) && is_array($pattern['vars'])) { $result_vars = array_merge($result_vars, $pattern['vars']); } if (!$accept_debug) { if (isset($pattern['@']) && is_file($t = $pattern['@'] . '/resources/templates/error.html')) { $app_url = $is_secure_pattern_func($pattern) ? str_replace('http://', 'https://', self::$app_url) : self::$app_url; return self::template($result_vars, $pattern, $ins, $t, $app_url . self::$package_media_url . '/' . $pattern['idx']); } else { if (array_key_exists('error_redirect', $pattern)) { return self::map_redirect($pattern['error_redirect'], [], $pattern); } else { if (array_key_exists('error_template', $pattern)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $pattern['error_template'])); } else { if (array_key_exists('error_redirect', $selfmap)) { return self::map_redirect($selfmap['error_redirect'], [], $pattern); } else { if (array_key_exists('error_template', $selfmap)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $selfmap['error_template'])); } else { if (self::has_class_plugin('flow_exception')) { /** * 例外発生時の処理・出力 * @param \Exception $e 発生した例外 */ self::call_class_plugin_funcs('flow_exception', $e); return self::terminate(); } else { if (self::has_class_plugin('flow_output')) { self::call_class_plugin_funcs('flow_output', ['error' => ['message' => $e->getMessage()]]); return self::terminate(); } } } } } } } } /** * @param boolean $val Error Json出力時にException traceも出力するフラグ */ $trace = \ebi\Conf::get('exception_trace', false); $message = []; foreach (\ebi\FlowInvalid::get() as $g => $e) { $em = ['message' => $e->getMessage(), 'type' => basename(str_replace("\\", '/', get_class($e)))]; if ($trace) { $em['trace'] = $e->getTraceAsString(); } if (!empty($g)) { $em['group'] = $g; } $message[] = $em; } \ebi\HttpHeader::send('Content-Type', 'application/json'); print json_encode(['error' => $message]); return self::terminate(); } } } if (array_key_exists('nomatch_redirect', $selfmap) && strpos($selfmap['nomatch_redirect'], '://') === false) { foreach ($selfmap['patterns'] as $m) { if ($selfmap['nomatch_redirect'] == $m['name']) { self::$url_pattern[$m['name']][$m['num']] = $m['format']; break; } } self::map_redirect($selfmap['nomatch_redirect'], [], []); } \ebi\HttpHeader::send_status(404); return self::terminate(); }
/** * Set template * @param string $template_path Relative path from resource_path * @param mixed{} $vars bind variables * @return $this */ public function set_template($template_path, $vars = []) { /** * @param string $path Email template resources root */ $resource_path = \ebi\Conf::get('resource_path', \ebi\Conf::resource_path('mail')); $path = \ebi\Util::path_absolute($resource_path, $template_path); if (!is_file($path)) { throw new \ebi\exception\InvalidArgumentException($template_path . ' not found'); } $xml = \ebi\Xml::extract(file_get_contents($path), 'mail'); try { try { $from = $xml->find_get('from'); $this->from($from->in_attr('address'), $from->in_attr('name')); } catch (\ebi\exception\NotFoundException $e) { } foreach ($xml->find('to') as $to) { $this->to($to->in_attr('address'), $to->in_attr('name')); } try { $this->return_path($xml->find_get('return_path')->in_attr('address')); } catch (\ebi\exception\NotFoundException $e) { } /** * @param string $xtc_name xtc query key */ $xtc_name = \ebi\Conf::get('xtc_name', 'xtc'); $xtc = self::xtc($template_path); $this->header['X-T-Code'] = $xtc; $vars['t'] = new \ebi\FlowHelper(); $vars['xtc'] = [$xtc_name => $xtc]; $subject = trim(str_replace(["\r\n", "\r", "\n"], '', $xml->find_get('subject')->value())); $template = new \ebi\Template(); $template->cp($vars); $body_xml = $xml->find_get('body'); $signature = $body_xml->in_attr('signature'); $signature_text = ''; if (!empty($signature)) { $sig_path = \ebi\Util::path_absolute($resource_path, $signature); if (!is_file($sig_path)) { throw new \ebi\exception\InvalidArgumentException($signature . ' not found'); } $sig_xml = \ebi\Xml::extract(file_get_contents($sig_path), 'mail'); $signature_text = \ebi\Util::plain_text(PHP_EOL . $sig_xml->find_get('signature')->value() . PHP_EOL); } $message = $template->get(\ebi\Util::plain_text(PHP_EOL . $body_xml->value() . PHP_EOL) . $signature_text); $this->message($message); $this->subject($template->get($subject)); try { $html = $xml->find_get('html'); $html_path = \ebi\Util::path_absolute($resource_path, $html->in_attr('src', preg_replace('/^(.+)\\.\\w+$/', '\\1', $path) . '.html')); foreach ($html->find('media') as $media) { $file = \ebi\Util::path_absolute($resource_path, $media->in_attr('src')); if (!is_file($file)) { throw new \ebi\exception\InvalidArgumentException($media->in_attr('src') . ' invalid media'); } $this->media($media->in_attr('src'), file_get_contents($file)); } $template = new \ebi\Template(); $template->cp($vars); $this->html($template->read($html_path)); } catch (\ebi\exception\NotFoundException $e) { } foreach ($xml->find('attach') as $attach) { $file = \ebi\Util::path_absolute($resource_path, $attach->in_attr('src')); if (!is_file($file)) { throw new \ebi\exception\InvalidArgumentException($attach->in_attr('src') . ' invalid media'); } $this->attach($attach->in_attr('name', $attach->in_attr('src')), file_get_contents($file)); } return $this; } catch (\ebi\exception\NotFoundException $e) { throw new \ebi\exception\InvalidArgumentException($template_path . ' invalid data'); } }
private function request($method, $url, $download_path = null) { if (!isset($this->resource)) { $this->resource = curl_init(); } $url_info = parse_url($url); $cookie_base_domain = (isset($url_info['host']) ? $url_info['host'] : '') . (isset($url_info['path']) ? $url_info['path'] : ''); switch ($method) { case 'RAW': case 'POST': curl_setopt($this->resource, CURLOPT_POST, true); break; case 'GET': if (isset($url_info['query'])) { parse_str($url_info['query'], $vars); foreach ($vars as $k => $v) { if (!isset($this->request_vars[$k])) { $this->request_vars[$k] = $v; } } list($url) = explode('?', $url, 2); } curl_setopt($this->resource, CURLOPT_HTTPGET, true); break; case 'HEAD': curl_setopt($this->resource, CURLOPT_NOBODY, true); break; case 'PUT': curl_setopt($this->resource, CURLOPT_PUT, true); break; case 'DELETE': curl_setopt($this->resource, CURLOPT_CUSTOMREQUEST, 'DELETE'); break; } switch ($method) { case 'POST': if (!empty($this->request_file_vars)) { $vars = []; if (!empty($this->request_vars)) { foreach (explode('&', http_build_query($this->request_vars)) as $q) { $s = explode('=', $q, 2); $vars[urldecode($s[0])] = isset($s[1]) ? urldecode($s[1]) : null; } } foreach (explode('&', http_build_query($this->request_file_vars)) as $q) { $s = explode('=', $q, 2); if (isset($s[1])) { if (!is_file($f = urldecode($s[1]))) { throw new \ebi\exception\InvalidArgumentException($f . ' not found'); } $vars[urldecode($s[0])] = class_exists('\\CURLFile', false) ? new \CURLFile($f) : '@' . $f; } } curl_setopt($this->resource, CURLOPT_POSTFIELDS, $vars); } else { curl_setopt($this->resource, CURLOPT_POSTFIELDS, http_build_query($this->request_vars)); } break; case 'RAW': if (!isset($this->request_header['Content-Type'])) { $this->request_header['Content-Type'] = 'text/plain'; } curl_setopt($this->resource, CURLOPT_POSTFIELDS, $this->raw); break; case 'GET': case 'HEAD': case 'PUT': case 'DELETE': $url = $url . (!empty($this->request_vars) ? '?' . http_build_query($this->request_vars) : ''); } curl_setopt($this->resource, CURLOPT_URL, $url); curl_setopt($this->resource, CURLOPT_FOLLOWLOCATION, false); curl_setopt($this->resource, CURLOPT_HEADER, false); curl_setopt($this->resource, CURLOPT_RETURNTRANSFER, false); curl_setopt($this->resource, CURLOPT_FORBID_REUSE, true); curl_setopt($this->resource, CURLOPT_FAILONERROR, false); curl_setopt($this->resource, CURLOPT_TIMEOUT, $this->timeout); if (self::$recording_request) { curl_setopt($this->resource, CURLINFO_HEADER_OUT, true); } /** * @param boolean $ssl_verify SSL証明書を確認するかの真偽値 */ if (\ebi\Conf::get('ssl-verify', true) === false) { curl_setopt($this->resource, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->resource, CURLOPT_SSL_VERIFYPEER, false); } if (!empty($this->user)) { curl_setopt($this->resource, CURLOPT_USERPWD, $this->user . ':' . $this->password); } if (!isset($this->request_header['Expect'])) { $this->request_header['Expect'] = null; } if (!isset($this->request_header['Cookie'])) { $cookies = ''; foreach ($this->cookie as $domain => $cookie_value) { if (strpos($cookie_base_domain, $domain) === 0 || strpos($cookie_base_domain, $domain[0] == '.' ? $domain : '.' . $domain) !== false) { foreach ($cookie_value as $k => $v) { if (!$v['secure'] || $v['secure'] && substr($url, 0, 8) == 'https://') { $cookies .= sprintf('%s=%s; ', $k, $v['value']); } } } } curl_setopt($this->resource, CURLOPT_COOKIE, $cookies); } if (!isset($this->request_header['User-Agent'])) { curl_setopt($this->resource, CURLOPT_USERAGENT, empty($this->agent) ? isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null : $this->agent); } curl_setopt($this->resource, CURLOPT_HTTPHEADER, array_map(function ($k, $v) { return $k . ': ' . $v; }, array_keys($this->request_header), $this->request_header)); curl_setopt($this->resource, CURLOPT_HEADERFUNCTION, [$this, 'callback_head']); if (empty($download_path)) { curl_setopt($this->resource, CURLOPT_WRITEFUNCTION, [$this, 'callback_body']); } else { if (strpos($download_path, '://') === false && !is_dir(dirname($download_path))) { mkdir(dirname($download_path), 0777, true); } $fp = fopen($download_path, 'wb'); curl_setopt($this->resource, CURLOPT_WRITEFUNCTION, function ($resource, $data) use(&$fp) { if ($fp) { fwrite($fp, $data); } return strlen($data); }); } $this->request_header = $this->request_vars = []; $this->head = $this->body = $this->raw = ''; curl_exec($this->resource); if (!empty($download_path) && $fp) { fclose($fp); } if (($err_code = curl_errno($this->resource)) > 0) { if ($err_code == 47 || $err_code == 52) { return $this; } throw new \ebi\exception\ConnectionException($err_code . ': ' . curl_error($this->resource)); } $this->url = curl_getinfo($this->resource, CURLINFO_EFFECTIVE_URL); $this->status = curl_getinfo($this->resource, CURLINFO_HTTP_CODE); if (self::$recording_request) { self::$record_request[] = curl_getinfo($this->resource, CURLINFO_HEADER_OUT); } if (preg_match_all('/Set-Cookie:[\\s]*(.+)/i', $this->head, $match)) { foreach ($match[1] as $cookies) { $cookie_name = $cookie_value = $cookie_domain = $cookie_path = $cookie_expires = null; $cookie_domain = $cookie_base_domain; $cookie_path = '/'; $secure = false; foreach (explode(';', $cookies) as $cookie) { $cookie = trim($cookie); if (strpos($cookie, '=') !== false) { list($k, $v) = explode('=', $cookie, 2); $k = trim($k); $v = trim($v); switch (strtolower($k)) { case 'expires': $cookie_expires = ctype_digit($v) ? (int) $v : strtotime($v); break; case 'domain': $cookie_domain = preg_replace('/^[\\w]+:\\/\\/(.+)$/', '\\1', $v); break; case 'path': $cookie_path = $v; break; default: if (!isset($cookie_name)) { $cookie_name = $k; $cookie_value = $v; } } } else { if (strtolower($cookie) == 'secure') { $secure = true; } } } $cookie_domain = substr(\ebi\Util::path_absolute('http://' . $cookie_domain, $cookie_path), 7); if ($cookie_expires !== null && $cookie_expires < time()) { if (isset($this->cookie[$cookie_domain][$cookie_name])) { unset($this->cookie[$cookie_domain][$cookie_name]); } } else { $this->cookie[$cookie_domain][$cookie_name] = ['value' => $cookie_value, 'expires' => $cookie_expires, 'secure' => $secure]; } } } curl_close($this->resource); unset($this->resource); if ($this->redirect_count++ < $this->redirect_max) { switch ($this->status) { case 300: case 301: case 302: case 303: case 307: if (preg_match('/Location:[\\040](.*)/i', $this->head, $redirect_url)) { return $this->request('GET', trim(\ebi\Util::path_absolute($url, $redirect_url[1])), $download_path); } } } $this->redirect_count = 1; return $this; }
private function rtblock($src, $filename) { if (strpos($src, 'rt:block') !== false || strpos($src, 'rt:extends') !== false) { $base_filename = $filename; $blocks = $paths = $blockvars = []; try { while (true) { $e = \ebi\Xml::extract($this->rtcomment($src), 'rt:extends'); $href = $e->in_attr('href'); if (substr($href, 0, 1) == '#') { $href = $filename . $href; } $href = \ebi\Util::path_absolute(str_replace("\\", '/', dirname($filename)) . '/', $href); if (empty($href) || !is_file(preg_replace('/^(.+)#.*$/', '\\1', $href))) { throw new \ebi\exception\InvalidTemplateException('href not found ' . $filename); } if ($filename === $href) { throw new \ebi\exception\InvalidTemplateException('Infinite Recursion Error' . $filename); } $readxml = \ebi\Xml::anonymous($this->rtcomment($src)); foreach ($readxml->find('rt:block') as $b) { $n = $b->in_attr('name'); if (!empty($n) && !array_key_exists($n, $blocks)) { $blocks[$n] = $b->value(); $paths[$n] = $filename; } } foreach ($readxml->find('rt:blockvar') as $b) { if (!isset($blockvars[$b->in_attr('name')])) { $blockvars[$b->in_attr('name')] = $b->value(); } } $src = $this->replace_xtag($this->read_src($href)); $filename = preg_replace('/^(.+)#.*$/', '\\1', $href); } } catch (\ebi\exception\NotFoundException $e) { } /** * ブロック処理前の処理 * @param string $src * @return $src */ foreach ($this->get_object_plugin_funcs('before_block_template') as $o) { $src = static::call_func($o, $src); } if (empty($blocks)) { foreach (\ebi\Xml::anonymous($src)->find('rt:block') as $b) { $src = str_replace($b->plain(), $b->value(), $src); } } else { if (!empty($this->template_super)) { $src = $this->read_src(\ebi\Util::path_absolute(str_replace("\\", '/', dirname($base_filename) . '/'), $this->template_super)); } try { while (true) { $b = \ebi\Xml::extract($src, 'rt:block'); $n = $b->in_attr('name'); $src = str_replace($b->plain(), array_key_exists($n, $blocks) ? $blocks[$n] : $b->value(), $src); } } catch (\ebi\exception\NotFoundException $e) { } } $this->file = $filename; foreach ($blockvars as $k => $v) { $this->vars($k, $v); } } return $src; }
/** * @automap * @throws \ebi\exception\NotFoundException */ public function test_view() { $req = new \ebi\Request(); $testdir = $this->test_path(); $req_path = $req->in_vars('path'); $path = \ebi\Util::path_absolute($testdir, $req_path); if (strpos($path, $testdir) === false) { throw new \ebi\exception\NotFoundException($req->in_vars('path') . ' not found'); } $src = str_replace('<?php', '', file_get_contents($path)); $pos = strpos($src, '*/'); if ($pos === false) { $info = new \ebi\Dt\DocInfo(); $info->name($req_path); } else { $info = \ebi\Dt\DocInfo::parse($req_path, $src, $pos + 2); } while ($path != $testdir) { $path = dirname($path) . '/'; if (is_file($f = $path . '__setup__.php')) { $src = str_replace('<?php', '', file_get_contents($f)) . PHP_EOL . '// ' . str_repeat('-', 80) . PHP_EOL . $src; } } return ['info' => $info, 'src' => '<?php' . PHP_EOL . $src]; }
eq("http://www.email.address/index.html", \ebi\Util::path_absolute("http://www.email.address/doc/ja/", "../././.././index.html")); eq("/www/ebi/index.html", \ebi\Util::path_absolute("/www/ebi/", "index.html")); eq("/www.email.address/doc/ja/index.html", \ebi\Util::path_absolute("/www.email.address/doc/ja/", "index.html")); eq("/www.email.address/doc/index.html", \ebi\Util::path_absolute("/www.email.address/doc/ja/", "../index.html")); eq("/www.email.address/doc/ja/action.html/index.html", \ebi\Util::path_absolute('/www.email.address/doc/ja/action.html', 'index.html')); eq("/www.email.address/index.html", \ebi\Util::path_absolute("/www.email.address/doc/ja/", "../../index.html")); eq("/www.email.address/index.html", \ebi\Util::path_absolute("/www.email.address/doc/ja/", "../././.././index.html")); eq("c:/www.email.address/doc/index.html", \ebi\Util::path_absolute("c:/www.email.address/doc/ja/", "../index.html")); eq("http://www.email.address/index.html", \ebi\Util::path_absolute("http://www.email.address/doc/ja", "/index.html")); eq("http://www.email.address/doc/ja/index.html", \ebi\Util::path_absolute('http://www.email.address/doc/ja/action.html', 'index.html')); eq("http://www.email.address/doc/ja/sample.cgi?param=test", \ebi\Util::path_absolute('http://www.email.address/doc/ja/sample.cgi?query=key', '?param=test')); eq("http://www.email.address/doc/index.html", \ebi\Util::path_absolute('http://www.email.address/doc/ja/action.html', '../../index.html')); eq("http://www.email.address/?param=test", \ebi\Util::path_absolute('http://www.email.address/doc/ja/sample.cgi?query=key', '../../../?param=test')); eq("/doc/ja/index.html", \ebi\Util::path_absolute('/', "/doc/ja/index.html")); eq("/index.html", \ebi\Util::path_absolute('/', "index.html")); eq("http://www.email.address/login", \ebi\Util::path_absolute("http://www.email.address", "/login")); eq("http://www.email.address/login", \ebi\Util::path_absolute("http://www.email.address/login", "")); eq("http://www.email.address/login.cgi", \ebi\Util::path_absolute("http://www.email.address/logout.cgi", "login.cgi")); eq("http://www.email.address/hoge/login.cgi", \ebi\Util::path_absolute("http://www.email.address/hoge/logout.cgi", "login.cgi")); eq("http://www.email.address/hoge/login.cgi", \ebi\Util::path_absolute("http://www.email.address/hoge/#abc/aa", "login.cgi")); eq("http://www.email.address/hoge/abc.html#login", \ebi\Util::path_absolute("http://www.email.address/hoge/abc.html", "#login")); eq("http://www.email.address/hoge/abc.html#login", \ebi\Util::path_absolute("http://www.email.address/hoge/abc.html#logout", "#login")); eq("http://www.email.address/hoge/abc.html?abc=aa#login", \ebi\Util::path_absolute("http://www.email.address/hoge/abc.html?abc=aa#logout", "#login")); eq("javascript::alert('')", \ebi\Util::path_absolute("http://www.email.address/hoge/abc.html", "javascript::alert('')")); eq("mailto::hoge@email.address", \ebi\Util::path_absolute("http://www.email.address/hoge/abc.html", "mailto::hoge@email.address")); eq("http://www.email.address/hoge/login.cgi", \ebi\Util::path_absolute("http://www.email.address/hoge/?aa=bb/", "login.cgi")); eq("http://www.email.address/login", \ebi\Util::path_absolute("http://email.address/hoge/hoge", "http://www.email.address/login")); eq("http://localhost:8888/spec/css/style.css", \ebi\Util::path_absolute("http://localhost:8888/spec/", "./css/style.css")); eq('phar://C:/abc/def/ghi/xyz.html', \ebi\Util::path_absolute("phar://C:/abc/def/ghi/", "xyz.html")); eq('phar://C:/abc/def/xyz.html', \ebi\Util::path_absolute("phar://C:/abc/def/ghi", "../xyz.html"));