Skip to content

Commit 498c968

Browse files
committed
Merge branch '4.0' into 'main'
2 parents 0bde626 + 5d6ae12 commit 498c968

7 files changed

Lines changed: 54 additions & 52 deletions

File tree

phpmyfaq/assets/templates/default/ucp.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
</div>
254254
</form>
255255

256+
{% if webauthnSupportEnabled %}
256257
<!-- Passkey -->
257258
<div class="card shadow mb-4">
258259
<div class="card-header py-3">
@@ -290,6 +291,7 @@
290291
</form>
291292
</div>
292293
</div>
294+
{% endif %}
293295

294296

295297
</div>

phpmyfaq/attachment.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Symfony\Component\DependencyInjection\ContainerBuilder;
2727
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
2828
use Symfony\Component\HttpFoundation\Request;
29+
use Symfony\Component\HttpFoundation\StreamedResponse;
2930

3031
if (!defined('IS_VALID_PHPMYFAQ')) {
3132
http_response_code(400);
@@ -113,11 +114,27 @@
113114
$attachment && $attachment->getRecordId() > 0 && ($faqConfig->get('records.allowDownloadsForGuests') ||
114115
(($groupPermission || ($groupPermission && $userPermission)) && isset($permission['dlattachment'])))
115116
) {
116-
try {
117+
$response = new StreamedResponse(function () use ($attachment) {
117118
$attachment->rawOut();
118-
} catch (AttachmentException|ErrorException $e) {
119-
$attachmentErrors[] = $e->getMessage();
119+
});
120+
121+
$response->headers->set('Content-Type', $attachment->getMimeType());
122+
$response->headers->set('Content-Length', $attachment->getFilesize());
123+
124+
if ($attachment->getMimeType() === 'application/pdf') {
125+
$response->headers->set(
126+
'Content-Disposition',
127+
'inline; filename="' . rawurlencode($attachment->getFilename()) . '"'
128+
);
129+
} else {
130+
$response->headers->set(
131+
'Content-Disposition',
132+
'attachment; filename="' . rawurlencode($attachment->getFilename()) . '"'
133+
);
120134
}
135+
136+
$response->headers->set('Content-MD5', $attachment->getRealHash());
137+
$response->send();
121138
} else {
122139
$attachmentErrors[] = Translation::get('msgAttachmentInvalid');
123140
}

phpmyfaq/src/phpMyFAQ/Attachment/AbstractAttachment.php

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ abstract class AbstractAttachment
9696
/**
9797
* Constructor.
9898
*
99-
* @param mixed $id attachment id
99+
* @param mixed $attachmentId attachment id
100100
*/
101-
public function __construct(mixed $id = null)
101+
public function __construct(mixed $attachmentId = null)
102102
{
103103
$this->db = Database::getInstance();
104104

105-
if (null !== $id) {
106-
$this->id = $id;
105+
if (null !== $attachmentId) {
106+
$this->id = $attachmentId;
107107
$this->getMeta();
108108
}
109109
}
@@ -173,7 +173,7 @@ public function setKey(?string $key, bool $default = true): void
173173
$this->key = $key;
174174
$this->encrypted = null !== $key;
175175
// Not default means the key was set explicitly
176-
// for this attachment, so lets hash it
176+
// for this attachment, so let's hash it
177177
if (!$this->encrypted) {
178178
return;
179179
}
@@ -204,9 +204,9 @@ public function getId(): int
204204
/**
205205
* Sets attachment id.
206206
*/
207-
public function setId(int $id): void
207+
public function setId(int $attachmentId): void
208208
{
209-
$this->id = $id;
209+
$this->id = $attachmentId;
210210
}
211211

212212
/**
@@ -220,11 +220,11 @@ public function getRecordId(): int
220220
/**
221221
* Set record id.
222222
*
223-
* @param int $id record id
223+
* @param int $recordId record id
224224
*/
225-
public function setRecordId(int $id): void
225+
public function setRecordId(int $recordId): void
226226
{
227-
$this->recordId = $id;
227+
$this->recordId = $recordId;
228228
}
229229

230230
/**
@@ -268,34 +268,33 @@ public function saveMeta(): int
268268
return $this->id;
269269
}
270270

271-
/**
272-
* Returns filename.
273-
*/
274271
public function getFilename(): string
275272
{
276273
return $this->filename;
277274
}
278275

279-
/**
280-
* Returns the MIME type
281-
*/
282276
public function getMimeType(): string
283277
{
284278
return $this->mimeType;
285279
}
286280

281+
public function getFilesize(): int
282+
{
283+
return $this->filesize;
284+
}
285+
286+
public function getRealHash(): string
287+
{
288+
return $this->realHash;
289+
}
290+
287291
/**
288292
* Update several meta things after it was saved.
289293
*/
290294
protected function postUpdateMeta(): void
291295
{
292296
$sql = sprintf(
293-
"
294-
UPDATE
295-
%sfaqattachment
296-
SET virtual_hash = '%s',
297-
mime_type = '%s'
298-
WHERE id = %d",
297+
"UPDATE %sfaqattachment SET virtual_hash = '%s', mime_type = '%s' WHERE id = %d",
299298
Database::getTablePrefix(),
300299
$this->db->escape($this->virtualHash),
301300
$this->readMimeType(),
@@ -320,14 +319,11 @@ protected function readMimeType(): string
320319
/**
321320
* Generate hash based on current conditions.
322321
*
323-
* @return string
324-
*
322+
* @return string|null NOTE The way a file is saved in the filesystem
325323
* NOTE The way a file is saved in the filesystem
326324
* is based on md5 hash. If the file is unencrypted,
327-
* it's md5 hash is used directly, otherwise a
325+
* it md5 hash is used directly, otherwise a
328326
* hash based on several tokens gets generated.
329-
*
330-
* @return string|null
331327
* @throws AttachmentException
332328
*/
333329
protected function mkVirtualHash(): ?string

phpmyfaq/src/phpMyFAQ/Attachment/AttachmentInterface.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,27 @@ interface AttachmentInterface
2828
* Save current attachment to the appropriate storage.
2929
*
3030
* @param string $filePath full path to the attachment file
31-
*
3231
* @return bool
3332
*/
34-
public function save($filePath);
33+
public function save(string $filePath): bool;
3534

3635
/**
3736
* Delete attachment.
3837
*
3938
* @return bool
4039
*/
41-
public function delete();
40+
public function delete(): bool;
4241

4342
/**
4443
* Retrieve file contents into a variable.
4544
*
4645
* @return string
4746
*/
48-
public function get();
47+
public function get(): string;
4948

5049
/**
5150
* Output current file to stdout.
5251
*
53-
* @param bool $headers if headers must be sent
54-
* @param string $disposition disposition type (ignored if $headers false)
5552
*/
56-
public function rawOut($headers = true, $disposition = 'attachment');
53+
public function rawOut(): void;
5754
}

phpmyfaq/src/phpMyFAQ/Attachment/File.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ public function isStorageOk(): bool
8787
* Save current attachment to the appropriate storage.
8888
* The filepath given will be processed and moved to the appropriate location.
8989
*
90-
* @param string $filePath full path to the attachment file
91-
* @param string|null $filename filename to force
90+
* @param string $filePath full path to the attachment file
9291
* @throws FileException|AttachmentException
9392
* @todo rollback if something went wrong
9493
*/
@@ -159,22 +158,11 @@ public function get(): string
159158
/**
160159
* Output current file to stdout.
161160
*
162-
* @param bool $headers if headers must be sent
163-
* @param string $disposition disposition type (ignored if $headers false)
164161
* @throws AttachmentException
165162
*/
166-
public function rawOut($headers = true, $disposition = 'attachment'): void
163+
public function rawOut(): void
167164
{
168165
$file = $this->getFile();
169-
170-
if ($headers) {
171-
$disposition = 'attachment' == $disposition ? 'attachment' : 'inline';
172-
header('Content-Type: ' . $this->mimeType);
173-
header('Content-Length: ' . $this->filesize);
174-
header(sprintf('Content-Disposition: %s; filename="', $disposition) . rawurlencode($this->filename) . '"');
175-
header('Content-MD5: ' . $this->realHash);
176-
}
177-
178166
while (!$file->eof()) {
179167
echo $file->getChunk();
180168
}

phpmyfaq/src/phpMyFAQ/Controller/AbstractController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public function __construct()
7272
$this->container = $this->createContainer();
7373
$this->configuration = $this->container->get('phpmyfaq.configuration');
7474
$this->currentUser = $this->container->get('phpmyfaq.user.current_user');
75+
TwigWrapper::setTemplateSetName($this->configuration->get('layout.templateSet'));
7576
$this->isSecured();
7677
}
7778

phpmyfaq/ucp.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@
102102
'ad_gen_no' => Translation::get('ad_gen_no'),
103103
'msgConfirmTwofactorConfig' => Translation::get('msgConfirmTwofactorConfig'),
104104
'csrfTokenRemoveTwofactor' => Token::getInstance($container->get('session'))->getTokenString('remove-twofactor'),
105-
'msgGravatarNotConnected' => Translation::get('msgGravatarNotConnected')
105+
'msgGravatarNotConnected' => Translation::get('msgGravatarNotConnected'),
106+
'webauthnSupportEnabled' => $faqConfig->get('security.enableWebAuthnSupport')
106107
];
107108

108109
return $templateVars;

0 commit comments

Comments
 (0)