3 namespace wcf\system\devtools\package
;
5 use wcf\data\devtools\project\DevtoolsProject
;
6 use wcf\system\language\LanguageFactory
;
7 use wcf\util\XMLWriter
;
10 * Writes the `package.xml` file of a project.
12 * @author Matthias Schmidt
13 * @copyright 2001-2019 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package WoltLabSuite\Core\System\Devtools\Package
18 class DevtoolsPackageXmlWriter
21 * data used to write the `package.xml` file
24 protected $packageXmlData;
27 * devtools project whose `package.xml` file will be written
28 * @var DevtoolsProject
39 * Creates a new `DevtoolsPackageXmlWriter` object.
41 * @param DevtoolsProject $project
42 * @param array $packageXmlData
44 public function __construct(DevtoolsProject
$project, array $packageXmlData)
46 $this->project
= $project;
47 $this->packageXmlData
= $packageXmlData;
51 * Returns `true` if the given string needs to be placed in a CDATA
52 * section or `false`, otherwise.
54 * @param string $string
57 protected function requiresCdata($string)
59 return \
strpos($string, '<') !== false
60 || \
strpos($string, '>') !== false
61 || \
strpos($string, '&') !== false;
65 * Writes the `package.xml` file.
67 public function write()
69 $this->xmlWriter
= new XMLWriter();
70 $this->xmlWriter
->beginDocument(
72 'http://www.woltlab.com',
73 'http://www.woltlab.com/XSD/' . WSC_API_VERSION
. '/package.xsd',
74 ['name' => $this->packageXmlData
['packageIdentifier']]
77 $this->writePackageInformation();
78 $this->writeAuthorInformation();
79 $this->writeRequiredPackages();
80 $this->writeOptionalPackages();
81 $this->writeExcludedPackages();
82 $this->writeCompatibility();
83 $this->writeInstructions();
85 $this->xmlWriter
->endDocument($this->project
->getPackageXmlPath());
89 * Writes the `authorinformation` element.
91 protected function writeAuthorInformation()
93 $this->xmlWriter
->startElement('authorinformation');
95 $this->xmlWriter
->writeElement(
97 $this->packageXmlData
['author'],
99 $this->requiresCdata($this->packageXmlData
['author'])
101 if (isset($this->packageXmlData
['authorUrl']) && $this->packageXmlData
['authorUrl'] !== '') {
102 $this->xmlWriter
->writeElement(
104 $this->packageXmlData
['authorUrl'],
106 $this->requiresCdata($this->packageXmlData
['authorUrl'])
110 $this->xmlWriter
->endElement();
114 * Writes the `compatibility` element.
116 protected function writeCompatibility()
118 if (empty($this->packageXmlData
['apiVersions'])) {
122 $this->xmlWriter
->startElement('compatibility');
124 foreach ($this->packageXmlData
['apiVersions'] as $apiVersion) {
125 $this->xmlWriter
->writeElement('api', '', ['version' => $apiVersion]);
128 $this->xmlWriter
->endElement();
132 * Writes the `optionalpackages` element.
134 protected function writeExcludedPackages()
136 if (!empty($this->packageXmlData
['excludedPackages'])) {
137 $this->xmlWriter
->startElement('excludedpackages');
139 foreach ($this->packageXmlData
['excludedPackages'] as $excludedPackage) {
141 if (!empty($excludedPackage['version'])) {
142 $attributes['version'] = $excludedPackage['version'];
145 $this->xmlWriter
->writeElement(
147 $excludedPackage['packageIdentifier'],
153 $this->xmlWriter
->endElement();
158 * Writes the `instructions` elements.
160 protected function writeInstructions()
162 if (empty($this->packageXmlData
['instructions'])) {
166 foreach ($this->packageXmlData
['instructions'] as $instructions) {
167 $attributes = ['type' => $instructions['type']];
168 if ($instructions['type'] === 'update') {
169 $attributes['fromversion'] = $instructions['fromVersion'];
172 $this->xmlWriter
->startElement('instructions', $attributes);
174 foreach ($instructions['instructions'] as $instruction) {
175 $attributes = ['type' => $instruction['pip']];
176 if (!empty($instruction['runStandalone'])) {
177 $attributes['run'] = 'standalone';
179 if (!empty($instruction['application'])) {
180 $attributes['application'] = $instruction['application'];
183 $this->xmlWriter
->writeElement('instruction', $instruction['value'], $attributes, false);
186 $this->xmlWriter
->endElement();
191 * Writes the `optionalpackages` element.
193 protected function writeOptionalPackages()
195 if (!empty($this->packageXmlData
['optionalPackages'])) {
196 $this->xmlWriter
->startElement('optionalpackages');
198 foreach ($this->packageXmlData
['optionalPackages'] as $optionalPackage) {
199 $this->xmlWriter
->writeElement(
201 $optionalPackage['packageIdentifier'],
202 ['file' => "optionals/{$optionalPackage['packageIdentifier']}.tar"],
207 $this->xmlWriter
->endElement();
212 * Writes a child of the `packageinformation` element with i18n data.
214 * @param string $information
215 * @param null|string $elementName is set to lowercase version of `$information` if missing
217 protected function writeI18nPackageInformation($information, $elementName = null)
219 if ($elementName === null) {
220 $elementName = \
strtolower($information);
223 $english = LanguageFactory
::getInstance()->getLanguageByCode('en');
225 if (isset($this->packageXmlData
[$information . '_i18n'])) {
226 $defaultLanguageID = null;
227 if ($english !== null && isset($this->packageXmlData
[$information . '_i18n'][$english->languageID
])) {
228 $defaultLanguageID = $english->languageID
;
230 \reset
($this->packageXmlData
[$information . '_i18n']);
231 $defaultLanguageID = \
key($this->packageXmlData
[$information . '_i18n']);
234 $this->xmlWriter
->writeElement(
236 $this->packageXmlData
[$information . '_i18n'][$defaultLanguageID],
238 $this->requiresCdata($this->packageXmlData
[$information . '_i18n'][$defaultLanguageID])
241 foreach ($this->packageXmlData
[$information . '_i18n'] as $languageID => $informationValue) {
242 if ($languageID !== $defaultLanguageID) {
243 $this->xmlWriter
->writeElement(
246 ['language' => LanguageFactory
::getInstance()->getLanguage($languageID)->languageCode
],
247 $this->requiresCdata($informationValue)
252 $this->xmlWriter
->writeElement(
254 $this->packageXmlData
[$information],
256 $this->requiresCdata($this->packageXmlData
[$information])
262 * Writes the `packageinformation` element.
264 protected function writePackageInformation()
266 $this->xmlWriter
->startElement('packageinformation');
268 $this->xmlWriter
->writeComment(" {$this->packageXmlData['packageIdentifier']} ");
270 $this->writeI18nPackageInformation('packageName');
271 $this->writeI18nPackageInformation('packageDescription');
273 if (!empty($this->packageXmlData
['isApplication'])) {
274 $this->xmlWriter
->writeElement(
276 \
intval($this->packageXmlData
['isApplication']),
281 if (!empty($this->packageXmlData
['applicationDirectory'])) {
282 $this->xmlWriter
->writeElement(
283 'applicationdirectory',
284 $this->packageXmlData
['applicationDirectory'],
289 $this->xmlWriter
->writeElement(
291 $this->packageXmlData
['version'],
295 $this->xmlWriter
->writeElement(
297 $this->packageXmlData
['date'],
301 if (!empty($this->packageXmlData
['packageUrl'])) {
302 $this->xmlWriter
->writeElement(
304 $this->packageXmlData
['packageUrl'],
306 $this->requiresCdata($this->packageXmlData
['packageUrl'])
309 $this->writeI18nPackageInformation('license');
311 $this->xmlWriter
->endElement();
315 * Writes the `optionalpackages` element.
317 protected function writeRequiredPackages()
319 if (!empty($this->packageXmlData
['requiredPackages'])) {
320 $this->xmlWriter
->startElement('requiredpackages');
322 foreach ($this->packageXmlData
['requiredPackages'] as $requiredPackage) {
324 if (!empty($requiredPackage['minVersion'])) {
325 $attributes['minversion'] = $requiredPackage['minVersion'];
327 if (!empty($requiredPackage['file'])) {
328 $attributes['file'] = "requirements/{$requiredPackage['packageIdentifier']}.tar";
331 $this->xmlWriter
->writeElement(
333 $requiredPackage['packageIdentifier'],
339 $this->xmlWriter
->endElement();