Merge branch '2.1'
[GitHub/WoltLab/com.woltlab.wcf.conversation.git] / files / lib / data / conversation / ViewableConversation.class.php
1 <?php
2 namespace wcf\data\conversation;
3 use wcf\data\conversation\label\ConversationLabel;
4 use wcf\data\conversation\label\ConversationLabelList;
5 use wcf\data\user\User;
6 use wcf\data\user\UserProfile;
7 use wcf\data\DatabaseObjectDecorator;
8 use wcf\data\TLegacyUserPropertyAccess;
9 use wcf\system\cache\runtime\UserProfileRuntimeCache;
10 use wcf\system\database\util\PreparedStatementConditionBuilder;
11 use wcf\system\WCF;
12
13 /**
14 * Represents a viewable conversation.
15 *
16 * @author Marcel Werk
17 * @copyright 2001-2017 WoltLab GmbH
18 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
19 * @package WoltLabSuite\Core\Data\Conversation
20 *
21 * @method Conversation getDecoratedObject()
22 * @mixin Conversation
23 * @property-read integer|null $otherParticipantID
24 * @property-read string|null $otherParticipant
25 */
26 class ViewableConversation extends DatabaseObjectDecorator {
27 use TLegacyUserPropertyAccess;
28
29 /**
30 * participant summary
31 * @var string
32 */
33 protected $__participantSummary;
34
35 /**
36 * user profile object
37 * @var UserProfile
38 */
39 protected $userProfile;
40
41 /**
42 * last poster's profile
43 * @var UserProfile
44 */
45 protected $lastPosterProfile;
46
47 /**
48 * other participant's profile
49 * @var UserProfile
50 */
51 protected $otherParticipantProfile;
52
53 /**
54 * list of assigned labels
55 * @var ConversationLabel[]
56 */
57 protected $labels = [];
58
59 /**
60 * @inheritDoc
61 */
62 protected static $baseClass = Conversation::class;
63
64 /**
65 * maps legacy direct access to last poster's user profile data to the real
66 * user profile property names
67 * @var string[]
68 * @deprecated
69 */
70 protected static $__lastUserAvatarPropertyMapping = [
71 'lastPosterAvatarID' => 'avatarID',
72 'lastPosterAvatarName' => 'avatarName',
73 'lastPosterAvatarExtension' => 'avatarExtension',
74 'lastPosterAvatarWidth' => 'width',
75 'lastPosterAvatarHeight' => 'height',
76 'lastPosterEmail' => 'email',
77 'lastPosterDisableAvatar' => 'disableAvatar',
78 'lastPosterEnableGravatar' => 'enableGravatar',
79 'lastPosterGravatarFileExtension' => 'gravatarFileExtension',
80 'lastPosterAvatarFileHash' => 'fileHash'
81 ];
82
83 /**
84 * @inheritDoc
85 * @deprecated
86 */
87 public function __get($name) {
88 $value = parent::__get($name);
89 if ($value !== null) {
90 return $value;
91 }
92 else if (array_key_exists($name, $this->object->data)) {
93 return null;
94 }
95
96 /** @noinspection PhpVariableVariableInspection */
97 $value = $this->getUserProfile()->$name;
98 if ($value !== null) {
99 return $value;
100 }
101
102 if (isset(static::$__lastUserAvatarPropertyMapping[$name])) {
103 return $this->getLastPosterProfile()->getAvatar()->{static::$__lastUserAvatarPropertyMapping[$name]};
104 }
105
106 return null;
107 }
108
109 /**
110 * Returns the user profile object.
111 *
112 * @return UserProfile
113 */
114 public function getUserProfile() {
115 if ($this->userProfile === null) {
116 if ($this->userID) {
117 $this->userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->userID);
118 }
119 else {
120 $this->userProfile = UserProfile::getGuestUserProfile($this->username);
121 }
122 }
123
124 return $this->userProfile;
125 }
126
127 /**
128 * Returns the last poster's profile object.
129 *
130 * @return UserProfile
131 */
132 public function getLastPosterProfile() {
133 if ($this->lastPosterProfile === null) {
134 if ($this->lastPosterID) {
135 $this->lastPosterProfile = UserProfileRuntimeCache::getInstance()->getObject($this->lastPosterID);
136 }
137 else {
138 $this->lastPosterProfile = UserProfile::getGuestUserProfile($this->lastPoster);
139 }
140 }
141
142 return $this->lastPosterProfile;
143 }
144
145 /**
146 * Returns the number of pages in this conversation.
147 *
148 * @return integer
149 */
150 public function getPages() {
151 /** @noinspection PhpUndefinedFieldInspection */
152 if (WCF::getUser()->conversationMessagesPerPage) {
153 /** @noinspection PhpUndefinedFieldInspection */
154 $messagesPerPage = WCF::getUser()->conversationMessagesPerPage;
155 }
156 else {
157 $messagesPerPage = CONVERSATION_MESSAGES_PER_PAGE;
158 }
159
160 return intval(ceil(($this->replies + 1) / $messagesPerPage));
161 }
162
163 /**
164 * Returns a summary of the participants.
165 *
166 * @return User[]
167 */
168 public function getParticipantSummary() {
169 if ($this->__participantSummary === null) {
170 $this->__participantSummary = [];
171
172 if ($this->participantSummary) {
173 $data = unserialize($this->participantSummary);
174 if ($data !== false) {
175 foreach ($data as $userData) {
176 $this->__participantSummary[] = new User(null, [
177 'userID' => $userData['userID'],
178 'username' => $userData['username'],
179 'hideConversation' => $userData['hideConversation']
180 ]);
181 }
182 }
183 }
184 }
185
186 return $this->__participantSummary;
187 }
188
189 /**
190 * Returns the other participant's profile object.
191 *
192 * @return UserProfile
193 */
194 public function getOtherParticipantProfile() {
195 if ($this->otherParticipantProfile === null) {
196 if ($this->otherParticipantID) {
197 $this->otherParticipantProfile = UserProfileRuntimeCache::getInstance()->getObject($this->otherParticipantID);
198 }
199 else {
200 $this->otherParticipantProfile = UserProfile::getGuestUserProfile($this->otherParticipant);
201 }
202 }
203
204 return $this->otherParticipantProfile;
205 }
206
207 /**
208 * Assigns a label.
209 *
210 * @param ConversationLabel $label
211 */
212 public function assignLabel(ConversationLabel $label) {
213 $this->labels[$label->labelID] = $label;
214 }
215
216 /**
217 * Returns a list of assigned labels.
218 *
219 * @return ConversationLabel[]
220 */
221 public function getAssignedLabels() {
222 return $this->labels;
223 }
224
225 /**
226 * Converts a conversation into a viewable conversation.
227 *
228 * @param Conversation $conversation
229 * @param ConversationLabelList $labelList
230 * @return ViewableConversation
231 */
232 public static function getViewableConversation(Conversation $conversation, ConversationLabelList $labelList = null) {
233 $conversation = new ViewableConversation($conversation);
234
235 if ($labelList === null) {
236 $labelList = ConversationLabel::getLabelsByUser();
237 }
238
239 $labels = $labelList->getObjects();
240 if (!empty($labels)) {
241 $conditions = new PreparedStatementConditionBuilder();
242 $conditions->add("conversationID = ?", [$conversation->conversationID]);
243 $conditions->add("labelID IN (?)", [array_keys($labels)]);
244
245 $sql = "SELECT labelID
246 FROM wcf".WCF_N."_conversation_label_to_object
247 ".$conditions;
248 $statement = WCF::getDB()->prepareStatement($sql);
249 $statement->execute($conditions->getParameters());
250 while ($row = $statement->fetchArray()) {
251 $conversation->assignLabel($labels[$row['labelID']]);
252 }
253 }
254
255 return $conversation;
256 }
257 }