diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml
index 05179692..a31199b3 100644
--- a/.github/workflows/codestyle.yml
+++ b/.github/workflows/codestyle.yml
@@ -4,7 +4,6 @@ on:
push:
branches:
- master
- pull_request:
permissions:
contents: read
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 52d79e6a..e3cc1285 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -1,13 +1,13 @@
exclude('*/vendor/*')
- ->in(__DIR__.'/files/');
+ ->in(__DIR__ . '/files/');
return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
- '@PER-CS2.0' => true,
- 'single_line_empty_body' => false,
+ '@PSR1' => true,
+ '@PSR2' => true,
'array_push' => true,
'backtick_to_shell_exec' => true,
@@ -25,18 +25,23 @@
'non_printable_character' => ['use_escape_sequences_in_strings' => true],
+ 'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'native_function_casing' => true,
'native_function_type_declaration_casing' => true,
'cast_spaces' => ['space' => 'none'],
+ 'lowercase_cast' => true,
'no_unset_cast' => true,
+ 'short_scalar_cast' => true,
'class_attributes_separation' => true,
+ 'no_blank_lines_after_class_opening' => true,
'no_null_property_initialization' => true,
'self_accessor' => true,
'single_class_element_per_statement' => true,
+ 'single_trait_insert_per_statement' => true,
'no_empty_comment' => true,
'single_line_comment_style' => ['comment_types' => ['hash']],
@@ -55,12 +60,15 @@
'native_function_invocation' => ['include' => ['@internal']],
'no_unreachable_default_argument_value' => true,
'nullable_type_declaration_for_default_null_value' => true,
+ 'return_type_declaration' => true,
'static_lambda' => true,
'fully_qualified_strict_types' => ['leading_backslash_in_global_namespace' => true],
+ 'no_leading_import_slash' => true,
'no_unused_imports' => true,
'ordered_imports' => true,
+ 'declare_equal_normalize' => true,
'dir_constant' => true,
'explicit_indirect_variable' => true,
'function_to_constant' => true,
@@ -71,6 +79,7 @@
'clean_namespace' => true,
'no_leading_namespace_whitespace' => true,
+ 'single_blank_line_before_namespace' => true,
'no_homoglyph_names' => true,
@@ -82,6 +91,7 @@
'operator_linebreak' => true,
'standardize_increment' => true,
'standardize_not_equals' => true,
+ 'ternary_operator_spaces' => true,
'ternary_to_elvis_operator' => true,
'ternary_to_null_coalescing' => true,
'unary_operator_spaces' => true,
@@ -102,6 +112,7 @@
'array_indentation' => true,
'blank_line_before_statement' => ['statements' => ['return', 'exit']],
+ 'compact_nullable_typehint' => true,
'method_chaining_indentation' => true,
'no_extra_blank_lines' => ['tokens' => ['case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'square_brace_block', 'switch', 'throw', 'use']],
'no_spaces_around_offset' => true,
diff --git a/.phpcs.xml b/.phpcs.xml
index c721282f..fa15c659 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -9,5 +9,7 @@
-
+
+
+
diff --git a/composer.json b/composer.json
new file mode 100644
index 00000000..60267d03
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,8 @@
+{
+ "name": "woltlab/com.woltlab.wcf.conversation",
+ "type": "project",
+ "require-dev": {
+ "phpstan/phpstan": "^2.1"
+ },
+ "require": {}
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..4703f643
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,77 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "069580d97420a2a4f15021f8f35e0fc4",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "phpstan/phpstan",
+ "version": "2.1.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "f9adff3b87c03b12cc7e46a30a524648e497758f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f9adff3b87c03b12cc7e46a30a524648e497758f",
+ "reference": "f9adff3b87c03b12cc7e46a30a524648e497758f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "keywords": [
+ "dev",
+ "static analysis"
+ ],
+ "support": {
+ "docs": "https://phpstan.org/user-guide/getting-started",
+ "forum": "https://github.com/phpstan/phpstan/discussions",
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "security": "https://github.com/phpstan/phpstan/security/policy",
+ "source": "https://github.com/phpstan/phpstan-src"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/phpstan",
+ "type": "github"
+ }
+ ],
+ "time": "2025-03-09T09:30:48+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {},
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/files/lib/action/ConversationLabelFormAction.class.php b/files/lib/action/ConversationLabelFormAction.class.php
index bfd1b497..735bcfc0 100644
--- a/files/lib/action/ConversationLabelFormAction.class.php
+++ b/files/lib/action/ConversationLabelFormAction.class.php
@@ -74,7 +74,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
}
$data = $form->getData()['data'];
- $deleteLabel = $label && $data['deleteLabel'] ?? false;
+ $deleteLabel = $label && ($data['deleteLabel'] ?? false);
unset($data['deleteLabel']);
if ($deleteLabel) {
diff --git a/files/lib/data/conversation/Conversation.class.php b/files/lib/data/conversation/Conversation.class.php
index 6d674cbd..75ce0b41 100644
--- a/files/lib/data/conversation/Conversation.class.php
+++ b/files/lib/data/conversation/Conversation.class.php
@@ -141,11 +141,9 @@ public function canReply(): bool
/**
* Overrides the last message data, used when `leftAt < lastPostTime`.
*
- * @param int $userID
- * @param string $username
- * @param int $time
+ * @return void
*/
- public function setLastMessage($userID, $username, $time)
+ public function setLastMessage(?int $userID, string $username, int $time)
{
$this->data['lastPostTime'] = $time;
$this->data['lastPosterID'] = $userID;
@@ -156,9 +154,9 @@ public function setLastMessage($userID, $username, $time)
* Loads participation data for given user id (default: current user) on runtime.
* You should use Conversation::getUserConversation() instead if possible.
*
- * @param int $userID
+ * @return void
*/
- public function loadUserParticipation($userID = null)
+ public function loadUserParticipation(?int $userID = null)
{
if ($userID === null) {
$userID = WCF::getUser()->userID;
@@ -179,11 +177,9 @@ public function loadUserParticipation($userID = null)
/**
* Returns a specific user conversation.
*
- * @param int $conversationID
- * @param int $userID
- * @return null|Conversation
+ * @return ?Conversation
*/
- public static function getUserConversation($conversationID, $userID)
+ public static function getUserConversation(int $conversationID, int $userID)
{
$sql = "SELECT conversation_to_user.*, conversation.*
FROM wcf1_conversation conversation
@@ -205,10 +201,9 @@ public static function getUserConversation($conversationID, $userID)
* Returns a list of user conversations.
*
* @param int[] $conversationIDs
- * @param int $userID
- * @return Conversation[]
+ * @return Conversation[]
*/
- public static function getUserConversations(array $conversationIDs, $userID)
+ public static function getUserConversations(array $conversationIDs, int $userID)
{
$conditionBuilder = new PreparedStatementConditionBuilder();
$conditionBuilder->add('conversation.conversationID IN (?)', [$conversationIDs]);
@@ -316,10 +311,9 @@ public function getFirstMessage(): ?ConversationMessage
/**
* Returns a list of the ids of all participants.
*
- * @param bool $excludeLeftParticipants
- * @return int[]
+ * @return int[]
*/
- public function getParticipantIDs($excludeLeftParticipants = false)
+ public function getParticipantIDs(bool $excludeLeftParticipants = false)
{
$conditions = new PreparedStatementConditionBuilder();
$conditions->add("conversationID = ?", [$this->conversationID]);
@@ -340,11 +334,9 @@ public function getParticipantIDs($excludeLeftParticipants = false)
/**
* Returns a list of the usernames of all participants.
*
- * @param bool $excludeSelf
- * @param bool $leftByOwnChoice
- * @return string[]
+ * @return string[]
*/
- public function getParticipantNames($excludeSelf = false, $leftByOwnChoice = false, bool $isAuthor = false)
+ public function getParticipantNames(bool $excludeSelf = false, bool $leftByOwnChoice = false, bool $isAuthor = false)
{
$conditions = new PreparedStatementConditionBuilder();
$conditions->add("conversationID = ?", [$this->conversationID]);
@@ -422,9 +414,8 @@ public function getPopoverLinkClass(): string
* of all given conversation ids.
*
* @param int[] $conversationIDs
- * @param int $userID
*/
- public static function isParticipant(array $conversationIDs, $userID = null): bool
+ public static function isParticipant(array $conversationIDs, ?int $userID = null): bool
{
if ($userID === null) {
$userID = WCF::getUser()->userID;
@@ -473,15 +464,14 @@ public static function isParticipant(array $conversationIDs, $userID = null): bo
/**
* Validates the participants.
*
- * @param mixed $participants
- * @param string $field
+ * @param string[]|string $participants
* @param int[] $existingParticipants
- * @return array $result
- * @throws UserInputException
+ * @return list
+ * @throws UserInputException
*/
public static function validateParticipants(
- $participants,
- $field = 'participants',
+ array|string $participants,
+ string $field = 'participants',
array $existingParticipants = []
) {
$result = [];
@@ -534,14 +524,13 @@ public static function validateParticipants(
/**
* Validates the group participants.
*
- * @param mixed $participants
- * @param string $field
+ * @param string[]|string $participants
* @param int[] $existingParticipants
- * @return array $result
+ * @return list
*/
public static function validateGroupParticipants(
- $participants,
- $field = 'participants',
+ array|string $participants,
+ string $field = 'participants',
array $existingParticipants = []
) {
$groupIDs = \is_array($participants) ? $participants : ArrayUtil::toIntegerArray(\explode(',', $participants));
@@ -550,7 +539,7 @@ public static function validateGroupParticipants(
foreach ($groupIDs as $groupID) {
$group = UserGroup::getGroupByID($groupID);
- /** @noinspection PhpUndefinedFieldInspection */
+ // @phpstan-ignore property.notFound
if ($group !== null && $group->canBeAddedAsConversationParticipant) {
$validGroupIDs[] = $groupID;
}
@@ -599,11 +588,10 @@ public static function validateGroupParticipants(
/**
* Validates the given participant.
*
- * @param UserProfile $user
- * @param string $field
- * @throws UserInputException
+ * @return void
+ * @throws UserInputException
*/
- public static function validateParticipant(UserProfile $user, $field = 'participants')
+ public static function validateParticipant(UserProfile $user, string $field = 'participants')
{
// check participant's settings and permissions
if (!$user->getPermission('user.conversation.canUseConversation')) {
diff --git a/files/lib/data/conversation/ConversationAction.class.php b/files/lib/data/conversation/ConversationAction.class.php
index d64d0544..3786c4d4 100644
--- a/files/lib/data/conversation/ConversationAction.class.php
+++ b/files/lib/data/conversation/ConversationAction.class.php
@@ -34,8 +34,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationEditor[] getObjects()
- * @method ConversationEditor getSingleObject()
+ * @extends AbstractDatabaseObjectAction
*/
class ConversationAction extends AbstractDatabaseObjectAction implements
IClipboardAction,
@@ -60,7 +59,6 @@ class ConversationAction extends AbstractDatabaseObjectAction implements
/**
* @inheritDoc
- * @return Conversation
*/
public function create()
{
@@ -74,7 +72,7 @@ public function create()
$data['participants'] = \count($this->parameters['participants']);
}
// count attachments
- if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) {
+ if (isset($this->parameters['attachmentHandler'])) {
$data['attachments'] = \count($this->parameters['attachmentHandler']);
}
$conversation = \call_user_func([$this->className, 'create'], $data);
@@ -178,7 +176,7 @@ public function delete()
}
// delete conversations
- parent::delete();
+ $count = parent::delete();
if (!empty($this->objectIDs)) {
// delete notifications
@@ -193,6 +191,8 @@ public function delete()
UserStorageHandler::getInstance()->reset($participantIDs, 'unreadConversationCount');
}
}
+
+ return $count;
}
/**
@@ -354,6 +354,7 @@ public function markAsRead()
$returnValues['markAsRead'] = \reset($conversationIDs);
}
+ // @phpstan-ignore return.void
return $returnValues;
}
@@ -394,6 +395,8 @@ public function validateMarkAsRead()
/**
* Marks all conversations as read.
+ *
+ * @return array{markAllAsRead: bool}
*/
public function markAllAsRead()
{
@@ -428,6 +431,8 @@ public function markAllAsRead()
/**
* Validates the markAllAsRead action.
+ *
+ * @return void
*/
public function validateMarkAllAsRead()
{
@@ -437,8 +442,9 @@ public function validateMarkAllAsRead()
/**
* Validates parameters to close conversations.
*
- * @throws PermissionDeniedException
- * @throws UserInputException
+ * @return void
+ * @throws PermissionDeniedException
+ * @throws UserInputException
*/
public function validateClose()
{
@@ -481,8 +487,9 @@ public function close()
/**
* Validates parameters to open conversations.
*
- * @throws PermissionDeniedException
- * @throws UserInputException
+ * @return void
+ * @throws PermissionDeniedException
+ * @throws UserInputException
*/
public function validateOpen()
{
@@ -525,8 +532,9 @@ public function open()
/**
* Validates parameters to hide conversations.
*
- * @throws PermissionDeniedException
- * @throws UserInputException
+ * @return void
+ * @throws PermissionDeniedException
+ * @throws UserInputException
*/
public function validateHideConversation()
{
@@ -554,7 +562,7 @@ public function validateHideConversation()
/**
* Hides or restores conversations.
*
- * @return string[]
+ * @return array{actionName: string, redirectURL: string}
*/
public function hideConversation()
{
@@ -581,6 +589,18 @@ public function validateGetConversations(): void
}
/**
+ * @return array{
+ * items: array,
+ * totalCount: int,
+ * }
* @since 5.5
*/
public function getConversations(): array
@@ -682,6 +702,8 @@ public function getConversations(): array
/**
* Validates the 'unmarkAll' action.
+ *
+ * @return void
*/
public function validateUnmarkAll()
{
@@ -690,6 +712,8 @@ public function validateUnmarkAll()
/**
* Unmarks all conversations.
+ *
+ * @return void
*/
public function unmarkAll()
{
@@ -701,7 +725,8 @@ public function unmarkAll()
/**
* Validates parameters to display the 'add participants' form.
*
- * @throws PermissionDeniedException
+ * @return void
+ * @throws PermissionDeniedException
*/
public function validateGetAddParticipantsForm()
{
@@ -717,12 +742,19 @@ public function validateGetAddParticipantsForm()
/**
* Shows the 'add participants' form.
*
- * @return array
+ * @return array{
+ * excludedSearchValues: string[],
+ * maxItems: int,
+ * canAddGroupParticipants: int,
+ * template: string,
+ * restrictUserGroupIDs: list,
+ * }
*/
public function getAddParticipantsForm()
{
$restrictUserGroupIDs = [];
foreach (UserGroup::getAllGroups() as $group) {
+ // @phpstan-ignore property.notFound
if ($group->canBeAddedAsConversationParticipant) {
$restrictUserGroupIDs[] = $group->groupID;
}
@@ -747,6 +779,8 @@ public function getAddParticipantsForm()
/**
* Validates parameters to add new participants.
+ *
+ * @return void
*/
public function validateAddParticipants()
{
@@ -771,7 +805,13 @@ public function validateAddParticipants()
/**
* Adds new participants.
*
- * @return array
+ * @return array{
+ * count: int,
+ * successMessage: string,
+ * }|array{
+ * actionName: 'addParticipants',
+ * errorMessage: string,
+ * }
*/
public function addParticipants()
{
@@ -873,8 +913,9 @@ public function addParticipants()
/**
* Validates parameters to remove a participant from a conversation.
*
- * @throws PermissionDeniedException
- * @throws UserInputException
+ * @return void
+ * @throws PermissionDeniedException
+ * @throws UserInputException
*/
public function validateRemoveParticipant()
{
@@ -910,6 +951,8 @@ public function validateRemoveParticipant()
/**
* Removes a participant from a conversation.
+ *
+ * @return array{userID: int}
*/
public function removeParticipant()
{
@@ -936,6 +979,8 @@ public function removeParticipant()
/**
* Rebuilds the conversation data of the relevant conversations.
+ *
+ * @return void
*/
public function rebuild()
{
@@ -982,7 +1027,8 @@ public function rebuild()
/**
* Validates the parameters to edit a conversation's subject.
*
- * @throws PermissionDeniedException
+ * @return void
+ * @throws PermissionDeniedException
*/
public function validateEditSubject()
{
@@ -997,7 +1043,7 @@ public function validateEditSubject()
/**
* Edits a conversation's subject.
*
- * @return string[]
+ * @return array{subject: string}
*/
public function editSubject()
{
@@ -1027,11 +1073,9 @@ public function editSubject()
/**
* Adds conversation modification data.
*
- * @param Conversation $conversation
- * @param string $key
- * @param mixed $value
+ * @return void
*/
- protected function addConversationData(Conversation $conversation, $key, $value)
+ protected function addConversationData(Conversation $conversation, string $key, mixed $value)
{
if (!isset($this->conversationData[$conversation->conversationID])) {
$this->conversationData[$conversation->conversationID] = [];
@@ -1043,7 +1087,7 @@ protected function addConversationData(Conversation $conversation, $key, $value)
/**
* Returns conversation data.
*
- * @return mixed[][]
+ * @return mixed[][]
*/
protected function getConversationData()
{
@@ -1056,6 +1100,7 @@ protected function getConversationData()
* Unmarks conversations.
*
* @param int[] $conversationIDs
+ * @return void
*/
protected function unmarkItems(array $conversationIDs = [])
{
diff --git a/files/lib/data/conversation/ConversationEditor.class.php b/files/lib/data/conversation/ConversationEditor.class.php
index dea31864..a088b53f 100644
--- a/files/lib/data/conversation/ConversationEditor.class.php
+++ b/files/lib/data/conversation/ConversationEditor.class.php
@@ -14,9 +14,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method static Conversation create(array $parameters = [])
- * @method Conversation getDecoratedObject()
- * @mixin Conversation
+ * @mixin Conversation
+ * @extends DatabaseObjectEditor
*/
class ConversationEditor extends DatabaseObjectEditor
{
@@ -28,7 +27,7 @@ class ConversationEditor extends DatabaseObjectEditor
/**
* Adds a new message to this conversation.
*
- * @param ConversationMessage $message
+ * @return void
*/
public function addMessage(ConversationMessage $message)
{
@@ -43,6 +42,8 @@ public function addMessage(ConversationMessage $message)
/**
* Resets the participants of this conversation.
+ *
+ * @return void
*/
public function resetParticipants()
{
@@ -58,9 +59,9 @@ public function resetParticipants()
*
* @param int[] $participantIDs
* @param int[] $invisibleParticipantIDs
- * @param string $visibility
+ * @return void
*/
- public function updateParticipants(array $participantIDs, array $invisibleParticipantIDs = [], $visibility = 'all')
+ public function updateParticipants(array $participantIDs, array $invisibleParticipantIDs = [], string $visibility = 'all')
{
$usernames = [];
if (!empty($participantIDs) || !empty($invisibleParticipantIDs)) {
@@ -124,6 +125,8 @@ public function updateParticipants(array $participantIDs, array $invisiblePartic
/**
* Updates participant count.
+ *
+ * @return void
*/
public function updateParticipantCount()
{
@@ -148,6 +151,8 @@ public function updateParticipantCount()
/**
* Updates the participant summary of this conversation.
+ *
+ * @return void
*/
public function updateParticipantSummary()
{
@@ -166,9 +171,9 @@ public function updateParticipantSummary()
/**
* Removes a participant from this conversation.
*
- * @param int $userID
+ * @return void
*/
- public function removeParticipant($userID)
+ public function removeParticipant(int $userID)
{
$sql = "SELECT joinedAt, isInvisible
FROM wcf1_conversation_to_user
@@ -217,6 +222,8 @@ public function removeParticipant($userID)
/**
* Updates the first message of this conversation.
+ *
+ * @return void
*/
public function updateFirstMessage()
{
@@ -236,6 +243,8 @@ public function updateFirstMessage()
/**
* Updates the last message of this conversation.
+ *
+ * @return void
*/
public function updateLastMessage()
{
@@ -260,6 +269,7 @@ public function updateLastMessage()
* Updates the participant summary of the given conversations.
*
* @param int[] $conversationIDs
+ * @return void
*/
public static function updateParticipantSummaries(array $conversationIDs)
{
@@ -277,6 +287,7 @@ public static function updateParticipantSummaries(array $conversationIDs)
* Updates the participant counts of the given conversations.
*
* @param int[] $conversationIDs
+ * @return void
*/
public static function updateParticipantCounts(array $conversationIDs)
{
diff --git a/files/lib/data/conversation/ConversationList.class.php b/files/lib/data/conversation/ConversationList.class.php
index 8118d6a1..b8783056 100644
--- a/files/lib/data/conversation/ConversationList.class.php
+++ b/files/lib/data/conversation/ConversationList.class.php
@@ -2,6 +2,7 @@
namespace wcf\data\conversation;
+use wcf\data\DatabaseObjectDecorator;
use wcf\data\DatabaseObjectList;
/**
@@ -11,11 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method Conversation current()
- * @method Conversation[] getObjects()
- * @method Conversation|null getSingleObject()
- * @method Conversation|null search($objectID)
- * @property Conversation[] $objects
+ * @template TDatabaseObject of Conversation|DatabaseObjectDecorator = Conversation
+ * @extends DatabaseObjectList
*/
class ConversationList extends DatabaseObjectList
{
diff --git a/files/lib/data/conversation/ConversationParticipantList.class.php b/files/lib/data/conversation/ConversationParticipantList.class.php
index f43944d0..f2d44e79 100644
--- a/files/lib/data/conversation/ConversationParticipantList.class.php
+++ b/files/lib/data/conversation/ConversationParticipantList.class.php
@@ -29,11 +29,9 @@ class ConversationParticipantList extends UserProfileList
/**
* Creates a new ConversationParticipantList object.
*
- * @param int $conversationID
- * @param int $userID
* @param bool $isAuthor true if given user is the author of this conversation
*/
- public function __construct($conversationID, $userID = 0, $isAuthor = false)
+ public function __construct(int $conversationID, int $userID = 0, bool $isAuthor = false)
{
parent::__construct();
diff --git a/files/lib/data/conversation/FeedConversation.class.php b/files/lib/data/conversation/FeedConversation.class.php
index fc7b097a..5f43ee66 100644
--- a/files/lib/data/conversation/FeedConversation.class.php
+++ b/files/lib/data/conversation/FeedConversation.class.php
@@ -13,8 +13,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method Conversation getDecoratedObject()
- * @mixin Conversation
+ * @mixin Conversation
+ * @extends DatabaseObjectDecorator
* @deprecated 6.1
*/
class FeedConversation extends DatabaseObjectDecorator implements IFeedEntry
diff --git a/files/lib/data/conversation/FeedConversationList.class.php b/files/lib/data/conversation/FeedConversationList.class.php
index 63e280c8..e90b60df 100644
--- a/files/lib/data/conversation/FeedConversationList.class.php
+++ b/files/lib/data/conversation/FeedConversationList.class.php
@@ -11,11 +11,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method FeedConversation current()
- * @method FeedConversation[] getObjects()
- * @method FeedConversation|null getSingleObject()
- * @method FeedConversation|null search($objectID)
- * @property FeedConversation[] $objects
+ * @extends ConversationList
* @deprecated 6.1
*/
class FeedConversationList extends ConversationList
diff --git a/files/lib/data/conversation/UserConversationList.class.php b/files/lib/data/conversation/UserConversationList.class.php
index 331805aa..f4e0fc20 100644
--- a/files/lib/data/conversation/UserConversationList.class.php
+++ b/files/lib/data/conversation/UserConversationList.class.php
@@ -16,11 +16,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ViewableConversation current()
- * @method ViewableConversation[] getObjects()
- * @method ViewableConversation|null getSingleObject()
- * @method ViewableConversation|null search($objectID)
- * @property ViewableConversation[] $objects
+ * @extends ConversationList
*/
class UserConversationList extends ConversationList
{
@@ -119,7 +115,7 @@ public function __construct($userID, $filter = '', $labelID = 0)
/**
* Sets the label list of the user the conversations belong to.
*
- * @param ConversationLabelList $labelList
+ * @return void
*/
public function setLabelList(ConversationLabelList $labelList)
{
diff --git a/files/lib/data/conversation/ViewableConversation.class.php b/files/lib/data/conversation/ViewableConversation.class.php
index 6a7126ea..75b27a90 100644
--- a/files/lib/data/conversation/ViewableConversation.class.php
+++ b/files/lib/data/conversation/ViewableConversation.class.php
@@ -18,34 +18,34 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method Conversation getDecoratedObject()
- * @mixin Conversation
- * @property-read int|null $otherParticipantID
- * @property-read string|null $otherParticipant
+ * @mixin Conversation
+ * @property-read ?int $otherParticipantID
+ * @property-read ?string $otherParticipant
+ * @extends DatabaseObjectDecorator
*/
class ViewableConversation extends DatabaseObjectDecorator
{
/**
* participant summary
- * @var string
+ * @var User[]|null
*/
protected $__participantSummary;
/**
* user profile object
- * @var UserProfile
+ * @var ?UserProfile
*/
protected $userProfile;
/**
* last poster's profile
- * @var UserProfile
+ * @var ?UserProfile
*/
protected $lastPosterProfile;
/**
* other participant's profile
- * @var UserProfile
+ * @var ?UserProfile
*/
protected $otherParticipantProfile;
@@ -63,7 +63,7 @@ class ViewableConversation extends DatabaseObjectDecorator
/**
* Returns the user profile object.
*
- * @return UserProfile
+ * @return UserProfile
*/
public function getUserProfile()
{
@@ -81,7 +81,7 @@ public function getUserProfile()
/**
* Returns the last poster's profile object.
*
- * @return UserProfile
+ * @return UserProfile
*/
public function getLastPosterProfile()
{
@@ -99,7 +99,7 @@ public function getLastPosterProfile()
/**
* Returns the number of pages in this conversation.
*
- * @return int
+ * @return int
*/
public function getPages()
{
@@ -111,13 +111,13 @@ public function getPages()
$messagesPerPage = CONVERSATION_MESSAGES_PER_PAGE;
}
- return \intval(\ceil(($this->replies + 1) / $messagesPerPage));
+ return (int)\ceil(($this->replies + 1) / $messagesPerPage);
}
/**
* Returns a summary of the participants.
*
- * @return User[]
+ * @return User[]
*/
public function getParticipantSummary()
{
@@ -144,7 +144,7 @@ public function getParticipantSummary()
/**
* Returns the other participant's profile object.
*
- * @return UserProfile
+ * @return UserProfile
*/
public function getOtherParticipantProfile()
{
@@ -163,7 +163,7 @@ public function getOtherParticipantProfile()
/**
* Assigns a label.
*
- * @param ConversationLabel $label
+ * @return void
*/
public function assignLabel(ConversationLabel $label)
{
@@ -173,7 +173,7 @@ public function assignLabel(ConversationLabel $label)
/**
* Returns a list of assigned labels.
*
- * @return ConversationLabel[]
+ * @return ConversationLabel[]
*/
public function getAssignedLabels()
{
@@ -183,9 +183,7 @@ public function getAssignedLabels()
/**
* Converts a conversation into a viewable conversation.
*
- * @param Conversation $conversation
- * @param ConversationLabelList $labelList
- * @return ViewableConversation
+ * @return ViewableConversation
*/
public static function getViewableConversation(Conversation $conversation, ?ConversationLabelList $labelList = null)
{
diff --git a/files/lib/data/conversation/label/ConversationLabel.class.php b/files/lib/data/conversation/label/ConversationLabel.class.php
index e3b9a87e..f81ee91c 100644
--- a/files/lib/data/conversation/label/ConversationLabel.class.php
+++ b/files/lib/data/conversation/label/ConversationLabel.class.php
@@ -40,10 +40,9 @@ class ConversationLabel extends DatabaseObject
/**
* Returns a list of conversation labels for given user id.
*
- * @param int $userID
- * @return ConversationLabelList
+ * @return ConversationLabelList
*/
- public static function getLabelsByUser($userID = null)
+ public static function getLabelsByUser(?int $userID = null)
{
if ($userID === null) {
$userID = WCF::getUser()->userID;
@@ -59,7 +58,7 @@ public static function getLabelsByUser($userID = null)
/**
* Returns a list of available CSS class names.
*
- * @return string[]
+ * @return string[]
*/
public static function getLabelCssClassNames()
{
diff --git a/files/lib/data/conversation/label/ConversationLabelAction.class.php b/files/lib/data/conversation/label/ConversationLabelAction.class.php
index ac4a3c3e..8aa9f91f 100644
--- a/files/lib/data/conversation/label/ConversationLabelAction.class.php
+++ b/files/lib/data/conversation/label/ConversationLabelAction.class.php
@@ -13,9 +13,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationLabel create()
- * @method ConversationLabelEditor[] getObjects()
- * @method ConversationLabelEditor getSingleObject()
+ * @extends AbstractDatabaseObjectAction
*/
class ConversationLabelAction extends AbstractDatabaseObjectAction
{
diff --git a/files/lib/data/conversation/label/ConversationLabelEditor.class.php b/files/lib/data/conversation/label/ConversationLabelEditor.class.php
index 9b1d3af0..735918ac 100644
--- a/files/lib/data/conversation/label/ConversationLabelEditor.class.php
+++ b/files/lib/data/conversation/label/ConversationLabelEditor.class.php
@@ -11,9 +11,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method static ConversationLabel create(array $parameters = [])
- * @method ConversationLabel getDecoratedObject()
- * @mixin ConversationLabel
+ * @mixin ConversationLabel
+ * @extends DatabaseObjectEditor
*/
class ConversationLabelEditor extends DatabaseObjectEditor
{
diff --git a/files/lib/data/conversation/label/ConversationLabelList.class.php b/files/lib/data/conversation/label/ConversationLabelList.class.php
index b99786e1..5d7fd5f8 100644
--- a/files/lib/data/conversation/label/ConversationLabelList.class.php
+++ b/files/lib/data/conversation/label/ConversationLabelList.class.php
@@ -11,11 +11,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationLabel current()
- * @method ConversationLabel[] getObjects()
- * @method ConversationLabel|null getSingleObject()
- * @method ConversationLabel|null search($objectID)
- * @property ConversationLabel[] $objects
+ * @extends DatabaseObjectList
*/
class ConversationLabelList extends DatabaseObjectList
{
diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php
index 96f13a58..214fdfcc 100644
--- a/files/lib/data/conversation/message/ConversationMessage.class.php
+++ b/files/lib/data/conversation/message/ConversationMessage.class.php
@@ -41,7 +41,7 @@ class ConversationMessage extends DatabaseObject implements IMessage, IEmbeddedM
/**
* conversation object
- * @var Conversation
+ * @var ?Conversation
*/
protected $conversation;
@@ -71,10 +71,9 @@ public function getSimplifiedFormattedMessage(): string
/**
* Assigns and returns the embedded attachments.
*
- * @param bool $ignoreCache
- * @return null|GroupedAttachmentList
+ * @return ?GroupedAttachmentList
*/
- public function getAttachments($ignoreCache = false)
+ public function getAttachments(bool $ignoreCache = false)
{
if ($this->attachments || $ignoreCache) {
$attachmentList = new GroupedAttachmentList('com.woltlab.wcf.conversation.message');
@@ -108,7 +107,7 @@ public function getExcerpt($maxLength = 255): string
*
* @param string $mimeType Either 'text/plain' or 'text/html'
*/
- public function getMailText($mimeType = 'text/plain'): string
+ public function getMailText(string $mimeType = 'text/plain'): string
{
if ($this->hasEmbeddedObjects) {
MessageEmbeddedObjectManager::getInstance()->loadObjects(
@@ -134,7 +133,7 @@ public function getMailText($mimeType = 'text/plain'): string
/**
* Returns the conversation of this message.
*
- * @return Conversation
+ * @return ?Conversation
*/
public function getConversation()
{
@@ -148,7 +147,7 @@ public function getConversation()
/**
* Sets the conversation of this message.
*
- * @param Conversation $conversation
+ * @return void
*/
public function setConversation(Conversation $conversation)
{
diff --git a/files/lib/data/conversation/message/ConversationMessageAction.class.php b/files/lib/data/conversation/message/ConversationMessageAction.class.php
index f7617e88..d0655c4d 100644
--- a/files/lib/data/conversation/message/ConversationMessageAction.class.php
+++ b/files/lib/data/conversation/message/ConversationMessageAction.class.php
@@ -41,8 +41,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessageEditor[] getObjects()
- * @method ConversationMessageEditor getSingleObject()
+ * @extends AbstractDatabaseObjectAction
+ * @implements IAttachmentMessageQuickReplyAction
*/
class ConversationMessageAction extends AbstractDatabaseObjectAction implements
IAttachmentMessageQuickReplyAction,
@@ -72,7 +72,6 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements
/**
* @inheritDoc
- * @return ConversationMessage
*/
public function create()
{
@@ -81,7 +80,7 @@ public function create()
}
// count attachments
- if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) {
+ if (isset($this->parameters['attachmentHandler'])) {
$this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']);
}
@@ -103,7 +102,6 @@ public function create()
}
// create message
- /** @var ConversationMessage $message */
$message = parent::create();
$messageEditor = new ConversationMessageEditor($message);
@@ -157,7 +155,7 @@ public function create()
);
// update attachments
- if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) {
+ if (isset($this->parameters['attachmentHandler'])) {
/** @noinspection PhpUndefinedMethodInspection */
$this->parameters['attachmentHandler']->updateObjectID($message->messageID);
}
@@ -202,7 +200,7 @@ public function create()
public function update()
{
// count attachments
- if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) {
+ if (isset($this->parameters['attachmentHandler'])) {
$this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']);
}
@@ -318,6 +316,7 @@ public function quickReply()
$returnValues = QuickReplyManager::getInstance()->createMessage(
$this,
$this->parameters,
+ // @phpstan-ignore argument.type
ConversationAction::class,
CONVERSATION_LIST_DEFAULT_SORT_ORDER,
'conversationMessageList'
@@ -490,8 +489,6 @@ public function save()
*/
public function validateContainer(DatabaseObject $container)
{
- /** @var Conversation $container */
-
if (!$container->conversationID) {
throw new UserInputException('objectID');
}
@@ -547,10 +544,8 @@ public function validateMessage(DatabaseObject $container, HtmlInputProcessor $h
/**
* @inheritDoc
*/
- public function getMessageList(DatabaseObject $container, $lastMessageTime)
+ public function getMessageList(DatabaseObject $container, int $lastMessageTime)
{
- /** @var Conversation $container */
-
$messageList = new ViewableConversationMessageList();
$messageList->setConversation($container);
$messageList->getConditionBuilder()
@@ -568,8 +563,6 @@ public function getMessageList(DatabaseObject $container, $lastMessageTime)
*/
public function getPageNo(DatabaseObject $container)
{
- /** @var Conversation $container */
-
$sql = "SELECT COUNT(*) AS count
FROM wcf1_conversation_message
WHERE conversationID = ?";
@@ -585,7 +578,6 @@ public function getPageNo(DatabaseObject $container)
*/
public function getRedirectUrl(DatabaseObject $container, DatabaseObject $message)
{
- /** @var ConversationMessage $message */
return $message->getLink();
}
@@ -600,7 +592,7 @@ public function getAttachmentHandler(DatabaseObject $container)
/**
* @inheritDoc
*/
- public function getHtmlInputProcessor($message = null, $objectID = 0)
+ public function getHtmlInputProcessor(?string $message = null, int $objectID = 0)
{
if ($message === null) {
return $this->htmlInputProcessor;
diff --git a/files/lib/data/conversation/message/ConversationMessageEditor.class.php b/files/lib/data/conversation/message/ConversationMessageEditor.class.php
index 4d0c62cb..c684752f 100644
--- a/files/lib/data/conversation/message/ConversationMessageEditor.class.php
+++ b/files/lib/data/conversation/message/ConversationMessageEditor.class.php
@@ -11,9 +11,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method static ConversationMessage create(array $parameters = [])
- * @method ConversationMessage getDecoratedObject()
- * @mixin ConversationMessage
+ * @mixin ConversationMessage
+ * @extends DatabaseObjectEditor
*/
class ConversationMessageEditor extends DatabaseObjectEditor
{
diff --git a/files/lib/data/conversation/message/ConversationMessageList.class.php b/files/lib/data/conversation/message/ConversationMessageList.class.php
index 20b1990e..331f4793 100644
--- a/files/lib/data/conversation/message/ConversationMessageList.class.php
+++ b/files/lib/data/conversation/message/ConversationMessageList.class.php
@@ -2,6 +2,7 @@
namespace wcf\data\conversation\message;
+use wcf\data\DatabaseObjectDecorator;
use wcf\data\DatabaseObjectList;
/**
@@ -11,11 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessage current()
- * @method ConversationMessage[] getObjects()
- * @method ConversationMessage|null getSingleObject()
- * @method ConversationMessage|null search($objectID)
- * @property ConversationMessage[] $objects
+ * @template TDatabaseObject of ConversationMessage|DatabaseObjectDecorator = ConversationMessage
+ * @extends DatabaseObjectList
*/
class ConversationMessageList extends DatabaseObjectList
{
diff --git a/files/lib/data/conversation/message/SearchResultConversationMessage.class.php b/files/lib/data/conversation/message/SearchResultConversationMessage.class.php
index 342e4dee..58494c43 100644
--- a/files/lib/data/conversation/message/SearchResultConversationMessage.class.php
+++ b/files/lib/data/conversation/message/SearchResultConversationMessage.class.php
@@ -14,7 +14,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @property-read string|null $subject
+ * @property-read ?string $subject
*/
class SearchResultConversationMessage extends ViewableConversationMessage implements ISearchResultObject
{
diff --git a/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php b/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php
index 365dc8f3..3b915798 100644
--- a/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php
+++ b/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php
@@ -9,11 +9,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method SearchResultConversationMessage current()
- * @method SearchResultConversationMessage[] getObjects()
- * @method SearchResultConversationMessage|null getSingleObject()
- * @method SearchResultConversationMessage|null search($objectID)
- * @property SearchResultConversationMessage[] $objects
+ * @extends SimplifiedViewableConversationMessageList
*/
class SearchResultConversationMessageList extends SimplifiedViewableConversationMessageList
{
diff --git a/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php b/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php
index 3edaf7a4..06350305 100644
--- a/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php
+++ b/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php
@@ -9,6 +9,9 @@
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
+ *
+ * @template TDatabaseObject of ViewableConversationMessage = ViewableConversationMessage
+ * @extends ViewableConversationMessageList
*/
class SimplifiedViewableConversationMessageList extends ViewableConversationMessageList
{
diff --git a/files/lib/data/conversation/message/ViewableConversationMessage.class.php b/files/lib/data/conversation/message/ViewableConversationMessage.class.php
index a030ba70..5db50c28 100644
--- a/files/lib/data/conversation/message/ViewableConversationMessage.class.php
+++ b/files/lib/data/conversation/message/ViewableConversationMessage.class.php
@@ -13,8 +13,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessage getDecoratedObject()
- * @mixin ConversationMessage
+ * @mixin ConversationMessage
+ * @extends DatabaseObjectDecorator
*/
class ViewableConversationMessage extends DatabaseObjectDecorator
{
diff --git a/files/lib/data/conversation/message/ViewableConversationMessageList.class.php b/files/lib/data/conversation/message/ViewableConversationMessageList.class.php
index 34c02ee3..d690e870 100644
--- a/files/lib/data/conversation/message/ViewableConversationMessageList.class.php
+++ b/files/lib/data/conversation/message/ViewableConversationMessageList.class.php
@@ -15,11 +15,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ViewableConversationMessage current()
- * @method ViewableConversationMessage[] getObjects()
- * @method ViewableConversationMessage|null getSingleObject()
- * @method ViewableConversationMessage|null search($objectID)
- * @property ViewableConversationMessage[] $objects
+ * @template TDatabaseObject of ViewableConversationMessage = ViewableConversationMessage
+ * @extends ConversationMessageList
*/
class ViewableConversationMessageList extends ConversationMessageList
{
@@ -47,7 +44,7 @@ class ViewableConversationMessageList extends ConversationMessageList
/**
* attachment list
- * @var GroupedAttachmentList
+ * @var ?GroupedAttachmentList
*/
protected $attachmentList;
@@ -121,6 +118,8 @@ public function readObjects()
/**
* Reads the embedded objects of the messages in the list.
+ *
+ * @return void
*/
public function readEmbeddedObjects()
{
@@ -139,6 +138,8 @@ public function readEmbeddedObjects()
/**
* Reads the list of attachments.
+ *
+ * @return void
*/
public function readAttachments()
{
@@ -153,7 +154,7 @@ public function readAttachments()
/**
* Returns the max post time.
*
- * @return int
+ * @return int
*/
public function getMaxPostTime()
{
@@ -163,7 +164,7 @@ public function getMaxPostTime()
/**
* Returns the list of attachments.
*
- * @return GroupedAttachmentList
+ * @return ?GroupedAttachmentList
*/
public function getAttachmentList()
{
@@ -173,9 +174,9 @@ public function getAttachmentList()
/**
* Enables/disables the loading of attachments.
*
- * @param bool $enable
+ * @return void
*/
- public function enableAttachmentLoading($enable = true)
+ public function enableAttachmentLoading(bool $enable = true)
{
$this->attachmentLoading = $enable;
}
@@ -183,9 +184,9 @@ public function enableAttachmentLoading($enable = true)
/**
* Enables/disables the loading of embedded objects.
*
- * @param bool $enable
+ * @return void
*/
- public function enableEmbeddedObjectLoading($enable = true)
+ public function enableEmbeddedObjectLoading(bool $enable = true)
{
$this->embeddedObjectLoading = $enable;
}
@@ -193,7 +194,7 @@ public function enableEmbeddedObjectLoading($enable = true)
/**
* Sets active conversation.
*
- * @param Conversation $conversation
+ * @return void
*/
public function setConversation(Conversation $conversation)
{
diff --git a/files/lib/data/modification/log/ConversationLogModificationLogList.class.php b/files/lib/data/modification/log/ConversationLogModificationLogList.class.php
index c4ac1811..dc09772c 100644
--- a/files/lib/data/modification/log/ConversationLogModificationLogList.class.php
+++ b/files/lib/data/modification/log/ConversationLogModificationLogList.class.php
@@ -2,6 +2,7 @@
namespace wcf\data\modification\log;
+use wcf\data\DatabaseObject;
use wcf\system\cache\runtime\UserProfileRuntimeCache;
use wcf\system\log\modification\ConversationModificationLogHandler;
use wcf\system\WCF;
@@ -13,18 +14,14 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ViewableConversationModificationLog current()
- * @method ViewableConversationModificationLog[] getObjects()
- * @method ViewableConversationModificationLog|null getSingleObject()
- * @method ViewableConversationModificationLog|null search($objectID)
- * @property ViewableConversationModificationLog[] $objects
+ * @extends ModificationLogList
*/
class ConversationLogModificationLogList extends ModificationLogList
{
/**
* @inheritDoc
*/
- public function __construct($conversationID)
+ public function __construct(int $conversationID)
{
parent::__construct();
@@ -50,11 +47,13 @@ public function readObjects()
" . (!empty($this->sqlOrderBy) ? "ORDER BY " . $this->sqlOrderBy : '');
$statement = WCF::getDB()->prepare($sql, $this->sqlLimit, $this->sqlOffset);
$statement->execute($this->getConditionBuilder()->getParameters());
+ // @phpstan-ignore assign.propertyType, argument.templateType
$this->objects = $statement->fetchObjects(($this->objectClassName ?: $this->className));
// use table index as array index
$objects = $userIDs = [];
foreach ($this->objects as $object) {
+ /** @var ModificationLog $object */
$objectID = $object->{$this->getDatabaseTableIndexName()};
$objects[$objectID] = $object;
@@ -64,17 +63,16 @@ public function readObjects()
$userIDs[] = $object->userID;
}
}
- $this->objectIDs = $this->indexToObject;
- $this->objects = $objects;
- if (!empty($userIDs)) {
+ if ($userIDs !== []) {
UserProfileRuntimeCache::getInstance()->cacheObjectIDs($userIDs);
}
- foreach ($this->objects as &$object) {
- $object = new ViewableConversationModificationLog($object);
- }
- unset($object);
+ $this->objectIDs = $this->indexToObject;
+ $this->objects = \array_map(
+ static fn(DatabaseObject $object) => new ViewableConversationModificationLog($object),
+ $objects
+ );
}
/**
diff --git a/files/lib/data/modification/log/ViewableConversationModificationLog.class.php b/files/lib/data/modification/log/ViewableConversationModificationLog.class.php
index ce4bbf01..d9f86f70 100644
--- a/files/lib/data/modification/log/ViewableConversationModificationLog.class.php
+++ b/files/lib/data/modification/log/ViewableConversationModificationLog.class.php
@@ -14,8 +14,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ModificationLog getDecoratedObject()
- * @mixin ModificationLog
+ * @mixin ModificationLog
+ * @extends DatabaseObjectDecorator
*/
class ViewableConversationModificationLog extends DatabaseObjectDecorator
{
@@ -26,7 +26,7 @@ class ViewableConversationModificationLog extends DatabaseObjectDecorator
/**
* user profile object
- * @var UserProfile
+ * @var ?UserProfile
*/
protected $userProfile;
@@ -46,7 +46,7 @@ public function __toString()
/**
* Returns the profile object of the user who created the modification entry.
*
- * @return UserProfile
+ * @return UserProfile
*/
public function getUserProfile()
{
diff --git a/files/lib/form/ConversationAddForm.class.php b/files/lib/form/ConversationAddForm.class.php
index f4723f5f..9dfa97db 100644
--- a/files/lib/form/ConversationAddForm.class.php
+++ b/files/lib/form/ConversationAddForm.class.php
@@ -80,15 +80,15 @@ class ConversationAddForm extends MessageForm
/**
* draft status
- * @var int
+ * @var bool
*/
- public $draft = 0;
+ public $draft = false;
/**
* true, if participants can add new participants
- * @var int
+ * @var bool
*/
- public $participantCanInvite = 0;
+ public $participantCanInvite = false;
/**
* participants (user ids)
@@ -276,7 +276,7 @@ public function save()
'userID' => WCF::getUser()->userID,
'username' => WCF::getUser()->username,
'isDraft' => $this->draft ? 1 : 0,
- 'participantCanInvite' => $this->participantCanInvite,
+ 'participantCanInvite' => $this->participantCanInvite ? 1 : 0,
]);
if ($this->draft) {
$data['draftData'] = \serialize([
@@ -343,7 +343,7 @@ public function assignVariables()
}
WCF::getTPL()->assign([
- 'participantCanInvite' => $this->participantCanInvite,
+ 'participantCanInvite' => $this->participantCanInvite ? 1 : 0,
'participants' => $this->participants,
'participantsData' => $this->getParticipantsData(),
'invisibleParticipants' => $this->invisibleParticipants,
@@ -365,7 +365,14 @@ public function show()
parent::show();
}
- private function getParticipantsData($invisible = false)
+ /**
+ * @return list
+ */
+ private function getParticipantsData(bool $invisible = false): array
{
$result = [];
$participants = ArrayUtil::trim(\explode(
diff --git a/files/lib/form/ConversationDraftEditForm.class.php b/files/lib/form/ConversationDraftEditForm.class.php
index c72b4808..72ba10b3 100644
--- a/files/lib/form/ConversationDraftEditForm.class.php
+++ b/files/lib/form/ConversationDraftEditForm.class.php
@@ -149,7 +149,7 @@ public function readData()
if (empty($_POST)) {
$this->text = $this->conversation->getFirstMessage()->message;
- $this->participantCanInvite = $this->conversation->participantCanInvite;
+ $this->participantCanInvite = (bool)$this->conversation->participantCanInvite;
$this->subject = $this->conversation->subject;
if ($this->conversation->draftData) {
diff --git a/files/lib/page/ConversationFeedPage.class.php b/files/lib/page/ConversationFeedPage.class.php
index e7dfe701..80ff60a6 100644
--- a/files/lib/page/ConversationFeedPage.class.php
+++ b/files/lib/page/ConversationFeedPage.class.php
@@ -11,6 +11,8 @@
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
+ *
+ * @extends AbstractFeedPage
* @deprecated 6.1 use `ConversationRssFeedPage` instead
*/
class ConversationFeedPage extends AbstractFeedPage
diff --git a/files/lib/page/ConversationListPage.class.php b/files/lib/page/ConversationListPage.class.php
index b7e4095f..69c0ac1f 100644
--- a/files/lib/page/ConversationListPage.class.php
+++ b/files/lib/page/ConversationListPage.class.php
@@ -21,7 +21,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @property UserConversationList $objectList
+ * @extends SortablePage
*/
class ConversationListPage extends SortablePage
{
diff --git a/files/lib/page/ConversationPage.class.php b/files/lib/page/ConversationPage.class.php
index 0d58f2bc..931be5f3 100644
--- a/files/lib/page/ConversationPage.class.php
+++ b/files/lib/page/ConversationPage.class.php
@@ -32,7 +32,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @property ViewableConversationMessageList $objectList
+ * @extends MultipleLinkPage
*/
class ConversationPage extends MultipleLinkPage
{
@@ -365,6 +365,8 @@ public function assignVariables()
/**
* Calculates the position of a specific post in this conversation.
+ *
+ * @return void
*/
protected function goToPost()
{
@@ -382,6 +384,8 @@ protected function goToPost()
/**
* Gets the id of the last post in this conversation and forwards the user to this post.
+ *
+ * @return void
*/
protected function goToLastPost()
{
@@ -412,6 +416,8 @@ protected function goToLastPost()
/**
* Forwards the user to the first new message in this conversation.
+ *
+ * @return void
*/
protected function goToFirstNewPost()
{
diff --git a/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php b/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php
index c6964c20..f4cdfc60 100644
--- a/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php
+++ b/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php
@@ -15,7 +15,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessage getObject($objectID)
+ * @extends AbstractAttachmentObjectType
*/
class ConversationMessageAttachmentObjectType extends AbstractAttachmentObjectType
{
@@ -142,7 +142,7 @@ public function setPermissions(array $attachments)
}
}
- if (!empty($messageIDs)) {
+ if ($messageIDs !== []) {
$this->cacheObjects($messageIDs);
}
diff --git a/files/lib/system/cache/runtime/ConversationMessageRuntimeCache.class.php b/files/lib/system/cache/runtime/ConversationMessageRuntimeCache.class.php
index 82a1c363..303ae745 100644
--- a/files/lib/system/cache/runtime/ConversationMessageRuntimeCache.class.php
+++ b/files/lib/system/cache/runtime/ConversationMessageRuntimeCache.class.php
@@ -13,9 +13,7 @@
* @license GNU Lesser General Public License
* @since 6.1
*
- * @method ConversationMessage[] getCachedObjects()
- * @method ConversationMessage getObject($objectID)
- * @method ConversationMessage[] getObjects(array $objectIDs)
+ * @extends AbstractRuntimeCache
*/
class ConversationMessageRuntimeCache extends AbstractRuntimeCache
{
diff --git a/files/lib/system/cache/runtime/ConversationRuntimeCache.class.php b/files/lib/system/cache/runtime/ConversationRuntimeCache.class.php
index 8f5f9a2c..c430ec80 100644
--- a/files/lib/system/cache/runtime/ConversationRuntimeCache.class.php
+++ b/files/lib/system/cache/runtime/ConversationRuntimeCache.class.php
@@ -13,9 +13,7 @@
* @license GNU Lesser General Public License
* @since 3.0
*
- * @method Conversation[] getCachedObjects()
- * @method Conversation getObject($objectID)
- * @method Conversation[] getObjects(array $objectIDs)
+ * @extends AbstractRuntimeCache
*/
class ConversationRuntimeCache extends AbstractRuntimeCache
{
diff --git a/files/lib/system/cache/runtime/UserConversationRuntimeCache.class.php b/files/lib/system/cache/runtime/UserConversationRuntimeCache.class.php
index df671b46..34e6ed2c 100644
--- a/files/lib/system/cache/runtime/UserConversationRuntimeCache.class.php
+++ b/files/lib/system/cache/runtime/UserConversationRuntimeCache.class.php
@@ -14,9 +14,7 @@
* @license GNU Lesser General Public License
* @since 3.0
*
- * @method Conversation[] getCachedObjects()
- * @method Conversation getObject($objectID)
- * @method Conversation[] getObjects(array $objectIDs)
+ * @extends AbstractRuntimeCache
*/
class UserConversationRuntimeCache extends AbstractRuntimeCache
{
diff --git a/files/lib/system/clipboard/action/ConversationClipboardAction.class.php b/files/lib/system/clipboard/action/ConversationClipboardAction.class.php
index 76268da0..d5add99b 100644
--- a/files/lib/system/clipboard/action/ConversationClipboardAction.class.php
+++ b/files/lib/system/clipboard/action/ConversationClipboardAction.class.php
@@ -14,6 +14,8 @@
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
+ *
+ * @extends AbstractClipboardAction
*/
class ConversationClipboardAction extends AbstractClipboardAction
{
@@ -136,6 +138,7 @@ public function getTypeName()
* Returns a list of conversations with user participation.
*
* @param Conversation[] $conversations
+ * @return void
*/
protected function validateParticipation(array $conversations)
{
diff --git a/files/lib/system/conversation/command/DeleteEmptyConversations.class.php b/files/lib/system/conversation/command/DeleteEmptyConversations.class.php
index a0502f23..8c18db1c 100644
--- a/files/lib/system/conversation/command/DeleteEmptyConversations.class.php
+++ b/files/lib/system/conversation/command/DeleteEmptyConversations.class.php
@@ -18,12 +18,15 @@
*/
final class DeleteEmptyConversations
{
+ /**
+ * @param int[] $conversationIDs
+ */
public function __construct(
public readonly array $conversationIDs,
) {
}
- public function __invoke()
+ public function __invoke(): void
{
// update participants count and participant summary
ConversationEditor::updateParticipantCounts($this->conversationIDs);
diff --git a/files/lib/system/conversation/command/LeaveConversation.class.php b/files/lib/system/conversation/command/LeaveConversation.class.php
index 75db785f..385a6a9b 100644
--- a/files/lib/system/conversation/command/LeaveConversation.class.php
+++ b/files/lib/system/conversation/command/LeaveConversation.class.php
@@ -19,6 +19,9 @@
*/
final class LeaveConversation
{
+ /**
+ * @param int[] $conversationIDs
+ */
public function __construct(
public readonly array $conversationIDs,
public readonly int $hideConversation
@@ -33,7 +36,7 @@ public function __construct(
}
}
- public function __invoke()
+ public function __invoke(): void
{
$sql = "UPDATE wcf1_conversation_to_user
SET hideConversation = ?
diff --git a/files/lib/system/endpoint/controller/core/conversations/AssignConversationLabels.class.php b/files/lib/system/endpoint/controller/core/conversations/AssignConversationLabels.class.php
index 15b3bba9..f983ad67 100644
--- a/files/lib/system/endpoint/controller/core/conversations/AssignConversationLabels.class.php
+++ b/files/lib/system/endpoint/controller/core/conversations/AssignConversationLabels.class.php
@@ -65,6 +65,9 @@ public function __invoke(ServerRequestInterface $request, array $variables): Res
return new JsonResponse([]);
}
+ /**
+ * @param int[] $conversationIDs
+ */
private function removeOldLabels(ConversationLabelList $labelList, array $conversationIDs): void
{
// remove previous labels (if any)
@@ -83,6 +86,10 @@ private function removeOldLabels(ConversationLabelList $labelList, array $conver
$statement->execute($conditions->getParameters());
}
+ /**
+ * @param int[] $conversationIDs
+ * @param int[] $labelIDs
+ */
private function assignLabels(array $conversationIDs, array $labelIDs): void
{
if ($labelIDs === []) {
diff --git a/files/lib/system/endpoint/controller/core/conversations/GetConversationLabels.class.php b/files/lib/system/endpoint/controller/core/conversations/GetConversationLabels.class.php
index b9ff88f0..1fbd2e6a 100644
--- a/files/lib/system/endpoint/controller/core/conversations/GetConversationLabels.class.php
+++ b/files/lib/system/endpoint/controller/core/conversations/GetConversationLabels.class.php
@@ -85,6 +85,10 @@ private function getForm(string $id, ConversationLabelList $labelList, ?int $con
->build();
}
+ /**
+ * @param int[] $labelIDs
+ * @return int[]
+ */
private function getAssignedLabelIDs(array $labelIDs, ?int $conversationID): array
{
if ($conversationID === null) {
diff --git a/files/lib/system/event/listener/UserGroupAddCanBeAddedAsConversationParticipantListener.class.php b/files/lib/system/event/listener/UserGroupAddCanBeAddedAsConversationParticipantListener.class.php
index 752df02f..13af1347 100644
--- a/files/lib/system/event/listener/UserGroupAddCanBeAddedAsConversationParticipantListener.class.php
+++ b/files/lib/system/event/listener/UserGroupAddCanBeAddedAsConversationParticipantListener.class.php
@@ -24,7 +24,7 @@ class UserGroupAddCanBeAddedAsConversationParticipantListener implements IParame
/**
* true if group can be added as participant
- * @var bool
+ * @var int
*/
protected $canBeAddedAsConversationParticipant = 0;
@@ -35,7 +35,7 @@ public function execute($eventObj, $className, $eventName, array &$parameters)
{
$this->eventObj = $eventObj;
- if ($this->eventObj instanceof UserGroupEditForm && \is_object($this->eventObj->group)) {
+ if ($this->eventObj instanceof UserGroupEditForm && $this->eventObj->group !== null) {
switch ($this->eventObj->group->groupType) {
case UserGroup::EVERYONE:
case UserGroup::GUESTS:
@@ -49,6 +49,8 @@ public function execute($eventObj, $className, $eventName, array &$parameters)
/**
* Handles the assignVariables event.
+ *
+ * @return void
*/
protected function assignVariables()
{
@@ -59,17 +61,23 @@ protected function assignVariables()
/**
* Handles the readData event.
- * This is only called in UserGroupEditForm.
+ *
+ * @return void
*/
protected function readData()
{
- if (empty($_POST)) {
+ \assert($this->eventObj instanceof UserGroupEditForm);
+
+ if ($_POST === []) {
+ // @phpstan-ignore property.notFound
$this->canBeAddedAsConversationParticipant = $this->eventObj->group->canBeAddedAsConversationParticipant;
}
}
/**
* Handles the readFormParameters event.
+ *
+ * @return void
*/
protected function readFormParameters()
{
@@ -80,6 +88,8 @@ protected function readFormParameters()
/**
* Handles the save event.
+ *
+ * @return void
*/
protected function save()
{
diff --git a/files/lib/system/log/modification/ConversationModificationLogHandler.class.php b/files/lib/system/log/modification/ConversationModificationLogHandler.class.php
index 334b1d78..12cd45d5 100644
--- a/files/lib/system/log/modification/ConversationModificationLogHandler.class.php
+++ b/files/lib/system/log/modification/ConversationModificationLogHandler.class.php
@@ -23,8 +23,8 @@ class ConversationModificationLogHandler extends VoidExtendedModificationLogHand
/**
* Adds a log entry for newly added conversation participants.
*
- * @param Conversation $conversation
* @param int[] $participantIDs
+ * @return void
*/
public function addParticipants(Conversation $conversation, array $participantIDs)
{
@@ -47,7 +47,7 @@ public function addParticipants(Conversation $conversation, array $participantID
/**
* Adds a log entry for conversation close.
*
- * @param Conversation $conversation
+ * @return void
*/
public function close(Conversation $conversation)
{
@@ -57,7 +57,7 @@ public function close(Conversation $conversation)
/**
* Adds a log entry for conversation open.
*
- * @param Conversation $conversation
+ * @return void
*/
public function open(Conversation $conversation)
{
@@ -67,7 +67,7 @@ public function open(Conversation $conversation)
/**
* Adds a log entry for conversation leave.
*
- * @param Conversation $conversation
+ * @return void
*/
public function leave(Conversation $conversation)
{
@@ -77,10 +77,9 @@ public function leave(Conversation $conversation)
/**
* Adds a log entry for a removed participant.
*
- * @param Conversation $conversation
- * @param int $userID
+ * @return void
*/
- public function removeParticipant(Conversation $conversation, $userID)
+ public function removeParticipant(Conversation $conversation, int $userID)
{
$user = new User($userID);
$this->add($conversation, 'removeParticipant', [
@@ -92,11 +91,10 @@ public function removeParticipant(Conversation $conversation, $userID)
/**
* Adds a conversation modification log entry.
*
- * @param Conversation $conversation
- * @param string $action
- * @param array $additionalData
+ * @param mixed[] $additionalData
+ * @return void
*/
- public function add(Conversation $conversation, $action, array $additionalData = [])
+ public function add(Conversation $conversation, string $action, array $additionalData = [])
{
$this->createLog($action, $conversation->conversationID, null, $additionalData);
}
@@ -106,6 +104,7 @@ public function add(Conversation $conversation, $action, array $additionalData =
* ids.
*
* @param int[] $objectIDs
+ * @return void
* @deprecated 3.0, use deleteLogs()
*/
public function remove(array $objectIDs)
diff --git a/files/lib/system/moderation/queue/report/ConversationMessageModerationQueueReportHandler.class.php b/files/lib/system/moderation/queue/report/ConversationMessageModerationQueueReportHandler.class.php
index 71e05d5c..375260c0 100644
--- a/files/lib/system/moderation/queue/report/ConversationMessageModerationQueueReportHandler.class.php
+++ b/files/lib/system/moderation/queue/report/ConversationMessageModerationQueueReportHandler.class.php
@@ -41,7 +41,7 @@ class ConversationMessageModerationQueueReportHandler extends AbstractModeration
/**
* list of conversation message
- * @var ConversationMessage[]
+ * @var array
*/
protected static $messages = [];
@@ -129,10 +129,9 @@ public function isValid($objectID)
/**
* Returns a conversation message object by message id or null if message id is invalid.
*
- * @param int $objectID
- * @return ConversationMessage
+ * @return ?ConversationMessage
*/
- protected function getMessage($objectID)
+ protected function getMessage(int $objectID)
{
if (!\array_key_exists($objectID, self::$messages)) {
self::$messages[$objectID] = new ConversationMessage($objectID);
diff --git a/files/lib/system/search/ConversationMessageSearch.class.php b/files/lib/system/search/ConversationMessageSearch.class.php
index f9aab10e..cab3fa87 100644
--- a/files/lib/system/search/ConversationMessageSearch.class.php
+++ b/files/lib/system/search/ConversationMessageSearch.class.php
@@ -18,21 +18,17 @@
*/
final class ConversationMessageSearch extends AbstractSearchProvider
{
- /**
- * @var int
- */
- private $conversationID = 0;
+ private int $conversationID = 0;
/**
* searched conversation
- * @var Conversation
*/
- private $conversation;
+ private Conversation $conversation;
/**
* @var SearchResultConversationMessage[]
*/
- private $messageCache = [];
+ private array $messageCache = [];
/**
* @inheritDoc
@@ -50,7 +46,7 @@ public function cacheObjects(array $objectIDs, ?array $additionalData = null): v
/**
* @inheritDoc
*/
- public function getAdditionalData(): ?array
+ public function getAdditionalData(): array
{
return [
'conversationID' => $this->conversationID,
@@ -104,7 +100,7 @@ public function getSubjectFieldName(): string
/**
* @inheritDoc
*/
- public function getConditionBuilder(array $parameters): ?PreparedStatementConditionBuilder
+ public function getConditionBuilder(array $parameters): PreparedStatementConditionBuilder
{
$this->readParameters($parameters);
@@ -137,7 +133,7 @@ public function isAccessible(): bool
*/
public function getFormTemplateName(): string
{
- if ($this->conversation) {
+ if (isset($this->conversation)) {
return 'searchConversationMessage';
}
@@ -159,7 +155,7 @@ public function assignVariables(): void
}
/**
- * @inheritDoc
+ * @param array $parameters
*/
private function readParameters(array $parameters): void
{
diff --git a/files/lib/system/user/content/provider/ConversationMessageUserContentProvider.class.php b/files/lib/system/user/content/provider/ConversationMessageUserContentProvider.class.php
index dcdf06f1..03fffdb6 100644
--- a/files/lib/system/user/content/provider/ConversationMessageUserContentProvider.class.php
+++ b/files/lib/system/user/content/provider/ConversationMessageUserContentProvider.class.php
@@ -3,6 +3,7 @@
namespace wcf\system\user\content\provider;
use wcf\data\conversation\message\ConversationMessage;
+use wcf\data\conversation\message\ConversationMessageList;
/**
* User content provider for conversation messages.
@@ -11,6 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
* @since 5.2
+ *
+ * @extends AbstractDatabaseUserContentProvider
*/
class ConversationMessageUserContentProvider extends AbstractDatabaseUserContentProvider
{
diff --git a/files/lib/system/user/content/provider/ConversationUserContentProvider.class.php b/files/lib/system/user/content/provider/ConversationUserContentProvider.class.php
index 1145d864..980e8758 100644
--- a/files/lib/system/user/content/provider/ConversationUserContentProvider.class.php
+++ b/files/lib/system/user/content/provider/ConversationUserContentProvider.class.php
@@ -3,6 +3,7 @@
namespace wcf\system\user\content\provider;
use wcf\data\conversation\Conversation;
+use wcf\data\conversation\ConversationList;
/**
* User content provider for conversations.
@@ -11,6 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
* @since 5.2
+ *
+ * @extends AbstractDatabaseUserContentProvider
*/
class ConversationUserContentProvider extends AbstractDatabaseUserContentProvider
{
diff --git a/files/lib/system/user/notification/object/ConversationMessageUserNotificationObject.class.php b/files/lib/system/user/notification/object/ConversationMessageUserNotificationObject.class.php
index 3ca8b361..fbcd4319 100644
--- a/files/lib/system/user/notification/object/ConversationMessageUserNotificationObject.class.php
+++ b/files/lib/system/user/notification/object/ConversationMessageUserNotificationObject.class.php
@@ -12,8 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessage getDecoratedObject()
- * @mixin ConversationMessage
+ * @mixin ConversationMessage
+ * @extends DatabaseObjectDecorator
*/
class ConversationMessageUserNotificationObject extends DatabaseObjectDecorator implements IUserNotificationObject
{
diff --git a/files/lib/system/user/notification/object/ConversationUserNotificationObject.class.php b/files/lib/system/user/notification/object/ConversationUserNotificationObject.class.php
index 5bedbae6..e20b654b 100644
--- a/files/lib/system/user/notification/object/ConversationUserNotificationObject.class.php
+++ b/files/lib/system/user/notification/object/ConversationUserNotificationObject.class.php
@@ -12,8 +12,8 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method Conversation getDecoratedObject()
- * @mixin Conversation
+ * @mixin Conversation
+ * @extends DatabaseObjectDecorator
*/
class ConversationUserNotificationObject extends DatabaseObjectDecorator implements IUserNotificationObject
{
diff --git a/files/lib/system/worker/ConversationMessageRebuildDataWorker.class.php b/files/lib/system/worker/ConversationMessageRebuildDataWorker.class.php
index 97adba35..d92ae3eb 100644
--- a/files/lib/system/worker/ConversationMessageRebuildDataWorker.class.php
+++ b/files/lib/system/worker/ConversationMessageRebuildDataWorker.class.php
@@ -16,7 +16,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessageList getObjectList()
+ * @extends AbstractRebuildDataWorker
*/
class ConversationMessageRebuildDataWorker extends AbstractRebuildDataWorker
{
diff --git a/files/lib/system/worker/ConversationMessageSearchIndexRebuildDataWorker.class.php b/files/lib/system/worker/ConversationMessageSearchIndexRebuildDataWorker.class.php
index 7972ef1f..8ae4d47b 100644
--- a/files/lib/system/worker/ConversationMessageSearchIndexRebuildDataWorker.class.php
+++ b/files/lib/system/worker/ConversationMessageSearchIndexRebuildDataWorker.class.php
@@ -14,7 +14,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationMessageList getObjectList()
+ * @extends AbstractRebuildDataWorker
*/
final class ConversationMessageSearchIndexRebuildDataWorker extends AbstractRebuildDataWorker
{
diff --git a/files/lib/system/worker/ConversationRebuildDataWorker.class.php b/files/lib/system/worker/ConversationRebuildDataWorker.class.php
index 0b104101..016de8be 100644
--- a/files/lib/system/worker/ConversationRebuildDataWorker.class.php
+++ b/files/lib/system/worker/ConversationRebuildDataWorker.class.php
@@ -15,7 +15,7 @@
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License
*
- * @method ConversationList getObjectList()
+ * @extends AbstractRebuildDataWorker
*/
class ConversationRebuildDataWorker extends AbstractRebuildDataWorker
{
diff --git a/phpstan-ambient.neon b/phpstan-ambient.neon
new file mode 100644
index 00000000..db87f942
--- /dev/null
+++ b/phpstan-ambient.neon
@@ -0,0 +1,7 @@
+parameters:
+ dynamicConstantNames:
+ - MODULE_CONVERSATION
+ - CONVERSATIONS_PER_PAGE
+ - CONVERSATION_MESSAGES_PER_PAGE
+ - CONVERSATION_LIST_DEFAULT_SORT_FIELD
+ - CONVERSATION_LIST_DEFAULT_SORT_ORDER
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 00000000..69b765aa
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,13 @@
+includes:
+ - phpstan-ambient.neon
+ - ../WCF/phpstan-ambient.neon
+
+parameters:
+ level: 6
+ paths:
+ - files
+ scanFiles:
+ - constants.php
+ - ../WCF/constants.php
+ scanDirectories:
+ - ../WCF/wcfsetup/install/files