<commit_before><?php

namespace ellsif\WelCMS;

use ellsif\Logger;
use ellsif\util\FileUtil;
use ellsif\util\StringUtil;

/**
 * URLルーティング
 */
class Router
{

    /**
     * ルーティングを行う。
     *
     * ## 例外
     * 表示できるページが存在しない場合は例外をthrowします。
     */
    public function routing()
    {
        $pocket = Pocket::getInstance();
        $this->initialize();

        // アクティベーション処理
        $activated = (intval($pocket->settingActivated()) != 0);
        if (!$activated) {
            $this->routingActivation();
            return;
        }

        $urlInfo = $pocket->varUrlInfo();
        $paths = $urlInfo['paths'];
        Logger::getInstance()->log('debug', 'routing', json_encode($paths));

        // 個別ページ処理
        $pageEntity = WelUtil::getRepository('Page');
        $pages = $pageEntity->list(['path' => $pocket->varCurrentPath()]);
        if (count($pages) > 0) {
            $page = $pages[0];

            WelUtil::authenticatePage($page);
            $pocket->varIsPage(true);
            $this->routingSetPrinter();
            return;
        }

        // サービスとアクションを取得
        if (!$this->setServiceAndAction($paths)) {
            throw new \InvalidArgumentException('Not Found', 404);
        }

        // 出力フォーマットをチェック
        $this->routingSetFormat();

        $pocket->varUrlInfo($urlInfo);

        // プリンタを選択
        $this->routingSetPrinter();

        // 認証を行う
        if ($pocket->varAuth()) {
            $authClass = FileUtil::getFqClassName($pocket->varAuth() . 'Auth', [$pocket->dirApp(), $pocket->dirSystem()]);
            $auth = new $authClass();
            $auth->authenticate();
        }
    }

    /**
     * 初期化処理を行う。
     *
     * ## 説明
     * Configの値を初期化します。
     */
    protected function initialize()
    {
        $config = Pocket::getInstance();

        $urlInfo = WelUtil::parseUrl($_SERVER['REQUEST_URI']);
        $config->varUrlInfo($urlInfo);
        $config->varRequestMethod(strtoupper($_SERVER['REQUEST_METHOD']));
        $config->varCurrentUrl($_SERVER['REQUEST_URI']);
        $config->varCurrentPath(implode('/', $urlInfo['paths']));
    }

