Merge pull request #9783 from mattwire/back_to_single_lang
[civicrm-core.git] / Civi / Angular / ChangeSet.php
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 */
85 protected $resFilters = array();
86
87 /**
88 * @var array
89 * Each item is an array with keys:
90 * - regex: string
91 * - callback: function
92 */
93 protected $htmlFilters = array();
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])) {
118 $values[$module] = array();
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) {
133 $this->resFilters[] = array(
134 'resourceType' => $resourceType,
135 'callback' => $callback,
136 );
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) {
155 $this->htmlFilters[] = array(
156 'regex' => ($file{0} === ';') ? $file : $this->createRegex($file),
157 'callback' => $callback,
158 );
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 }