Completed
Push — master ( db24d0...9b8153 )
by Nazar
04:35
created

Cache::cache_compressed_includes_files()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 25
rs 8.5806
cc 4
eloc 20
nc 4
nop 4
1
<?php
2
/**
3
 * @package   CleverStyle CMS
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2014-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\Page\Includes;
9
use
10
	cs\Language,
11
	cs\Page\Includes_processing;
12
13
trait Cache {
14
	/**
15
	 * Creates cached version of given HTML, JS and CSS files.
16
	 * Resulting files names consist of `$filename_prefix` and extension.
17
	 *
18
	 * @param string     $target_file_path
19
	 * @param string[][] $includes                   Array of paths to files, may have keys: `css` and/or `js` and/or `html`
20
	 * @param bool       $vulcanization              Whether to put combined files separately or to make includes built-in (vulcanization)
21
	 * @param string[][] $not_embedded_resources_map Resources like images/fonts might not be embedded into resulting CSS because of big size or CSS/JS because
22
	 *                                               of CSP
23
	 *
24
	 * @return array
25
	 */
26
	protected function cache_compressed_includes_files ($target_file_path, $includes, $vulcanization, &$not_embedded_resources_map) {
27
		$local_includes = [];
28
		foreach ($includes as $extension => $files) {
29
			$not_embedded_resources = [];
30
			$content                = $this->cache_compressed_includes_files_single(
31
				$extension,
32
				$target_file_path,
33
				$files,
34
				$vulcanization,
35
				$not_embedded_resources
36
			);
37
			foreach ($not_embedded_resources as &$resource) {
38
				if (strpos($resource, '/') !== 0) {
39
					$resource = "/storage/pcache/$resource";
40
				}
41
			}
42
			unset($resource);
43
			$file_path = "$target_file_path.$extension";
44
			file_put_contents($file_path, gzencode($content, 9), LOCK_EX | FILE_BINARY);
45
			$relative_path                              = 'storage/pcache/'.basename($file_path).'?'.substr(md5($content), 0, 5);
46
			$local_includes[$extension]                 = $relative_path;
47
			$not_embedded_resources_map[$relative_path] = $not_embedded_resources;
48
		}
49
		return $local_includes;
50
	}
51
	/**
52
	 * @param string   $extension
53
	 * @param string   $target_file_path
54
	 * @param string[] $files
55
	 * @param bool     $vulcanization          Whether to put combined files separately or to make includes built-in (vulcanization)
56
	 * @param string[] $not_embedded_resources Resources like images/fonts might not be embedded into resulting CSS because of big size or CSS/JS because of CSP
57
	 *
58
	 * @return mixed
59
	 */
60
	protected function cache_compressed_includes_files_single ($extension, $target_file_path, $files, $vulcanization, &$not_embedded_resources) {
61
		$content = '';
62
		switch ($extension) {
63
			/**
64
			 * Insert external elements into resulting css file.
65
			 * It is needed, because those files will not be copied into new destination of resulting css file.
66
			 */
67
			case 'css':
68
				/**
69
				 * @param string $content
70
				 * @param string $file
71
				 *
72
				 * @return string
73
				 */
74
				$callback = function ($content, $file) use (&$not_embedded_resources) {
75
					return $content.Includes_processing::css(file_get_contents($file), $file, $not_embedded_resources);
76
				};
77
				break;
78
			/**
79
			 * Combine css and js files for Web Component into resulting files in order to optimize loading process
80
			 */
81
			case 'html':
82
				/**
83
				 * For CSP-compatible HTML files we need to know destination to put there additional JS/CSS files
84
				 *
85
				 * @param string $content
86
				 * @param string $file
87
				 *
88
				 * @return string
89
				 */
90
				$callback = function ($content, $file) use ($target_file_path, $vulcanization, &$not_embedded_resources) {
91
					$base_target_file_path = "$target_file_path-".basename($file).'+'.substr(md5($file), 0, 5);
92
					return $content.Includes_processing::html(
93
						file_get_contents($file),
94
						$file,
95
						$base_target_file_path,
96
						$vulcanization,
97
						$not_embedded_resources
98
					);
99
				};
100
				break;
101
			case 'js':
102
				/**
103
				 * @param string $content
104
				 * @param string $file
105
				 *
106
				 * @return string
107
				 */
108
				$callback = function ($content, $file) {
109
					return $content.Includes_processing::js(file_get_contents($file));
110
				};
111
				if (substr($target_file_path, -7) == ':System') {
112
					$content = 'window.cs={Language:'._json_encode(Language::instance()).'};';
113
					$content .= 'window.requirejs={paths:'._json_encode($this->get_requirejs_paths()).'};';
114
				}
115
		}
116
		/** @noinspection PhpUndefinedVariableInspection */
117
		return array_reduce($files, $callback, $content);
118
	}
119
}
120