    /**
     * ServiceとActionを決定する。
     *
     * ## 説明
     * URLからServiceとAcrionを判定し、ConfingのvarService、varAction、varActionParamsに設定します。
     */
    protected function setServiceAndAction($paths)
    {
        Logger::getInstance()->log('debug', 'routing', "setServiceAndAction paths: " . json_encode($paths));

        $pocket = Pocket::getInstance();

        $dir = '';
        for($i = 0; $i < count($paths); $i++) {
            $service = $paths[$i];
            $action = $paths[$i + 1] ?? 'index';
            $actionMethod = WelUtil::safeFunction(pathinfo($action, PATHINFO_FILENAME));
            $actionExt = pathinfo($action, PATHINFO_EXTENSION);
            $callable = $this->getCallableAction($service, $actionMethod, $dir);
            if ($callable) {
                $pocket->varService($dir . $service);
                $pocket->varAction($actionExt ? ($actionMethod . '.' . $actionExt) : $actionMethod);
                $pocket->varActionParams(array_splice($paths, $i + 2));
                $pocket->varActionMethod($callable[0]);
                $pocket->varAuth($callable[1]);
                return true;
            }
            $dir .= $service . '/';
        }

        // 上記に無い場合はSiteServiceを利用
        if (count($paths) < 1) {
            $service = 'site';
            $action = $paths[0] ?? 'index';
            $actionMethod = WelUtil::safeFunction(pathinfo($action, PATHINFO_FILENAME));
            $actionExt = pathinfo($action, PATHINFO_EXTENSION);<commit_msg>SiteServiceの下層を実装<commit_after><?php

namespace ellsif\WelCMS;

use ellsif\Logger;
use ellsif\util\FileUtil;
use ellsif\util\StringUtil;

/**
 * URLルーティング
 */
class Router
{

    /**
     * ルーティングを行う。
     *
     * ## 例外
     * 表示できるページが存在しない場合は例外をthrowします。
     */
    public function routing()
    {
        $pocket = Pocket::getInstance();
        $this->initialize();

        // アクティベーション処理
        $activated = (intval($pocket->settingActivated()) != 0);
        if (!$activated) {
            $this->routingActivation();
            return;
        }

        $urlInfo = $pocket->varUrlInfo();
        $paths = $urlInfo['paths'];
        Logger::getInstance()->log('debug', 'routing', json_encode($paths));

        // 個別ページ処理
        $pageEntity = WelUtil::getRepository('Page');
        $pages = $pageEntity->list(['path' => $pocket->varCurrentPath()]);
        if (count($pages) > 0) {
            $page = $pages[0];

            WelUtil::authenticatePage($page);
            $pocket->varIsPage(true);
            $this->routingSetPrinter();
            return;
        }

        // サービスとアクションを取得
        if (!$this->setServiceAndAction($paths)) {
            throw new \InvalidArgumentException('Not Found', 404);
        }

        // 出力フォーマットをチェック
        $this->routingSetFormat();

        $pocket->varUrlInfo($urlInfo);

        // プリンタを選択
        $this->routingSetPrinter();

        // 認証を行う
        if ($pocket->varAuth()) {
            $authClass = FileUtil::getFqClassName($pocket->varAuth() . 'Auth', [$pocket->dirApp(), $pocket->dirSystem()]);
            $auth = new $authClass();
            $auth->authenticate();
        }
    }

    /**
     * 初期化処理を行う。
     *
     * ## 説明
     * Configの値を初期化します。
     */
    protected function initialize()
    {
        $config = Pocket::getInstance();

        $urlInfo = WelUtil::parseUrl($_SERVER['REQUEST_URI']);
        $config->varUrlInfo($urlInfo);
        $config->varRequestMethod(strtoupper($_SERVER['REQUEST_METHOD']));
        $config->varCurrentUrl($_SERVER['REQUEST_URI']);
        $config->varCurrentPath(implode('/', $urlInfo['paths']));
    }

    /**
     * ServiceとActionを決定する。
     *
     * ## 説明
     * URLからServiceとAcrionを判定し、ConfingのvarService、varAction、varActionParamsに設定します。
     */
    protected function setServiceAndAction($paths)
    {
        Logger::getInstance()->log('debug', 'routing', "setServiceAndAction paths: " . json_encode($paths));

        $pocket = Pocket::getInstance();

        $dir = '';
        for($i = 0; $i < count($paths); $i++) {
            $service = $paths[$i];
            $action = $paths[$i + 1] ?? 'index';
            $actionMethod = WelUtil::safeFunction(pathinfo($action, PATHINFO_FILENAME));
            $actionExt = pathinfo($action, PATHINFO_EXTENSION);
            $callable = $this->getCallableAction($service, $actionMethod, $dir);
            if ($callable) {
                $pocket->varService($dir . $service);
                $pocket->varAction($actionExt ? ($actionMethod . '.' . $actionExt) : $actionMethod);
                $pocket->varActionParams(array_splice($paths, $i + 2));
                $pocket->varActionMethod($callable[0]);
                $pocket->varAuth($callable[1]);
                return true;
            }
            $dir .= $service . '/';
        }

        // 上記に無い場合はSiteServiceを利用
        if (count($paths) <= 1) {
            $service = 'site';
            $action = $paths[0] ?? 'index';
            $actionMethod = WelUtil::safeFunction(pathinfo($action, PATHINFO_FILENAME));
            $actionExt = pathinfo($action, PATHINFO_EXTENSION);
{'fraction_non_alphanumeric': 0.16415015930184235, 'fraction_numerical': 0.0036016068707577227, 'mean_word_length': 2.176418829740431, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '940523', 'n_tokens_mistral': 2416, 'n_tokens_neox': 2311, 'n_words': 315}