Skip to content

Commit ddca998

Browse files
committed
first commit
0 parents  commit ddca998

9 files changed

Lines changed: 288 additions & 0 deletions

eventListener.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/6.0/eventListener.xsd">
3+
<import>
4+
<eventlistener name="mediaCoverPhotoWsdbDatabaseEditListener">
5+
<eventclassname>wcf\acp\form\WsdbDatabaseEditForm</eventclassname>
6+
<eventname>createForm</eventname>
7+
<listenerclassname>wcf\system\wsdb\event\listener\MediaCoverPhotoWsdbDatabaseEditListener</listenerclassname>
8+
<environment>admin</environment>
9+
</eventlistener>
10+
<eventlistener name="mediaCoverPhotoWsdbRecordAddListener">
11+
<eventclassname>wcf\form\WsdbRecordAddForm</eventclassname>
12+
<eventname>createForm,buildForm</eventname>
13+
<listenerclassname>wcf\system\wsdb\event\listener\MediaCoverPhotoWsdbRecordAddListener</listenerclassname>
14+
<inherit>1</inherit>
15+
</eventlistener>
16+
</import>
17+
</data>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
use wcf\system\database\table\column\DefaultFalseBooleanDatabaseTableColumn;
4+
use wcf\system\database\table\column\IntDatabaseTableColumn;
5+
use wcf\system\database\table\column\VarcharDatabaseTableColumn;
6+
use wcf\system\database\table\index\DatabaseTableForeignKey;
7+
use wcf\system\database\table\PartialDatabaseTable;
8+
9+
return [
10+
PartialDatabaseTable::create('wcf1_wsdb_database')
11+
->columns([
12+
DefaultFalseBooleanDatabaseTableColumn::create('enableMediaCoverPhoto'),
13+
]),
14+
PartialDatabaseTable::create('wcf1_wsdb_record')
15+
->columns([
16+
VarcharDatabaseTableColumn::create('coverPhotoType')
17+
->length(15)
18+
->notNull()
19+
->defaultValue('coverPhotoID'),
20+
IntDatabaseTableColumn::create('coverMediaID'),
21+
])
22+
->foreignKeys([
23+
DatabaseTableForeignKey::create()
24+
->columns(['coverMediaID'])
25+
->referencedTable('wcf1_media')
26+
->referencedColumns(['mediaID'])
27+
->onDelete('SET NULL'),
28+
]),
29+
];
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace wcf\system\wsdb\event\listener;
4+
5+
use wcf\acp\form\WsdbDatabaseEditForm;
6+
use wcf\system\event\listener\AbstractEventListener;
7+
use wcf\system\form\builder\container\FormContainer;
8+
use wcf\system\form\builder\field\BooleanFormField;
9+
use wcf\system\form\builder\field\dependency\NonEmptyFormFieldDependency;
10+
11+
final class MediaCoverPhotoWsdbDatabaseEditListener extends AbstractEventListener
12+
{
13+
protected function onCreateForm(WsdbDatabaseEditForm $eventObj): void
14+
{
15+
$settings = $eventObj->form->getNodeById('settings');
16+
\assert($settings instanceof FormContainer);
17+
18+
$settings->insertAfter(
19+
BooleanFormField::create('enableMediaCoverPhoto')
20+
->label('dev.hanashi.wsdb.enableMediaCoverPhoto')
21+
->addDependency(
22+
NonEmptyFormFieldDependency::create('coverPhotoEnabled')
23+
->fieldId('enableCoverPhoto')
24+
),
25+
'enableCoverPhoto'
26+
);
27+
}
28+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
3+
namespace wcf\system\wsdb\event\listener;
4+
5+
use wcf\data\file\File;
6+
use wcf\data\file\FileEditor;
7+
use wcf\data\media\Media;
8+
use wcf\data\object\type\ObjectTypeCache;
9+
use wcf\form\WsdbRecordAddForm;
10+
use wcf\system\event\listener\AbstractEventListener;
11+
use wcf\system\form\builder\container\FormContainer;
12+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
13+
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
14+
use wcf\system\form\builder\field\media\SingleMediaSelectionFormField;
15+
use wcf\system\form\builder\field\RadioButtonFormField;
16+
use wcf\system\form\builder\IFormDocument;
17+
use wcf\system\WCF;
18+
19+
final class MediaCoverPhotoWsdbRecordAddListener extends AbstractEventListener
20+
{
21+
protected function onCreateForm(WsdbRecordAddForm $eventObj): void
22+
{
23+
$generalSectionContainer = $eventObj->form->getNodeById('generalSection');
24+
$coverPhotoIDFormField = $eventObj->form->getNodeById('coverPhotoID');
25+
if (
26+
!$eventObj->getDatabase()->enableCoverPhoto
27+
|| !$eventObj->getDatabase()->enableMediaCoverPhoto
28+
|| $generalSectionContainer === null
29+
|| $coverPhotoIDFormField === null
30+
|| !WCF::getSession()->getPermission('admin.content.cms.canUseMedia')
31+
) {
32+
return;
33+
}
34+
\assert($generalSectionContainer instanceof FormContainer);
35+
36+
$generalSectionContainer->insertBefore(
37+
RadioButtonFormField::create('coverPhotoType')
38+
->label('Grundlage für Titelbild')
39+
->options([
40+
'coverPhotoID' => 'Titelbild hochladen',
41+
'coverMediaID' => 'Medienverwaltung',
42+
])
43+
->value('coverPhotoID')
44+
->required(),
45+
'coverPhotoID'
46+
);
47+
48+
$coverPhotoIDFormField->addDependency(
49+
ValueFormFieldDependency::create('coverPhotoIDTypeDependency')
50+
->fieldId('coverPhotoType')
51+
->values(['coverPhotoID'])
52+
);
53+
54+
$generalSectionContainer->insertAfter(
55+
SingleMediaSelectionFormField::create('coverMediaID')
56+
->label('Titelbild (Medienverwaltung)')
57+
->imageOnly()
58+
->addDependency(
59+
ValueFormFieldDependency::create('coverMediaIDTypeDependency')
60+
->fieldId('coverPhotoType')
61+
->values(['coverMediaID'])
62+
),
63+
'coverPhotoID'
64+
);
65+
}
66+
67+
protected function onBuildForm(WsdbRecordAddForm $eventObj): void
68+
{
69+
if (
70+
!$eventObj->getDatabase()->enableCoverPhoto
71+
|| !$eventObj->getDatabase()->enableMediaCoverPhoto
72+
|| !WCF::getSession()->getPermission('admin.content.cms.canUseMedia')
73+
) {
74+
return;
75+
}
76+
77+
$eventObj->form->getDataHandler()->addProcessor(
78+
new CustomFormDataProcessor(
79+
'coverFormField',
80+
function (IFormDocument $document, array $parameters): array {
81+
if (
82+
$parameters['data']['coverPhotoType'] == 'coverMediaID'
83+
&& isset($parameters['data']['coverMediaID'])
84+
&& $parameters['data']['coverMediaID']
85+
) {
86+
$media = new Media($parameters['data']['coverMediaID']);
87+
if ($media->mediaID) {
88+
$fileID = $this->saveFile($media);
89+
if ($fileID !== null) {
90+
$parameters['data']['coverPhotoID'] = $fileID;
91+
}
92+
}
93+
}
94+
95+
return $parameters;
96+
}
97+
)
98+
);
99+
}
100+
101+
private function saveFile(Media $media): ?int
102+
{
103+
$fileID = $this->getFileIDByHash(\hash_file('sha256', $media->getLocation()));
104+
if ($fileID === null) {
105+
$file = FileEditor::createFromExistingFile(
106+
$media->getLocation(),
107+
$media->filename,
108+
'com.woltlab.wsdb.coverPhoto',
109+
true,
110+
\TIME_NOW
111+
);
112+
if ($file !== null) {
113+
$fileID = $file->fileID;
114+
}
115+
}
116+
117+
return $fileID;
118+
}
119+
120+
private function getFileIDByHash(string $hash): ?int
121+
{
122+
$objectType = ObjectTypeCache::getInstance()->getObjectTypeByName(
123+
'com.woltlab.wcf.file',
124+
'com.woltlab.wsdb.coverPhoto'
125+
);
126+
if ($objectType === null) {
127+
return null;
128+
}
129+
130+
$sql = "
131+
SELECT *
132+
FROM wcf1_file
133+
WHERE fileHash = ?
134+
AND objectTypeID = ?
135+
ORDER BY fileID
136+
LIMIT 1
137+
";
138+
$statement = WCF::getDB()->prepare($sql);
139+
$statement->execute([$hash, $objectType->objectTypeID]);
140+
141+
$file = $statement->fetchObject(File::class);
142+
143+
return $file->fileID ?? null;
144+
}
145+
}

language/de.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<language xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/6.0/language.xsd" languagecode="de" languagename="Deutsch" countrycode="de">
3+
<import>
4+
<category name="dev.hanashi.wsdb">
5+
<item name="dev.hanashi.wsdb.enableMediaCoverPhoto"><![CDATA[Medienverwaltung für Titelbild verwenden]]></item>
6+
</category>
7+
</import>
8+
</language>

language/en.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<language xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/6.0/language.xsd" languagecode="en" languagename="English" countrycode="gb">
3+
<import>
4+
<category name="dev.hanashi.wsdb">
5+
<item name="dev.hanashi.wsdb.enableMediaCoverPhoto"><![CDATA[Use media management for cover image]]></item>
6+
</category>
7+
</import>
8+
</language>

package.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<package xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/6.0/package.xsd" name="dev.hanashi.wsdb.media-file">
3+
<packageinformation>
4+
<!-- dev.hanashi.wsdb.media-file -->
5+
<packagename>Database: Media management cover image</packagename>
6+
<packagename language="de">Database: Medienverwaltung-Titelbild</packagename>
7+
<packagedescription>Allows you to select cover images from media management.</packagedescription>
8+
<packagedescription language="de">Ermöglicht es Titelbilder aus der Medienverwaltung auszuwählen.</packagedescription>
9+
<version>1.0.0</version>
10+
<date>2026-01-13</date>
11+
</packageinformation>
12+
<authorinformation>
13+
<author>Hanashi Development</author>
14+
<authorurl>https://hanashi.dev</authorurl>
15+
</authorinformation>
16+
<requiredpackages>
17+
<requiredpackage minversion="6.2.0 RC 2">com.woltlab.wcf</requiredpackage>
18+
<requiredpackage minversion="6.2.0 RC 1">com.woltlab.wsdb</requiredpackage>
19+
</requiredpackages>
20+
<excludedpackages>
21+
<excludedpackage version="6.3.0 Alpha 1">com.woltlab.wcf</excludedpackage>
22+
<excludedpackage version="6.3.0 Alpha 1">com.woltlab.wsdb</excludedpackage>
23+
</excludedpackages>
24+
<instructions type="install">
25+
<instruction type="file"/>
26+
<instruction type="language"/>
27+
<instruction type="eventListener"/>
28+
<instruction type="database">acp/database/install_dev.hanashi.wsdb.media-file.php</instruction>
29+
</instructions>
30+
</package>

phpstan-baseline.neon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
ignoreErrors:
3+
-
4+
message: '#^Access to an undefined property wcf\\data\\wsdb\\database\\Database\:\:\$enableMediaCoverPhoto\.$#'
5+
identifier: property.notFound
6+
count: 2
7+
path: files/lib/system/wsdb/event/listener/MediaCoverPhotoWsdbRecordAddListener.class.php

phpstan.neon

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
includes:
2+
- ../WCF/phpstan-ambient.neon
3+
- phpstan-baseline.neon
4+
5+
parameters:
6+
level: 6
7+
phpVersion:
8+
min: 80102
9+
max: 80499
10+
paths:
11+
- files
12+
scanFiles:
13+
- ../WCF/constants.php
14+
scanDirectories:
15+
- ../WCF/wcfsetup/install/files
16+
- ../com.woltlab.wsdb/files

0 commit comments

Comments
 (0)