/** * 外部 CSS、埋め込み CSS を style 属性として XHTML テキストに割り当てます。 * エンコーディング形式は変換されない点に注意して下さい。 * * @param string $contents 適用対象の XHTML テキスト。 * @return string style 属性を適用した XHTML テキストを返します。 * @author Naomichi Yamakita <*****@*****.**> */ public function assign($contents) { if (null_or_empty($contents)) { return $content; } if (!mb_check_encoding($contents, 'UTF-8')) { $contents = mb_convert_encoding($contents, 'UTF-8', 'Shift_JIS'); } $this->response->setContentType('application/xhtml+xml; charset=Shift_JIS'); // XML 宣言を取り除く (saveXML() コール時に付加されるため) if (preg_match('/^<\\?xml\\s[^>]+?\\?>\\s*/', $contents, $matches)) { $contents = substr($contents, strlen($matches[0])); } // xmlns 属性を取り除く (saveXML() コール時に付加されるため) $contents = preg_replace('/xmlns=["\'][^"\']+["\']/', '', $contents); // charset に UTF-8 以外のエンコーディングが指定されている場合、DOMDocument::loadHTML() が解析に失敗する $contents = preg_replace('/charset=Shift_JIS/i', 'charset=UTF-8', $contents); // 数値文字参照をエスケープ $contents = preg_replace('/&(#(?:\\d+|x[0-9a-fA-F]+)|[A-Za-z0-9]+);/', 'HTMLCSSINLINERESCAPE%$1%::::::::', $contents); try { $dom = new DOMDocument(); $dom->loadXML($contents); $dom->formatOutput = TRUE; $dom->encoding = 'UTF-8'; $dom->xmlStandalone = FALSE; $this->_xpath = new DOMXPath($dom); $this->loadCSS(); // CSS をインライン化 $css = $this->_htmlCSS->toArray(); $styles = array(); foreach ($css as $selector => $style) { // Selector2XPath は疑似要素の解析が不安定のためスルー if (strpos($selector, '@') !== FALSE) { continue; } if (strpos($selector, ':') !== FALSE) { $inline = NULL; foreach ($style as $name => $value) { $inline .= sprintf('%s:%s;', $name, $value); } $styles[] = sprintf('%s{%s}', $selector, $inline); continue; } $xpath = HTML_CSS_Selector2XPath::toXPath($selector); try { $elements = $this->_xpath->query($xpath); if ($elements->length == 0) { continue; } $inline = NULL; foreach ($style as $name => $value) { $inline .= sprintf('%s:%s;', $name, $value); } foreach ($elements as $element) { if ($attributeStyle = $element->attributes->getNamedItem('style')) { $attributeStyle->nodeValue = $inline . $attributeStyle->nodeValue; } else { $element->setAttribute('style', $inline); } } // 無効なセレクタを無視 } catch (Exception $e) { } } // 疑似クラスを <style> タグとして追加する if (sizeof($styles)) { $style = implode(PHP_EOL, $styles); $head = $this->_xpath->query('//head'); $node = new DOMElement('style', $style); $head->item(0)->appendChild($node)->setAttribute('type', 'text/css'); } $result = $dom->saveXML(); $result = preg_replace('/encoding="UTF-8"/i', 'encoding="Shift_JIS"', $result); $result = preg_replace('/charset=UTF-8/i', 'charset=Shift_JIS', $result); $result = preg_replace('/HTMLCSSINLINERESCAPE%(#(?:\\d+|x[0-9a-fA-F]+)|[A-Za-z0-9]+)%::::::::/', '&$1;', $result); return $result; } catch (Exception $e) { // loadXML() がスローする例外が分かりにくいため、問題が起きたテンプレートのパスをメッセージに追加しておく $message = sprintf('Failed to parse template. (hint: %s) [%s]', $e->getMessage(), $this->renderer->getTemplatePath()); throw new Mars_ParseException($message); } }
/** * OpenID プロバイダからコールバックされたパラメータを元 Mars_OpenID のオブジェクトインスタンスを生成します。 * * @return Mars_OpenID Mars_OpenID のオブジェクトインスタンスを返します。 * インスタンスの生成に失敗した (OpenID プロバイダからリクエストされたパラメータが不正、または存在しない) 場合は FALSE を返します。 * @author Naomichi Yamakita <*****@*****.**> */ public static function createFromRequest() { $request = Mars_DIContainerFactory::getContainer()->getRequest(); $provider = $request->getPathInfo('_openId.provider'); if (null_or_empty($provider)) { return FALSE; } try { $instance = self::create($provider); if (!$instance->receiveData()) { return FALSE; } } catch (Mars_UnsupportedException $e) { return FALSE; } return $instance; }
/** * Function to handle redirection of regular and also nested resource * routes. * * @param string $controller The controller for the route * @param string $action The action for the route * @param integer $id The id for the route * @return Redirect */ public function handleRedirect($route, $parentAssociation, $id = null, $responseCode) { $params = array(); if ($id && null_or_empty($parentAssociation)) { $route = explode('.', $route)[0] . '.' . self::ACTION_EDIT; $params = array($id); } elseif ($id && !null_or_empty($parentAssociation)) { $parent = explode('.', $route)[0]; $child = explode('.', $route)[1]; $route = $parent . '.' . $child . '.' . self::ACTION_EDIT; $params = array_values(array_merge($parentAssociation, array($id))); } elseif (is_null($id) && !null_or_empty($parentAssociation)) { $parent = explode('.', $route)[0]; $child = explode('.', $route)[1]; $route = $parent . '.' . $child . '.' . self::ACTION_SHOW; $params = array_values($parentAssociation); } elseif (is_null($id) && null_or_empty($parentAssociation)) { $route = explode('.', $route)[0] . '.' . self::ACTION_SHOW; $params = array(); } else { throw new InvalidArgumentException("incorrect format"); } //handle error responses return $this->redirect->route($route, $params); }
/** * OpenID プロバイダから返却されたパラメータを受け取ります。 * * @return bool パラメータを正しく解析できた場合に TRUE を返します。 * リクエストの妥当性をチェックする場合は {@link isAuthenticated()} メソッドを使用して下さい。 * @author Naomichi Yamakita <*****@*****.**> */ public function receiveData() { $this->_attributeExchange = new Mars_OpenIDAttributeExchange($this->_openId->getAttributes()); // レスポンスは GET、または POST で返される $data = $this->request->getParameter('openid_mode'); if (null_or_empty($data)) { return FALSE; } if ($this->request->getQuery('openid_mode') != 'cancel' && $this->_openId->validate()) { $this->_identity = $this->request->getParameter('openid_identity'); } return TRUE; }
/** * 3-legged OAuth プロバイダからコールバックされたパラメータを元に {@link Mars_OAuthProvider} を実装したクラスのオブジェクトインスタンスを生成します。 * (2-legged OAuth プロバイダで当メソッドを使用することはできません) * * @return Mars_OAuthProvider {@link Mars_OAuthProvider} を実装したクラスのオブジェクトインスタンスを返します。 * インスタンスの生成に失敗した (OAuth プロバイダからリクエストされたパラメータが不正、または存在しない) 場合は FALSE を返します。 * @throws Mars_RequestException パラメータが不正な場合に発生。 * @author Naomichi Yamakita <*****@*****.**> */ public static function createFromRequest() { // Twitter、facebook は PATH_INFO 形式、mixi は GET 形式で 'state' パラメータを返す // (mixi は 'state' パラメータ固定) $request = Mars_DIContainerFactory::getContainer()->getRequest(); $provider = $request->getParameter('state'); if (null_or_empty($provider)) { return FALSE; } try { $instance = self::create($provider); $instance->parseAccessToken(); } catch (Mars_UnsupportedException $e) { return FALSE; } return $instance; }