Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Mvc/Renderer/Json.php
<?php

namespace XF\Mvc\Renderer;

use
XF\Mvc\Reply\AbstractReply;
use
XF\Util\File;

use function
array_key_exists, count, is_array, is_object, strval;

class
Json extends AbstractRenderer
{
    protected
$encodeModifiers = JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT;

    protected function
initialize()
    {
       
$this->response->contentType('application/json');
    }

    public function
getResponseType()
    {
        return
'json';
    }

    public function
renderRedirect($url, $type, $message = '')
    {
        return [
           
'status' => 'ok',
           
'message' => $message,
           
'redirect' => $url
       
];
    }

    public function
renderMessage($message)
    {
        return [
           
'status' => 'ok',
           
'message' => $message
       
];
    }

    public function
renderErrors(array $errors)
    {
       
$app = \XF::app();
       
$params = [
           
'errors' => $errors,
           
'error' => count($errors) == 1 ? reset($errors) : false,
           
'forJson' => true
       
];
       
$html = $this->getTemplate($app['app.defaultType'] . ':error', $params)->render();

        return [
           
'status' => 'error',
           
'errors' => $errors,
           
'errorHtml' => $this->getHtmlOutputStructure($html)
        ];
    }

    public function
renderView($viewName, $templateName, array $params = [])
    {
        if (isset(
$params['innerContent']))
        {
            return
$params['innerContent'];
        }

       
$output = $this->renderViewObject($viewName, $templateName, $params);
        if (
$output === null)
        {
           
$output = [
               
'status' => 'ok',
               
'html' => $this->renderHtmlFallback($viewName, $templateName, $params)
            ];
        }
        else if (
is_array($output) && array_key_exists('html', $output) && $output['html'] === null)
        {
           
$output['html'] = $this->renderHtmlFallback($viewName, $templateName, $params);
        }

        return
$output;
    }

    public function
renderHtmlFallback($viewName, $templateName, array $params = [])
    {
       
$htmlOutput = $this->renderViewObject($viewName, $templateName, $params, 'html');
        if (
$htmlOutput === null && $templateName)
        {
           
$htmlOutput = $this->getTemplate($templateName, $params)->render();
        }

        return
$this->getHtmlOutputStructure($htmlOutput);
    }

    public function
getHtmlOutputStructure($html)
    {
       
$output = [
           
'content' => strval($html)
        ];

       
$templater = $this->templater;
       
$pageParams = $templater->pageParams;
       
$templateErrors = $templater->getTemplateErrors();

        if (
$output['content'] === '' && $templateErrors)
        {
           
$output['content'] = \XF::phrase('no_content_returned_try_again_later');
        }

        if (\
XF::$debugMode && $templateErrors)
        {
           
$output['templateErrors'] = true;

           
$templateErrorDetails = [];
            foreach (
$templateErrors AS $error)
            {
               
$templateErrorDetails[] = sprintf('Template %s: %s (%s:%d)',
                   
$error['template'],
                   
$error['error'],
                   
File::stripRootPathPrefix($error['file']),
                   
$error['line']
                );
            }
           
$output['templateErrorDetails'] = $templateErrorDetails;
        }

        if (isset(
$pageParams['pageTitle']))
        {
           
$output['title'] = $pageParams['pageTitle'];
        }
        if (isset(
$pageParams['pageH1']))
        {
           
$output['h1'] = $pageParams['pageH1'];
        }

       
$includedCss = $templater->getIncludedCss();
        if (
$includedCss)
        {
           
$output['css'] = $includedCss;
        }

       
$inlineCss = $templater->getInlineCss();
        if (
$inlineCss)
        {
           
$output['cssInline'] = $inlineCss;
        }

       
$includedJs = $templater->getIncludedJs();
        if (
$includedJs)
        {
           
$output['js'] = $includedJs;
        }

       
$inlineJs = $templater->getInlineJs();
        if (
$inlineJs)
        {
           
$output['jsInline'] = $inlineJs;
        }

        if (isset(
$templater->pageParams['jsState']) && is_array($templater->pageParams['jsState']))
        {
           
$output['jsState'] = $templater->pageParams['jsState'];
        }

        return
$output;
    }

    public function
postFilter($content, AbstractReply $reply)
    {
        if (!
is_array($content))
        {
           
$e = new \LogicException('JSON response output must be an array.');
            if (\
XF::$debugMode)
            {
                throw
$e;
            }
            else
            {
                \
XF::logException($e);
            }
           
$content = [];
        }

       
$replyJson = $reply->getJsonParams();
        if (
$replyJson)
        {
            foreach (
$replyJson AS $k => $v)
            {
                if (!
array_key_exists($k, $content))
                {
                   
$content[$k] = $v;
                }
            }
        }

        if (!
$reply->getViewOption('skipDefaultJsonParams'))
        {
           
$content = $this->addDefaultJsonParams($content);
        }

        return
json_encode($this->prepareJsonEncode($content), $this->encodeModifiers);
    }

    protected function
addDefaultJsonParams(array $content)
    {
       
$app = \XF::app();
       
$visitor = \XF::visitor();
       
$language = \XF::language();
       
$container = $app->container();

        if (
$visitor->user_id)
        {
           
$conversations = $visitor->conversations_unread;
           
$alerts = $visitor->alerts_unviewed;

           
$content['visitor'] = [
               
'conversations_unread' => $language->numberFormat($conversations),
               
'alerts_unviewed' => $language->numberFormat($alerts),
               
'total_unread' => $language->numberFormat($conversations + $alerts)
            ];
        }

        if (
$container->isCached('job.manager'))
        {
           
$jobManager = $app->jobManager();
           
$manualJobs = $jobManager->hasManualEnqueued();
           
$autoJobs = $jobManager->hasAutoEnqueued();
           
$autoBlocking = $jobManager->hasAutoBlocking();

            if (
$manualJobs || $autoJobs)
            {
                if (
$autoBlocking)
                {
                   
$autoBlockingMessage = $jobManager->getAutoBlockingMessage();
                    if (
$autoBlockingMessage)
                    {
                       
$autoBlockingMessage = strval($autoBlockingMessage);
                    }
                }
                else
                {
                   
$autoBlockingMessage = null;
                }

                if (
$autoJobs && \XF::options()->jobRunTrigger == 'activity')
                {
                   
$runAutoJobs = true;
                }
                else
                {
                   
$runAutoJobs = false;
                }

               
$content['job'] = [
                   
'manual' => $manualJobs ? array_keys($jobManager->getManualEnqueued()) : null,
                   
'autoBlocking' => $autoBlocking ? array_keys($jobManager->getAutoBlocking()) : null,
                   
'autoBlockingMessage' => $autoBlockingMessage,
                   
'auto' => $runAutoJobs
               
];
            }
        }

        if (\
XF::$debugMode)
        {
            if (
$container->isCached('db'))
            {
               
$queryCount = \XF::db()->getQueryCount();
            }
            else
            {
               
$queryCount = null;
            }

           
$content['debug'] = [
               
'time' => round(microtime(true) - \XF::app()->container('time.granular'), 4),
               
'queries' => $queryCount,
               
'memory' => round(memory_get_peak_usage() / 1024 / 1024, 2)
            ];
        }

        return
$content;
    }

    protected function
prepareJsonEncode($value)
    {
        if (
is_array($value))
        {
            foreach (
$value AS &$innerValue)
            {
               
$innerValue = $this->prepareJsonEncode($innerValue);
            }
        }
        else if (
is_object($value) && method_exists($value, 'jsonSerialize'))
        {
           
$value = $value->jsonSerialize();
        }
        else if (
is_object($value) && method_exists($value, '__toString'))
        {
           
$value = $value->__toString();
        }

        return
$value;
    }
}