0
|
1 <?php
|
|
2
|
|
3 $cms["modules"]["template.mod.php"] = array(
|
|
4 "name" => "template_module_name",
|
|
5 "description" => "template_module_description",
|
|
6 "files" => array(
|
|
7 ".cms/mod/template.mod.php",
|
|
8 ".cms/css/template.css",
|
|
9 ".cms/js/template.js",
|
|
10 ".cms/lang/ru_RU.UTF-8/template.mod.php",
|
|
11 ".cms/lang/en_US.UTF-8/template.mod.php",
|
|
12 ".cms/lang/uk_UA.UTF-8/template.mod.php",
|
|
13 ),
|
|
14 );
|
|
15
|
|
16 // Return if module disabled
|
|
17 if ( ! empty( $cms["config"]["template.mod.php"]["disabled"] ) ) {
|
|
18
|
|
19 return;
|
|
20
|
|
21 } else {
|
|
22
|
|
23 // Install
|
|
24 if ( empty( $cms["config"]["template.mod.php"]["template"] ) ) {
|
|
25 $cms["config"]["template.mod.php"]["template"] = "mini";
|
|
26 }
|
|
27 if ( empty( $cms["config"]["template.mod.php"]["scripts"] ) ) {
|
|
28 $cms["config"]["template.mod.php"]["scripts"] = "";
|
|
29 }
|
|
30
|
|
31 $cms["template"] = $cms["config"]["template.mod.php"]["template"];
|
|
32
|
|
33 if ( ! isset( $cms["config"]["template.mod.php"]["disable_write_to_disk"] ) ) {
|
|
34 $cms["config"]["template.mod.php"]["disable_write_to_disk"] = true;
|
|
35 }
|
|
36
|
|
37 if ( ! isset( $cms["config"]["template.mod.php"]["headers"] ) ) {
|
|
38 $cms["config"]["template.mod.php"]["headers"] = "cache-control: max-age=0";
|
|
39 }
|
|
40
|
|
41 if ( is_admin() ) {
|
|
42 hook_add_fn( "admin", "cms_template_admin" );
|
|
43 hook_add_fn( "admin_header", "cms_template_admin_header" );
|
|
44 hook_add_fn( "api", "cms_template_api" );
|
|
45 }
|
|
46 // Вызов функции cms_template_template сделаем пораньше,
|
|
47 // чтобы в других модулях не нужно было ставить 20
|
|
48 hook_add_fn( "template", "cms_template_template", 5 );
|
|
49 hook_add_fn( "echo", "cms_template_echo" );
|
|
50 hook_add_fn( "write", "cms_template_write" );
|
|
51
|
|
52 }
|
|
53
|
|
54 function cms_template_admin_header() {
|
|
55 global $cms;
|
|
56 $conf = $cms["config"]["template.mod.php"]["menu"]["template"];
|
|
57 if ( empty( $conf["hide"] ) && empty( $cms["config"]["admin_sections"][ $conf["section"] ]["hide"] ) ) {
|
|
58 echo "<link rel=stylesheet href='{$cms['base_path']}css/template.css'>";
|
|
59 echo "<script src='{$cms['base_path']}js/template.js'></script>";
|
|
60 }
|
|
61 }
|
|
62
|
|
63 function cms_template_admin() {
|
|
64 global $cms;
|
|
65
|
|
66 $conf = $cms["config"]["template.mod.php"]["menu"]["template"];
|
|
67 if ( empty( $conf["hide"] ) && empty( $cms["config"]["admin_sections"][ $conf["section"] ]["hide"] ) ) {
|
|
68
|
|
69 // Save settings
|
|
70 if ( ! empty( $_POST["save_template"] ) ) {
|
|
71 $cms["config"]["template.mod.php"]["template"] = $_POST["template"];
|
|
72 $cms["config"]["template.mod.php"]["disable_write_to_disk"] = empty( $_POST["enable_cache"] );
|
|
73 cms_save_config();
|
|
74 cms_clear_cache();
|
|
75 header( "Location: {$cms['base_path']}{$cms['config']['admin.mod.php']['admin_url']}" );
|
|
76 $cms["hooks"]["admin"]["next"] = ""; // Предотвратить выдачу админки
|
|
77 return;
|
|
78 }
|
|
79
|
|
80 // Save template headers
|
|
81 if ( ! empty( $_POST["save_template_headers"] ) ) {
|
|
82 $cms["config"]["template.mod.php"]["headers"] = $_POST["template_headers"];
|
|
83 cms_save_config();
|
|
84 header( "Location: {$cms['base_path']}{$cms['config']['admin.mod.php']['admin_url']}" );
|
|
85 $cms["hooks"]["admin"]["next"] = ""; // Предотвратить выдачу админки
|
|
86 return;
|
|
87 }
|
|
88
|
|
89 // Create menu item
|
|
90 if ( empty( $cms["config"]["template.mod.php"]["menu"]["template"] ) ) {
|
|
91 $cms["config"]["template.mod.php"]["menu"]["template"] = array(
|
|
92 "title" => "template_module_name",
|
|
93 "sort" => 70,
|
|
94 "section" => "settings",
|
|
95 );
|
|
96 cms_save_config();
|
|
97 }
|
|
98
|
|
99 $options = "";
|
|
100 foreach( glob( "{$cms['cms_dir']}/*/html.php" ) as $path_html_php ) {
|
|
101 $template = preg_replace( "/.*\/([^\/]+)\/html\.php/u", "$1", $path_html_php );
|
|
102 if ( substr( $template, 0, 6 ) !== "admin." ) {
|
|
103 $options .= "<div class=option value='{$template}'>{$template}</div>";
|
|
104 }
|
|
105 }
|
|
106
|
|
107 cms_template_load_settings();
|
|
108 $template_files_title = "<div class=title>" . __( "editable_files" ) . "</div>";
|
|
109 $template_files = "";
|
|
110 if ( isset( $cms["templates"] ) && is_array( $cms["templates"] ) ) {
|
|
111 foreach( $cms["templates"][ $cms["config"]["template.mod.php"]["template"] ]["files"] as $file ) {
|
|
112 $template_files .= "<div class=file>{$file}</div>";
|
|
113 }
|
|
114 }
|
|
115 if ( empty( $template_files ) ) {
|
|
116 $template_files = "<div class=no-files>" . __( "no_editable_files" ) . "</div>";
|
|
117 }
|
|
118
|
|
119 $tr_title = __( "help" );
|
|
120 $tr_current = __( "current_template" );
|
|
121 $tr_save = __( "save" );
|
|
122 $tr_upl = __( "install_template" );
|
|
123 if ( $cms["config"]["template.mod.php"]["disable_write_to_disk"] ) {
|
|
124 $enable_cache = "";
|
|
125 } else {
|
|
126 $enable_cache = "checked";
|
|
127 }
|
|
128 $headers_title = __( "headers_title" );
|
|
129
|
|
130 // Справка для шаблона определяется в файле template.settings.php
|
|
131 $help = __( "help", $cms["config"]["template.mod.php"]["template"] );
|
|
132 if ( $help === "help" ) $help = "";
|
|
133
|
|
134 // Display settings
|
|
135 $page = "
|
|
136 <div class=settings>
|
|
137 <div class=template-install>
|
|
138 <div class=upload_dnd>
|
|
139 <input id=template-upload type=file name='myfile[]' multiple class=files>
|
|
140 {$tr_upl}
|
|
141 </div>
|
|
142 </div>
|
|
143 <div class=template>
|
|
144 <form method=post>
|
|
145 <div>{$tr_current}</div>
|
|
146 <input name=template autocomplete=off type=hidden value='{$cms["config"]["template.mod.php"]["template"]}'>
|
|
147
|
|
148 <div class=template-select-grid>
|
|
149 <div class=field-select>
|
|
150 <div class=value>{$cms["config"]["template.mod.php"]["template"]}</div>
|
|
151 <div class=icon></div>
|
|
152 </div>
|
|
153 <div class=field-options>
|
|
154 {$options}
|
|
155 </div>
|
|
156 </div>
|
|
157
|
|
158 <label>
|
|
159 <input type=checkbox name=enable_cache {$enable_cache}>
|
|
160 <span class=enable-cache>" . __( "enable_cache" ) . "</span>
|
|
161 </label>
|
|
162
|
|
163 <button name=save_template value=save>{$tr_save}</button>
|
|
164 </form>
|
|
165 </div>
|
|
166 <form method=post class=template-headers>
|
|
167 <div class=template-headers-title>{$headers_title}</div>
|
|
168 <textarea name=template_headers>{$cms['config']['template.mod.php']['headers']}</textarea>
|
|
169 <button name=save_template_headers value=save>{$tr_save}</button>
|
|
170 </form>
|
|
171 <div class=template-manual>
|
|
172 <div>{$tr_title}</div>
|
|
173 {$help}
|
|
174 </div>
|
|
175 <div class=template-files>
|
|
176 {$template_files_title}
|
|
177 {$template_files}
|
|
178 </div>
|
|
179 </div>
|
|
180
|
|
181 <div class='template-editor-bg hidden'>
|
|
182 <div class=template-editor-grid>
|
|
183 <div class=template-editor-header>
|
|
184 <div class=close-template-button></div>
|
|
185 <div class=save-template-button></div>
|
|
186 <span class=template-editor-title></span>
|
|
187 </div>
|
|
188 <div class=template-editor>
|
|
189 <textarea></textarea>
|
|
190 </div>
|
|
191 <div class=snip-grid>
|
|
192 <div class=css>
|
|
193 <div data-type=snip data-otag='@media (min-width: px) and (max-width: px) {\n' data-ctag='\n}'>@media (min) and (max)</div>
|
|
194 <div data-type=snip data-otag='/* ' data-ctag=' */'>/* comment */</div>
|
|
195 <a href='{$cms['base_path']}man/{$cms['config']['locale']}/hint_css.html' target=_blank>" . __( "hint_css" ) . "</a>
|
|
196 </div>
|
|
197 <div class=php>
|
|
198 <a href='{$cms['base_path']}man/{$cms['config']['locale']}/hint_php.html' target=_blank>" . __( "hint_php" ) . "</a>
|
|
199 </div>
|
|
200 <div class=html>
|
|
201 <a href='{$cms['base_path']}man/{$cms['config']['locale']}/hint_html.html' target=_blank>" . __( "hint_html" ) . "</a>
|
|
202 </div>
|
|
203 </div>
|
|
204 </div>
|
|
205 </div>
|
|
206 ";
|
|
207
|
|
208 $cms["admin_pages"]["template"] = $page;
|
|
209
|
|
210 }
|
|
211
|
|
212 }
|
|
213
|
|
214 // Load template settings
|
|
215 function cms_template_load_settings() {
|
|
216 global $cms;
|
|
217 $settings = "{$cms['cms_dir']}/{$cms['config']['template.mod.php']['template']}/template.settings.php";
|
|
218 if ( file_exists( $settings ) ) {
|
|
219 include( $settings );
|
|
220 }
|
|
221 }
|
|
222
|
|
223
|
|
224 function cms_template_api() {
|
|
225 global $cms;
|
|
226
|
|
227 if ( ! empty( $_POST["fn"] ) ) {
|
|
228
|
|
229 switch ( $_POST["fn"] ) {
|
|
230
|
|
231 case "clear_cache":
|
|
232 cms_clear_cache();
|
|
233 echo( json_encode( array(
|
|
234 "info_text" => __( "cache_cleared" ),
|
|
235 "info_class" => "info-success",
|
|
236 "info_time" => 5000,
|
|
237 ) ) );
|
|
238 return;
|
|
239 break;
|
|
240
|
|
241 case "get_template_file":
|
|
242 $file = file_get_contents( $cms["site_dir"] . "/" . $_POST["file"] );
|
|
243 if ( $file !== false ) {
|
|
244 $ok = "true";
|
|
245 } else {
|
|
246 $ok = "false";
|
|
247 }
|
|
248 echo( json_encode( array(
|
|
249 "ok" => $ok,
|
|
250 "file" => $file,
|
|
251 ) ) );
|
|
252 return;
|
|
253 break;
|
|
254
|
|
255 case "save_template_file":
|
|
256 $file = file_put_contents( $cms["site_dir"] . "/" . $_POST["file"], $_POST["content"] );
|
|
257 if ( $file !== false ) {
|
|
258 $ok = "true";
|
|
259 $msg = __( "saved" );
|
|
260 $class = "info-success";
|
|
261 } else {
|
|
262 $ok = "false";
|
|
263 $msg = __( "save_error" );
|
|
264 $class = "info-error";
|
|
265 }
|
|
266 cms_clear_cache();
|
|
267 echo( json_encode( array(
|
|
268 "ok" => $ok,
|
|
269 "info_text" => $msg,
|
|
270 "info_class" => $class,
|
|
271 "info_time" => 5000,
|
|
272 ) ) );
|
|
273 return;
|
|
274 break;
|
|
275
|
|
276 case "install_template":
|
|
277 $success = true;
|
|
278 //$text = "dev.coffee-cms.ru";
|
|
279 //if ( $cms["url"]["host"] !== $text )
|
|
280 foreach ( $_FILES["myfile"]["name"] as $n => $name ) {
|
|
281 if ( $_FILES["myfile"]["error"][$n] ) {
|
|
282 $success = false;
|
|
283 $text = str_replace( "xxx", $name, __( "upload_error_xxx" ) );
|
|
284 break;
|
|
285 } else {
|
|
286 // Unpack Template
|
|
287 // Object Oriented Style for future compability with PHP 8
|
|
288 $zip = new ZipArchive;
|
|
289 if ( $zip->open( $_FILES["myfile"]["tmp_name"][$n] ) === TRUE ) {
|
|
290 $zip->extractTo( $cms["site_dir"] );
|
|
291 $zip->close();
|
|
292 $text = __( "install_success" );
|
|
293 } else {
|
|
294 $success = false;
|
|
295 $text = str_replace( "xxx", $name, __( "cant_unzip_xxx" ) );
|
|
296 break;
|
|
297 }
|
|
298 }
|
|
299 }
|
|
300
|
|
301 if ( $success ) {
|
|
302 echo( json_encode( array(
|
|
303 "info_text" => $text,
|
|
304 "info_class" => "info-success",
|
|
305 "info_time" => 5000,
|
|
306 ) ) );
|
|
307 return;
|
|
308 } else {
|
|
309 echo( json_encode( array(
|
|
310 "info_text" => $text,
|
|
311 "info_class" => "info-error",
|
|
312 "info_time" => 10000,
|
|
313 ) ) );
|
|
314 return;
|
|
315 }
|
|
316 break;
|
|
317
|
|
318 }
|
|
319 }
|
|
320 }
|
|
321
|
|
322
|
|
323 function cms_template_template() {
|
|
324 global $cms;
|
|
325 if ( is_file( $cms["cms_file"] ) ) {
|
|
326 if ( substr( $cms["cms_file"], -4 ) === ".php" || strpos( substr( $cms["cms_file"], strlen( $cms["cms_dir"] ) ), "/." ) !== false ) {
|
|
327 $cms["status"] = "404";
|
|
328 } else {
|
|
329 $cms["output"]["from"] = $cms["cms_file"];
|
|
330 $cms["output"]["to"] = $cms["site_dir"] . "/" . $cms["url"]["path"];
|
|
331 $cms["status"] = "200";
|
|
332 }
|
|
333 } else {
|
|
334 ob_start();
|
|
335 include( "{$cms['cms_dir']}/{$cms['template']}/html.php" );
|
|
336 $cms["output"] = ob_get_clean();
|
|
337 }
|
|
338 }
|
|
339
|
|
340
|
|
341 function cms_template_echo() {
|
|
342 global $cms;
|
|
343
|
|
344 $headers = array();
|
|
345 if ( substr( $cms["template"], 0, 6 ) !== "admin." ) {
|
|
346 $lines = explode( "\n", $cms["config"]["template.mod.php"]["headers"] );
|
|
347 foreach ( $lines as $line ) {
|
|
348 $line = trim( $line );
|
|
349 if ( ! empty( $line ) ) {
|
|
350 $headers[] = $line;
|
|
351 }
|
|
352 }
|
|
353 }
|
|
354
|
|
355 if ( is_array( $cms["output"] ) ) {
|
|
356 if ( $cms["status"] === "200" ) {
|
|
357 $types = array(
|
|
358 "css" => "text/css",
|
|
359 "js" => "application/javascript",
|
|
360 "svg" => "image/svg+xml",
|
|
361 );
|
|
362 $ext = preg_replace( "/.*\./u", "", $cms["output"]["to"] );
|
|
363 if ( isset( $types[$ext] ) ) {
|
|
364 $mime = $types[$ext];
|
|
365 } else {
|
|
366 $mime = "";
|
|
367 }
|
|
368 header( "Content-Type: {$mime}" );
|
|
369 header( "{$_SERVER['SERVER_PROTOCOL']} 200 OK" ); // fix server 404
|
|
370 foreach ( $headers as $header ) {
|
|
371 header( $header );
|
|
372 }
|
|
373 cms_readfile( $cms["output"]["from"], false );
|
|
374 } else {
|
|
375 header( "{$_SERVER['SERVER_PROTOCOL']} 404 Not Found" );
|
|
376 }
|
|
377 } else {
|
|
378 switch ( $cms["status"] ) {
|
|
379 case "200":
|
|
380 header( "{$_SERVER['SERVER_PROTOCOL']} 200 OK" ); // fix server 404
|
|
381 foreach ( $headers as $header ) {
|
|
382 header( $header );
|
|
383 }
|
|
384 echo $cms["output"];
|
|
385 break;
|
|
386 case "404":
|
|
387 header( "{$_SERVER['SERVER_PROTOCOL']} 404 Not Found" );
|
|
388 echo $cms["output"];
|
|
389 // Для админа выводится текст страницы
|
|
390 // а для анонима сообщение что не найдена
|
|
391 break;
|
|
392 case "301":
|
|
393 header( "Location: {$cms['status_301_location']}", true, 301 );
|
|
394 break;
|
|
395 case "302":
|
|
396 header( "Location: {$cms['status_302_location']}", true, 302 );
|
|
397 break;
|
|
398 }
|
|
399 }
|
|
400 }
|
|
401
|
|
402
|
|
403 function cms_template_write() {
|
|
404 global $cms;
|
|
405
|
|
406 if ( ! empty( $cms["config"]["template.mod.php"]["disable_write_to_disk"] ) ) {
|
|
407 return;
|
|
408 }
|
|
409
|
|
410 if ( $cms["status"] !== "200" ) {
|
|
411 return;
|
|
412 }
|
|
413
|
|
414 // write to disk
|
|
415 umask( 0 );
|
|
416
|
|
417 if ( is_array( $cms["output"] ) ) {
|
|
418
|
|
419 $dirs = explode( "/", str_replace( $cms["site_dir"] . "/", "", $cms["output"]["to"] ) );
|
|
420 $dir = $cms["site_dir"];
|
|
421 $file_name = array_pop( $dirs );
|
|
422 foreach ( $dirs as $path ) {
|
|
423 $dir .= "/" . $path;
|
|
424 if ( ! is_dir( $dir ) ) {
|
|
425 mkdir( $dir, 0777, false );
|
|
426 } elseif( is_file( $dir ) ) {
|
|
427 unlink( $dir );
|
|
428 mkdir( $dir, 0777, false );
|
|
429 }
|
|
430 }
|
|
431
|
|
432 if ( ! file_exists( $cms["output"]["to"] ) ) {
|
|
433 $tmp_name = $cms["site_dir"] . "/uploads/.tmp_" . cms_uid() . "_" . pathinfo( $cms["output"]["to"], PATHINFO_BASENAME );
|
|
434 copy( $cms["output"]["from"], $tmp_name );
|
|
435 rename( $tmp_name, $cms["output"]["to"] );
|
|
436 }
|
|
437
|
|
438 } else {
|
|
439
|
|
440 // create dirs
|
|
441 $dirs = explode( "/", $cms["url"]["path"] );
|
|
442 $dir = $cms["site_dir"];
|
|
443 $file_name = array_pop( $dirs );
|
|
444 foreach ( $dirs as $path ) {
|
|
445 $dir .= "/" . $path;
|
|
446 if ( ! file_exists( $dir ) ) {
|
|
447 mkdir( $dir, 0777, false );
|
|
448 } elseif( is_file( $dir ) ) {
|
|
449 unlink( $dir );
|
|
450 mkdir( $dir, 0777, false );
|
|
451 }
|
|
452 }
|
|
453
|
|
454 if ( ! $file_name ) {
|
|
455 $file = $dir . "/index.html";
|
|
456 } else {
|
|
457 $file = $dir . "/" . $file_name;
|
|
458 }
|
|
459
|
|
460 if ( ! file_exists( $file ) ) {
|
|
461 $tmp_name = $cms["site_dir"] . "/uploads/.tmp_" . cms_uid() . "_" . pathinfo( $file, PATHINFO_BASENAME );
|
|
462 file_put_contents( $tmp_name, $cms["output"], LOCK_EX );
|
|
463 chmod( $tmp_name, 0666 );
|
|
464 rename( $tmp_name, $file );
|
|
465 }
|
|
466
|
|
467 }
|
|
468 }
|
|
469
|
|
470
|
|
471 function cms_clear_cache() {
|
|
472 global $cms;
|
|
473
|
|
474 do_hook( "clear_cache" );
|
|
475
|
|
476 // array for delete dirs
|
|
477 $dirs = array();
|
|
478
|
|
479 // search all pages in database
|
|
480 if ( ! empty( $cms["base"] ) ) {
|
|
481 if ( $res = mysqli_query( $cms["base"], "SELECT `url` FROM `pages`" ) ) {
|
|
482 while ( $page = mysqli_fetch_assoc( $res ) ) {
|
|
483 if ( $page["url"] === "/" ) $page["url"] = "";
|
|
484 $file = $cms["site_dir"] . "/" . $page["url"];
|
|
485 if ( substr( $file, -1 ) === "/" ) {
|
|
486 $file .= "index.html";
|
|
487 } elseif ( is_dir( $file ) ) {
|
|
488 // for
|
|
489 // /parent/child
|
|
490 // /parent
|
|
491 $file .= "/index.html";
|
|
492 }
|
|
493 if ( is_file( $file ) ) unlink( $file );
|
|
494 // Add dirs to remove queue
|
|
495 $dir = "/" . $page["url"];
|
|
496 while ( $dir && $dir !== "/" && $dir !== "\\" ) {
|
|
497 $new_dir = $cms["site_dir"] . $dir;
|
|
498 if ( ! in_array( $new_dir, $dirs ) ) {
|
|
499 $dirs[] = $new_dir;
|
|
500 }
|
|
501 $dir = dirname( $dir );
|
|
502 }
|
|
503 }
|
|
504 }
|
|
505 }
|
|
506
|
|
507 // delete template files
|
|
508 $queue[] = $cms["cms_dir"];
|
|
509 while ( $cur = array_shift( $queue ) ) {
|
|
510 if ( is_dir( $cur ) ) {
|
|
511 // add current dir to array for delete
|
|
512 array_push( $dirs, str_replace( ".cms/", "", $cur ) );
|
|
513 // search children files and dirs
|
|
514 $queue = array_merge( $queue, glob( $cur . "/*" ) );
|
|
515 } else {
|
|
516 $file = str_replace( ".cms/", "", $cur );
|
|
517 if ( is_file( $file ) ) unlink( $file );
|
|
518 }
|
|
519 }
|
|
520
|
|
521 // delete dirs
|
|
522 rsort( $dirs );
|
|
523 foreach ( $dirs as $dir ) {
|
|
524 if ( is_dir( $dir ) && $dir !== $cms["cms_dir"] && $dir !== $cms["site_dir"] ) {
|
|
525 if ( is_dir_and_empty( $dir ) ) {
|
|
526 rmdir( $dir );
|
|
527 }
|
|
528 }
|
|
529 }
|
|
530
|
|
531 }
|