Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Utility/ProjectInfo.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Utility; | |
4 | |
5 use Drupal\Core\Extension\Extension; | |
6 | |
7 /** | |
8 * Performs operations on drupal.org project data. | |
9 */ | |
10 class ProjectInfo { | |
11 | |
12 /** | |
13 * Populates an array of project data. | |
14 * | |
15 * This iterates over a list of the installed modules or themes and groups | |
16 * them by project and status. A few parts of this function assume that | |
17 * enabled modules and themes are always processed first, and if uninstalled | |
18 * modules or themes are being processed (there is a setting to control if | |
19 * uninstalled code should be included in the Available updates report or | |
20 * not),those are only processed after $projects has been populated with | |
21 * information about the enabled code. 'Hidden' modules and themes are | |
22 * ignored if they are not installed. 'Hidden' Modules and themes in the | |
23 * "Testing" package are ignored regardless of installation status. | |
24 * | |
25 * This function also records the latest change time on the .info.yml files | |
26 * for each module or theme, which is important data which is used when | |
27 * deciding if the available update data should be invalidated. | |
28 * | |
29 * @param array $projects | |
30 * Reference to the array of project data of what's installed on this site. | |
31 * @param \Drupal\Core\Extension\Extension[] $list | |
32 * Array of data to process to add the relevant info to the $projects array. | |
33 * @param string $project_type | |
34 * The kind of data in the list. Can be 'module' or 'theme'. | |
35 * @param bool $status | |
36 * Boolean that controls what status (enabled or uninstalled) to process out | |
37 * of the $list and add to the $projects array. | |
38 * @param array $additional_whitelist | |
39 * (optional) Array of additional elements to be collected from the .info.yml | |
40 * file. Defaults to array(). | |
41 */ | |
42 public function processInfoList(array &$projects, array $list, $project_type, $status, array $additional_whitelist = []) { | |
43 foreach ($list as $file) { | |
44 // Just projects with a matching status should be listed. | |
45 if ($file->status != $status) { | |
46 continue; | |
47 } | |
48 | |
49 // Skip if the .info.yml file is broken. | |
50 if (empty($file->info)) { | |
51 continue; | |
52 } | |
53 | |
54 // Skip if it's a hidden project and the project is not installed. | |
55 if (!empty($file->info['hidden']) && empty($status)) { | |
56 continue; | |
57 } | |
58 | |
59 // Skip if it's a hidden project and the project is a test project. Tests | |
60 // should use hook_system_info_alter() to test ProjectInfo's | |
61 // functionality. | |
62 if (!empty($file->info['hidden']) && isset($file->info['package']) && $file->info['package'] == 'Testing') { | |
63 continue; | |
64 } | |
65 | |
66 // If the .info.yml doesn't define the 'project', try to figure it out. | |
67 if (!isset($file->info['project'])) { | |
68 $file->info['project'] = $this->getProjectName($file); | |
69 } | |
70 | |
71 // If we still don't know the 'project', give up. | |
72 if (empty($file->info['project'])) { | |
73 continue; | |
74 } | |
75 | |
76 // If we don't already know it, grab the change time on the .info.yml file | |
77 // itself. Note: we need to use the ctime, not the mtime (modification | |
78 // time) since many (all?) tar implementations will go out of their way to | |
79 // set the mtime on the files it creates to the timestamps recorded in the | |
80 // tarball. We want to see the last time the file was changed on disk, | |
81 // which is left alone by tar and correctly set to the time the .info.yml | |
82 // file was unpacked. | |
83 if (!isset($file->info['_info_file_ctime'])) { | |
84 $file->info['_info_file_ctime'] = $file->getCTime(); | |
85 } | |
86 | |
87 if (!isset($file->info['datestamp'])) { | |
88 $file->info['datestamp'] = 0; | |
89 } | |
90 | |
91 $project_name = $file->info['project']; | |
92 | |
93 // Figure out what project type we're going to use to display this module | |
94 // or theme. If the project name is 'drupal', we don't want it to show up | |
95 // under the usual "Modules" section, we put it at a special "Drupal Core" | |
96 // section at the top of the report. | |
97 if ($project_name == 'drupal') { | |
98 $project_display_type = 'core'; | |
99 } | |
100 else { | |
101 $project_display_type = $project_type; | |
102 } | |
103 if (empty($status)) { | |
104 // If we're processing uninstalled modules or themes, append a suffix. | |
105 $project_display_type .= '-disabled'; | |
106 } | |
107 if (!isset($projects[$project_name])) { | |
108 // Only process this if we haven't done this project, since a single | |
109 // project can have multiple modules or themes. | |
110 $projects[$project_name] = [ | |
111 'name' => $project_name, | |
112 // Only save attributes from the .info.yml file we care about so we do | |
113 // not bloat our RAM usage needlessly. | |
114 'info' => $this->filterProjectInfo($file->info, $additional_whitelist), | |
115 'datestamp' => $file->info['datestamp'], | |
116 'includes' => [$file->getName() => $file->info['name']], | |
117 'project_type' => $project_display_type, | |
118 'project_status' => $status, | |
119 ]; | |
120 } | |
121 elseif ($projects[$project_name]['project_type'] == $project_display_type) { | |
122 // Only add the file we're processing to the 'includes' array for this | |
123 // project if it is of the same type and status (which is encoded in the | |
124 // $project_display_type). This prevents listing all the uninstalled | |
125 // modules included with an enabled project if we happen to be checking | |
126 // for uninstalled modules, too. | |
127 $projects[$project_name]['includes'][$file->getName()] = $file->info['name']; | |
128 $projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']); | |
129 $projects[$project_name]['datestamp'] = max($projects[$project_name]['datestamp'], $file->info['datestamp']); | |
130 } | |
131 elseif (empty($status)) { | |
132 // If we have a project_name that matches, but the project_display_type | |
133 // does not, it means we're processing a uninstalled module or theme | |
134 // that belongs to a project that has some enabled code. In this case, | |
135 // we add the uninstalled thing into a separate array for separate | |
136 // display. | |
137 $projects[$project_name]['disabled'][$file->getName()] = $file->info['name']; | |
138 } | |
139 } | |
140 } | |
141 | |
142 /** | |
143 * Determines what project a given file object belongs to. | |
144 * | |
145 * @param \Drupal\Core\Extension\Extension $file | |
146 * An extension object. | |
147 * | |
148 * @return string | |
149 * The canonical project short name. | |
150 */ | |
151 public function getProjectName(Extension $file) { | |
152 $project_name = ''; | |
153 if (isset($file->info['project'])) { | |
154 $project_name = $file->info['project']; | |
155 } | |
156 elseif (strpos($file->getPath(), 'core/modules') === 0) { | |
157 $project_name = 'drupal'; | |
158 } | |
159 return $project_name; | |
160 } | |
161 | |
162 /** | |
163 * Filters the project .info.yml data to only save attributes we need. | |
164 * | |
165 * @param array $info | |
166 * Array of .info.yml file data as returned by | |
167 * \Drupal\Core\Extension\InfoParser. | |
168 * @param $additional_whitelist | |
169 * (optional) Array of additional elements to be collected from the .info.yml | |
170 * file. Defaults to array(). | |
171 * | |
172 * @return | |
173 * Array of .info.yml file data we need for the update manager. | |
174 * | |
175 * @see \Drupal\Core\Utility\ProjectInfo::processInfoList() | |
176 */ | |
177 public function filterProjectInfo($info, $additional_whitelist = []) { | |
178 $whitelist = [ | |
179 '_info_file_ctime', | |
180 'datestamp', | |
181 'major', | |
182 'name', | |
183 'package', | |
184 'project', | |
185 'project status url', | |
186 'version', | |
187 ]; | |
188 $whitelist = array_merge($whitelist, $additional_whitelist); | |
189 return array_intersect_key($info, array_combine($whitelist, $whitelist)); | |
190 } | |
191 | |
192 } |