Renderer::_adjustGuestContext()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 12
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Part of the files dealing with preparing the content for display posts
5
 * via callbacks (Display, PM, Search).
6
 *
7
 * @package   ElkArte Forum
8
 * @copyright ElkArte Forum contributors
9
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
10
 *
11
 * @version 2.0 dev
12
 *
13
 */
14
15
namespace ElkArte\MessagesCallback;
16
17
use ElkArte\Helper\ValuesContainer;
18
use ElkArte\MembersList;
19
use ElkArte\MessagesCallback\BodyParser\BodyParserInterface;
20
use ElkArte\EventManager;
21
22
/**
23
 * Class Renderer
24
 *
25
 * The common skeleton to display content via callback.
26
 * Classes extending this abstract should declare two constants:
27
 *   - BEFORE_PREPARE_HOOK
28
 *   - CONTEXT_HOOK
29
 * that will be strings used as hook names.
30
 *
31
 * @package ElkArte\MessagesCallback
32
 */
33
abstract class Renderer
34
{
35
	/** @var Object The database object */
36
	protected $_db;
37
38
	/** @var ValuesContainer Some options */
39
	protected $_options;
40
41
	/** @var int Position tracker, to know where we are into the request */
42
	protected $_counter = 0;
43
44
	/** @var bool Should we show the signature of this message? */
45
	protected $_signature_shown;
46
47
	/** @var array The current message being prepared */
48
	protected $_this_message;
49
50
	/** @var ValuesContainer Index mapping, to normalize certain indexes across requests */
51
	protected $_idx_mapper = [];
52
53
	/**
54
	 * Renderer constructor, starts everything.
55
	 *
56
	 * @param Object $_dbRequest
57
	 * @param Object $user
58
	 * @param BodyParserInterface $_bodyParser
59
	 * @param ValuesContainer $opt
60
	 */
61
	public function __construct(protected $_dbRequest, protected $user, protected $_bodyParser, $opt = null)
62
	{
63
		$this->_db = database();
64
		$this->_idx_mapper = new ValuesContainer([
65
			'id_msg' => 'id_msg',
66
			'id_member' => 'id_member',
67
			'name' => 'poster_name',
68
			'time' => 'poster_time',
69
		]);
70
71
		// opt:
72
		// icon_sources
73
		// show_signatures
74
		$this->_options = $opt ?? new ValuesContainer();
75
	}
76
77
	/**
78
	 * The main part: reads the DB resource and returns the complex array
79
	 * for a certain message.
80
	 *
81
	 * @param bool $reset
82
	 *
83
	 * @return bool|array
84
	 */
85
	public function getContext($reset = false)
86
	{
87
		global $txt, $context;
88
89
		// If the query returned false, bail.
90
		if (!is_object($this->_dbRequest) || $this->_dbRequest->hasResults() === false)
91
		{
92
			return false;
93
		}
94
95
		// Remember which message this is.  (ie. reply #83)
96
		if ($this->_counter === 0 || $reset)
97
		{
98
			$this->_counter = empty($context['start']) ? 0 : $context['start'];
99
		}
100
101
		// Start from the beginning, or get the next message
102
		$this->_currentContext($reset);
103
104
		if (empty($this->_this_message))
105
		{
106 4
			return false;
107
		}
108 4
109 4
		// If you're a lazy bum, you probably didn't give a subject...
110 4
		$this->_this_message['subject'] = $this->_this_message['subject'] !== '' ? $this->_this_message['subject'] : $txt['no_subject'];
111 4
112 4
		$this->_setupPermissions();
113 4
114
		$id_member = $this->_this_message[$this->_idx_mapper->id_member];
0 ignored issues
show
Bug Best Practice introduced by
The property id_member does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
115
		$member_context = MembersList::get($id_member);
116
		$member_context->loadContext();
117
118
		// If it couldn't load, or the user was a guest.... someday may be done with a guest table.
119
		if ($member_context->isEmpty())
120
		{
121
			$this->_adjustGuestContext($member_context);
122 4
		}
123 4
		else
124
		{
125
			$this->_adjustMemberContext($member_context);
126
		}
127
128
		$this->_adjustAllMembers($member_context);
129
130
		// Do the censor thang.
131
		$this->_this_message['subject'] = censor($this->_this_message['subject']);
132
133 2
		// Run BBC interpreter on the message.
134
		$this->_this_message['body'] = $this->_bodyParser->prepare($this->_this_message['body'], $this->_this_message['smileys_enabled']);
135 2
136 2
		call_integration_hook(static::BEFORE_PREPARE_HOOK, [&$this->_this_message]);
0 ignored issues
show
Bug introduced by
The constant ElkArte\MessagesCallback...er::BEFORE_PREPARE_HOOK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
137
138
		// Compose the memory eat- I mean message array.
139 2
		$output = $this->_buildOutputArray();
140
141
		call_integration_hook(static::CONTEXT_HOOK, [&$output, &$this->_this_message, $this->_counter]);
0 ignored issues
show
Bug introduced by
The constant ElkArte\MessagesCallback\Renderer::CONTEXT_HOOK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
142
143
		$output['classes'] = implode(' ', $output['classes']);
144
145 2
		$this->_counter++;
146
147
		return $output;
148
	}
149
150
	/**
151 2
	 * This function receives a request handle and attempts to retrieve the next result.
152
	 *
153
	 * What it does:
154
	 *
155
	 * - It is used by the controller callbacks from the template, such as
156
	 * posts in topic display page, posts search results page, or personal messages.
157
	 *
158 2
	 * @param bool $reset
159
	 *
160
	 * @return bool
161 2
	 */
162
	protected function _currentContext($reset = false)
163
	{
164
		// Start from the beginning...
165
		if ($reset)
166
		{
167 2
			$this->_dbRequest->data_seek(0);
168
		}
169 2
170
		// If the query has already returned false, get out of here
171 2
		if ($this->_dbRequest->hasResults() === false)
172 2
		{
173 2
			return false;
174
		}
175
176 2
		// Attempt to get the next message.
177
		$this->_this_message = $this->_dbRequest->fetch_assoc();
178 2
		if (!$this->_this_message)
179
		{
180
			$this->_dbRequest->free_result();
181
182
			return false;
183
		}
184 2
185
		return true;
186
	}
187 2
188
	/**
189
	 * Utility function, it shall be implemented by the extending class.
190 2
	 * Run just before \ElkArte\MembersList::get()->loadContext is executed.
191
	 */
192 2
	abstract protected function _setupPermissions();
193
194
	/**
195 2
	 * Utility function, it can be overridden to alter something just after the
196
	 * members' data has been loaded from the database.
197 2
	 * Run only if member exists failed.
198
	 *
199 2
	 * @param ValuesContainer $member_context
200
	 */
201 2
	protected function _adjustGuestContext($member_context)
202
	{
203 2
		global $txt;
204
205
		// Notice this information isn't used anywhere else....
206
		$member_context['name'] = $this->_this_message[$this->_idx_mapper->name];
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
207
		$member_context['id'] = 0;
208
		$member_context['group'] = $txt['guest_title'];
209
		$member_context['link'] = $this->_this_message[$this->_idx_mapper->name];
210
		$member_context['email'] = $this->_this_message['poster_email'] ?? '';
211
		$member_context['show_email'] = showEmailAddress(0);
212
		$member_context['is_guest'] = true;
213
	}
214
215
	/**
216
	 * Utility function, it can be overridden to alter something just after the
217
	 * members data have been set.
218 2
	 * Run only if member doesn't exist succeeded.
219
	 *
220
	 * @param ValuesContainer $member_context
221 2
	 */
222
	protected function _adjustMemberContext($member_context)
223
	{
224
		global $context, $modSettings;
225
226
		$member_id = $this->_this_message[$this->_idx_mapper->id_member];
0 ignored issues
show
Bug Best Practice introduced by
The property id_member does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
227 2
228
		$member_context['can_view_profile'] = allowedTo('profile_view_any') || ($member_id == $this->user->id && allowedTo('profile_view_own'));
229
		$member_context['is_topic_starter'] = $member_id == $context['topic_starter_id'];
230
		$member_context['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $member_context['warning_status'] && (!empty($context['user']['can_mod']) || ($this->user->is_guest === false && !empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $member_id == $this->user->id)));
231
232
		if ($this->_options->show_signatures === 1)
0 ignored issues
show
Bug Best Practice introduced by
The property show_signatures does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
233 2
		{
234 2
			if (empty($this->_signature_shown[$member_id]))
235
			{
236
				$this->_signature_shown[$member_id] = true;
237
			}
238
			else
239
			{
240
				$member_context['signature'] = '';
241 2
			}
242
		}
243
		elseif ($this->_options->show_signatures === 2)
244
		{
245
			$member_context['signature'] = '';
246
		}
247
	}
248
249
	/**
250
	 * Utility function, it can be overridden to alter something just after either
251
	 * the members or the guests data have been loaded from the database.
252
	 * Run both if the member exists or not.
253
	 *
254
	 * @param ValuesContainer $member_context
255
	 * @return mixed
256
	 */
257 2
	abstract protected function _adjustAllMembers($member_context);
258
259 2
	/**
260
	 * The most important bit that differentiate the various implementations.
261
	 * It is supposed to prepare the $output array with all the information
262 2
	 * needed by the template to properly render the message.
263 2
	 *
264 2
	 * The method of the class extending this abstract may run
265 2
	 * parent::_buildOutputArray()
266 2
	 * as first statement in order to have a starting point and
267 2
	 * some commonly used content for the array.
268 2
	 *
269 2
	 * @return array
270
	 */
271
	protected function _buildOutputArray()
272
	{
273
		return [
274
			'id' => $this->_this_message[$this->_idx_mapper->id_msg],
0 ignored issues
show
Bug Best Practice introduced by
The property id_msg does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
275
			'member' => MembersList::get($this->_this_message[$this->_idx_mapper->id_member]),
0 ignored issues
show
Bug Best Practice introduced by
The property id_member does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
276
			'subject' => $this->_this_message['subject'],
277
			'html_time' => htmlTime($this->_this_message[$this->_idx_mapper->time]),
0 ignored issues
show
Bug Best Practice introduced by
The property time does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
278
			'time' => standardTime($this->_this_message[$this->_idx_mapper->time]),
279
			'timestamp' => forum_time(true, $this->_this_message[$this->_idx_mapper->time]),
280
			'counter' => $this->_counter,
281
			'body' => $this->_this_message['body'],
282
			'can_see_ip' => allowedTo('moderate_forum') || ($this->_this_message[$this->_idx_mapper->id_member] == $this->user->id && !empty($this->user->id)),
283
			'classes' => []
284
		];
285
	}
286
}
287