PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.25
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.25
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Services / ShortCodeParser / SmartCodeParser.php

SmartCodeParser.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.25, at app/Services/ShortCodeParser/SmartCodeParser.php

256 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Services\ShortCodeParser;
4
5 use FluentCart\App\App;
6 use FluentCart\Framework\Container\Contracts\BindingResolutionException;
7 use FluentCart\Framework\Foundation\Application;
8 use FluentCart\Framework\Support\Arr;
9 use FluentCart\Framework\Support\Collection;
10
11 class SmartCodeParser
12 {
13
14 use ValueTransformer;
15
16 /**
17 * The application instance.
18 *
19 * @var Application
20 */
21 protected Application $app;
22
23 /**
24 * Configuration instance.
25 *
26 * @var ?Collection
27 */
28 protected ?Collection $config;
29
30 /**
31 * Hook Prefix.
32 *
33 * @var String
34 */
35 protected string $hookPrefix;
36
37 /**
38 * SmartCodeParser constructor.
39 */
40 public function __construct()
41 {
42 $application = App::getInstance();
43 $pluginConfig = $application->make('config')->get('shortcode');
44 $this->app = $application;
45 $this->config = new Collection($pluginConfig);
46 $this->hookPrefix = App::config()->get('hook_prefix');
47 }
48
49 /**
50 * Parses the given code using the appropriate parser class.
51 *
52 * @param string $code
53 * @param array $data
54 * @return string
55 * @throws BindingResolutionException
56 */
57 public function parse(string $code, array $data): ?string
58 {
59 return $this->parseCode($code, $data);
60 }
61
62 /**
63 * Parses the given code using the appropriate parser class.
64 *
65 * @param string $code
66 * @param mixed $data
67 * @return string
68 * @throws BindingResolutionException
69 */
70 public function parseCode(string $code, $data): ?string
71 {
72 $code = trim($code);
73
74 $explodedCode = explode('.', $code);
75 if (count($explodedCode) <= 1) {
76 return apply_filters($this->hookPrefix . 'smartcode_fallback', $code, $data);
77 }
78 $parserReference = $this->getParseHandlerReference($code);
79 $parseHandler = Arr::get($parserReference, 'handler');
80
81 if (!$parseHandler) {
82 return apply_filters($this->hookPrefix . 'smartcode_fallback', $code, $data);
83 }
84
85 $parser = $this->app->makeWith($parseHandler, ['data' => $data]);
86
87 $parsedValue = "";
88
89 if (method_exists($parser, 'parse')) {
90 $parsedValue = $parser->parse(
91 $parserReference['accessor'],
92 $parserReference['template'],
93 $this->evaluateCondition($parserReference['template'])
94 );
95
96 }
97
98 return $this->transform($parsedValue, $code, $data);
99 }
100
101 /**
102 * Retrieves the appropriate parser class for the given code.
103 *
104 * @param string $code
105 * @return ?string
106 */
107 public function getParserClass(string $code): ?string
108 {
109 $parsers = $this->config->get('parsers');
110 return Arr::get($parsers, $code);
111 }
112
113 /**
114 * Retrieves the parse handler reference for the given template.
115 *
116 * @param string $template
117 * @return array
118 */
119 public function getParseHandlerReference(string $template): array
120 {
121 static $reference = [];
122
123 $parserData = [
124 'parser' => null,
125 'accessor' => null,
126 'template' => $template,
127 'handler' => null,
128 ];
129
130 $templateCode = $this->getReference($template);
131
132 if (!isset($reference[$templateCode])) {
133 if (str_contains($templateCode, '.')) {
134 $parsed = explode($this->config->get('parser_separator'), $templateCode);
135 $parserData['parser'] = $parsed[0];
136 $parserData['accessor'] = implode($this->config->get('parser_separator'), array_slice($parsed, 1));
137 } else {
138 //If no parser is found, GlobalParser class will be called if exist
139 $parserData['parser'] = 'global';
140 $parserData['accessor'] = $templateCode;
141 }
142
143 $parserData['handler'] = $this->getParserClass($parserData['parser']);
144 $reference[$template] = $parserData;
145 }
146 if (!isset($reference[$template]) && isset($reference[$templateCode])) {
147 $reference[$template] = $reference[$templateCode];
148 }
149
150 return $reference[$template];
151 }
152
153 /**
154 * Retrieves the reference for the given template.
155 *
156 * @param string $template
157 * @return string
158 */
159 public function getReference(string $template): string
160 {
161 $template = explode('|', $template);
162 $template = $template [0];
163 $templateString = $template;
164
165 $templateReferences = $this->config->get('template_references');
166
167 if (isset($templateReferences[$template])) {
168 $templateString = $templateReferences[$template];
169 }
170
171 $parserReferences = $this->config->get('parser_references');
172
173 foreach ($parserReferences as $reference => $fields) {
174 if (in_array($templateString, $fields)) {
175 $templateString = $reference . $this->config->get('parser_separator') . $templateString;
176
177 break;
178 }
179 }
180
181 return $templateString;
182 }
183
184 /**
185 * Parses the template with the given data.
186 *
187 * @param string $template
188 * @param array $data
189 * @return string
190 * @throws BindingResolutionException
191 */
192 public function parseTemplate(string $template, array $data): string
193 {
194 $templateParts = $this->getTemplateWrapper();
195
196
197 $start = preg_quote($templateParts['start'], '/');
198 $end = preg_quote($templateParts['end'], '/');
199
200 $pattern = '/(' . $start . '|##)+(.*?)(' . $end . '|##)/';
201 // $pattern = '/(' . $start . '|##)((?:[^' . $end[0] . '#]|(?R))*)(' . $end . '|##)/';
202
203
204 return preg_replace_callback($pattern, function ($matches) use ($data) {
205 if (empty($matches[2])) {
206 return apply_filters($this->hookPrefix . 'smartcode_fallback', $matches[0], $data);
207 }
208 $code = trim($matches[2]);
209 $transformed = $this->parseCode($code, $data);
210
211 if($transformed === $code) {
212 return $matches[0];
213 }
214
215 return $transformed;
216
217 }, $template);
218 }
219
220 /**
221 * Configures the parser with new settings.
222 * @return SmartCodeParser
223 */
224 public static function make(): SmartCodeParser
225 {
226 return new static();
227 }
228
229 /**
230 * Retrieves the template wrapper parts.
231 *
232 * @return array
233 */
234 public function getTemplateWrapper(): array
235 {
236 preg_match('/^(.*):template:(.*)$/', $this->config->get('template_string'), $matches);
237
238 return [
239 'start' => $matches[1],
240 'end' => $matches[2],
241 ];
242 }
243
244 /**
245 * Wraps the given code with the template wrapper.
246 *
247 * @param string $code
248 * @return string
249 */
250 public function wrapSmartCode(string $code): string
251 {
252 $wrapper = $this->getTemplateWrapper();
253 return $wrapper['start'] . $code . $wrapper['end'];
254 }
255 }
256