Commit | Line | Data |
---|---|---|
98e9fb33 TO |
1 | <?php |
2 | namespace Civi\Angular; | |
3 | ||
4 | class ChangeSet implements ChangeSetInterface { | |
5 | ||
6 | /** | |
7 | * Update a listing of resources. | |
8 | * | |
9 | * @param array $changeSets | |
10 | * Array(ChangeSet). | |
11 | * @param string $resourceType | |
12 | * Ex: 'requires', 'settings' | |
13 | * @param array $resources | |
14 | * The list of resources. | |
15 | * @return mixed | |
16 | */ | |
17 | public static function applyResourceFilters($changeSets, $resourceType, $resources) { | |
18 | if ($resourceType === 'partials') { | |
19 | return self::applyHtmlFilters($changeSets, $resources); | |
20 | } | |
21 | foreach ($changeSets as $changeSet) { | |
22 | /** @var ChangeSet $changeSet */ | |
23 | foreach ($changeSet->resFilters as $filter) { | |
24 | if ($filter['resourceType'] === $resourceType) { | |
25 | $resources = call_user_func($filter['callback'], $resources); | |
26 | } | |
27 | } | |
28 | } | |
29 | return $resources; | |
30 | } | |
31 | ||
32 | /** | |
33 | * Update a set of HTML snippets. | |
34 | * | |
35 | * @param array $changeSets | |
36 | * Array(ChangeSet). | |
37 | * @param array $strings | |
38 | * Array(string $path => string $html). | |
39 | * @return array | |
40 | * Updated list of $strings. | |
41 | * @throws \CRM_Core_Exception | |
42 | */ | |
43 | private static function applyHtmlFilters($changeSets, $strings) { | |
44 | $coder = new Coder(); | |
45 | ||
46 | foreach ($strings as $path => $html) { | |
47 | /** @var \phpQueryObject $doc */ | |
48 | $doc = NULL; | |
49 | ||
50 | // Most docs don't need phpQueryObject. Initialize phpQuery on first match. | |
51 | ||
52 | foreach ($changeSets as $changeSet) { | |
53 | /** @var ChangeSet $changeSet */ | |
54 | foreach ($changeSet->htmlFilters as $filter) { | |
55 | if (preg_match($filter['regex'], $path)) { | |
56 | if ($doc === NULL) { | |
57 | $doc = \phpQuery::newDocument($html, 'text/html'); | |
58 | if (\CRM_Core_Config::singleton()->debug && !$coder->checkConsistentHtml($html)) { | |
59 | throw new \CRM_Core_Exception("Cannot process $path: inconsistent markup. Use check-angular.php to investigate."); | |
60 | } | |
61 | } | |
62 | call_user_func($filter['callback'], $doc, $path); | |
63 | } | |
64 | } | |
65 | } | |
66 | ||
67 | if ($doc !== NULL) { | |
68 | $strings[$path] = $coder->encode($doc); | |
69 | } | |
70 | } | |
71 | return $strings; | |
72 | } | |
73 | ||
74 | /** | |
75 | * @var string | |
76 | */ | |
77 | protected $name; | |
78 | ||
79 | /** | |
80 | * @var array | |
81 | * Each item is an array with keys: | |
82 | * - resourceType: string | |
83 | * - callback: function | |
84 | */ | |
c64f69d9 | 85 | protected $resFilters = []; |
98e9fb33 TO |
86 | |
87 | /** | |
88 | * @var array | |
89 | * Each item is an array with keys: | |
90 | * - regex: string | |
91 | * - callback: function | |
92 | */ | |
c64f69d9 | 93 | protected $htmlFilters = []; |
98e9fb33 TO |
94 | |
95 | /** | |
96 | * @param string $name | |
97 | * Symbolic name for this changeset. | |
98 | * @return \Civi\Angular\ChangeSetInterface | |
99 | */ | |
100 | public static function create($name) { | |
101 | $changeSet = new ChangeSet(); | |
102 | $changeSet->name = $name; | |
103 | return $changeSet; | |
104 | } | |
105 | ||
106 | /** | |
107 | * Declare that $module requires additional dependencies. | |
108 | * | |
109 | * @param string $module | |
110 | * @param string|array $dependencies | |
111 | * @return ChangeSet | |
112 | */ | |
113 | public function requires($module, $dependencies) { | |
114 | $dependencies = (array) $dependencies; | |
115 | return $this->alterResource('requires', | |
116 | function ($values) use ($module, $dependencies) { | |
117 | if (!isset($values[$module])) { | |
c64f69d9 | 118 | $values[$module] = []; |
98e9fb33 TO |
119 | } |
120 | $values[$module] = array_unique(array_merge($values[$module], $dependencies)); | |
121 | return $values; | |
122 | }); | |
123 | } | |
124 | ||
125 | /** | |
126 | * Declare a change to a resource. | |
127 | * | |
128 | * @param string $resourceType | |
129 | * @param callable $callback | |
130 | * @return ChangeSet | |
131 | */ | |
132 | public function alterResource($resourceType, $callback) { | |
c64f69d9 | 133 | $this->resFilters[] = [ |
98e9fb33 TO |
134 | 'resourceType' => $resourceType, |
135 | 'callback' => $callback, | |
c64f69d9 | 136 | ]; |
98e9fb33 TO |
137 | return $this; |
138 | } | |
139 | ||
140 | /** | |
141 | * Declare a change to HTML. | |
142 | * | |
143 | * @param string $file | |
144 | * A file name, wildcard, or regex. | |
145 | * Ex: '~/crmHello/intro.html' (filename) | |
146 | * Ex: '~/crmHello/*.html' (wildcard) | |
147 | * Ex: ';(Edit|List)Ctrl\.html$;' (regex) | |
148 | * @param callable $callback | |
149 | * Function which accepts up to two parameters: | |
150 | * - phpQueryObject $doc | |
151 | * - string $path | |
152 | * @return ChangeSet | |
153 | */ | |
154 | public function alterHtml($file, $callback) { | |
c64f69d9 | 155 | $this->htmlFilters[] = [ |
98e9fb33 TO |
156 | 'regex' => ($file{0} === ';') ? $file : $this->createRegex($file), |
157 | 'callback' => $callback, | |
c64f69d9 | 158 | ]; |
98e9fb33 TO |
159 | return $this; |
160 | } | |
161 | ||
162 | /** | |
163 | * Convert a string with a wildcard (*) to a regex. | |
164 | * | |
165 | * @param string $filterExpr | |
166 | * Ex: "/foo/*.bar" | |
167 | * @return string | |
168 | * Ex: ";^/foo/[^/]*\.bar$;" | |
169 | */ | |
170 | protected function createRegex($filterExpr) { | |
171 | $regex = preg_quote($filterExpr, ';'); | |
172 | $regex = str_replace('\\*', '[^/]*', $regex); | |
173 | $regex = ";^$regex$;"; | |
174 | return $regex; | |
175 | } | |
176 | ||
177 | /** | |
178 | * @return string | |
179 | */ | |
180 | public function getName() { | |
181 | return $this->name; | |
182 | } | |
183 | ||
184 | /** | |
185 | * @param string $name | |
186 | */ | |
187 | public function setName($name) { | |
188 | $this->name = $name; | |
189 | } | |
190 | ||
191 | } |