1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap;
14
15
16/**
17 * Class TemplateUtility
18 * @package ComboStrap
19 * See also {@link Template template engine} - not finished
20 */
21class TemplateUtility
22{
23
24    const VARIABLE_PREFIX = "$";
25
26    static function renderStringTemplateForPageId($pageTemplate, $pageId): string
27    {
28
29
30        $page = Page::createPageFromId($pageId);
31
32
33        return self::renderStringTemplateForDataPage($pageTemplate, $page);
34
35    }
36
37
38    /**
39     * This function is used on a lot of place
40     *
41     * Due to error with the title rendering, we have refactored
42     *
43     * @param $pageId
44     * @return array|mixed|null
45     * @deprecated 2021-07-02 see {@link Page::getTitle()}
46     */
47    public static function getPageTitle($pageId)
48    {
49        $name = $pageId;
50        // The title of the page
51        if (useHeading('navigation')) {
52
53            // $title = $page['title'] can not be used to retrieve the title
54            // because it didn't encode the HTML tag
55            // for instance if <math></math> is used, the output must have &lgt ...
56            // otherwise browser may add quote and the math plugin will not work
57            // May be a solution was just to encode the output
58
59            /**
60             * Bug:
61             * PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 98570240 bytes)
62             * in inc/Cache/CacheInstructions.php on line 44
63             * It was caused by a recursion in the rendering, it seems in {@link p_get_metadata()}
64             * The parameter METADATA_DONT_RENDER stops the recursion
65             *
66             * Don't use the below procedures, they all call the same function and render the meta
67             *   * $name = tpl_pagetitle($pageId, true);
68             *   * $title = p_get_first_heading($page['id']);
69             *
70             * In the <a href="https://www.dokuwiki.org/devel:metadata">documentation</a>,
71             * the rendering mode that they advertised for the title is `METADATA_RENDER_SIMPLE_CACHE`
72             *
73             * We have chosen METADATA_DONT_RENDER (0)
74             * because when we asks for the title of the directory,
75             * it will render the whole tree (the directory of the directory)
76             *
77             *
78             */
79            $name = p_get_metadata(cleanID($pageId), 'title', METADATA_DONT_RENDER);
80
81        }
82        return $name;
83    }
84
85    /**
86     * Replace placeholder
87     * @param Call[]|array $namespaceTemplateInstructions
88     * @param string|Page $pageValue
89     * @return array
90     */
91    public static function generateInstructionsFromDataPage(array $namespaceTemplateInstructions, $pageValue): array
92    {
93        $page = null;
94        if (is_string($pageValue)) {
95            $page = Page::createPageFromQualifiedPath($pageValue);
96        }
97        if ($pageValue instanceof Page) {
98            $page = $pageValue;
99        }
100        if ($page === null) {
101            if (PluginUtility::isDevOrTest()) {
102                throw new ExceptionComboRuntime("The page is null meaning the page value was not recognized. Bad dev.");
103            }
104        }
105
106        $instructions = [];
107        foreach ($namespaceTemplateInstructions as $call) {
108            if ($call instanceof Call) {
109                $newCall = Call::createFromCall($call);
110            } else {
111                $newCall = Call::createFromInstruction($call);
112            }
113            $instructions[] = $newCall->render($page)->toCallArray();
114        }
115        return $instructions;
116
117    }
118
119    /**
120     * @param Call[]|array $namespaceTemplateInstructions
121     * @param array $array - the data array
122     * @return array - native call stack instructions
123     */
124    public static function renderInstructionsTemplateFromDataArray(array $namespaceTemplateInstructions, array $array): array
125    {
126
127        $instructions = [];
128        foreach ($namespaceTemplateInstructions as $call) {
129            if (is_array($call)) {
130                $newCall = Call::createFromInstruction($call);
131            } else {
132                $newCall = Call::createFromCall($call);
133            }
134            $instructions[] = $newCall->renderFromData($array)->toCallArray();
135        }
136        return $instructions;
137
138    }
139
140    public static function renderStringTemplateForDataPage($stringTemplate, Page $page): string
141    {
142
143
144        return TemplateUtility::renderStringTemplateFromDataArray($stringTemplate, TemplateUtility::getMetadataDataFromPage($page));
145
146    }
147
148    /**
149     * Render a template string from a data array
150     * @param $pageTemplate
151     * @param array $array
152     * @return string
153     */
154    public static function renderStringTemplateFromDataArray($pageTemplate, array $array): string
155    {
156
157        $template = Template::create($pageTemplate);
158
159        foreach ($array as $key => $val) {
160            /**
161             * Hack: Replace every " by a ' to be able to detect/parse the title/h1 on a pipeline
162             * @see {@link \syntax_plugin_combo_pipeline}
163             */
164            $val = str_replace('"', "'", $val);
165            $template->set($key, $val);
166        }
167
168        return $template->render();
169
170    }
171
172    public static function getMetadataDataFromPage(Page $page): array
173    {
174
175        return $page->getMetadataForRendering();
176
177    }
178
179    public static function isVariable($ref): bool
180    {
181        return substr($ref, 0, 1) === TemplateUtility::VARIABLE_PREFIX;
182    }
183
184
185}
186