Completed
Pull Request — master (#3325)
by Emanuele
11:19
created

Drafts_PersonalMessage_Module::_loadDraft()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
dl 0
loc 14
rs 10
c 0
b 0
f 0
nc 2
nop 2
ccs 0
cts 9
cp 0
crap 12
1
<?php
2
3
/**
4
 * Integration system for drafts into PersonalMessage controller
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * This file contains code covered by:
11
 * copyright:    2011 Simple Machines (http://www.simplemachines.org)
12
 * license:    BSD, See included LICENSE.TXT for terms and conditions.
13
 *
14
 * @version 1.1
15
 *
16
 */
17
18
/**
19
 * Class Drafts_PersonalMessage_Module
20
 *
21
 * Prepares the draft functions for the personal message page
22
 */
23
class Drafts_PersonalMessage_Module extends ElkArte\sources\modules\Abstract_Module
24
{
25
	/**
26
	 * Autosave enabled
27
	 * @var bool
28
	 */
29
	protected static $_autosave_enabled = false;
30
31
	/**
32
	 * How often to autosave if enabled
33
	 * @var int
34
	 */
35
	protected static $_autosave_frequency = 30000;
36
37
	/**
38
	 * Subject length
39
	 * @var int
40
	 */
41
	protected static $_subject_length = 24;
42
43
	/**
44
	 * @var Event_Manager
45
	 */
46
	protected static $_eventsManager = null;
47
48
	/**
49
	 * @var \ElkArte\ValuesContainer
50
	 */
51
	protected $_loaded_draft;
52
53
	/**
54
	 * Add PM draft hooks and events to the system
55
	 *
56
	 * {@inheritdoc}
57
	 */
58
	public static function hooks(\Event_Manager $eventsManager)
59
	{
60
		global $modSettings, $context;
61
62
		loadLanguage('Drafts');
63
		require_once(SUBSDIR . '/Drafts.subs.php');
64
65
		// Are PM drafts enabled?
66
		$context['drafts_pm_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_pm_enabled']) && allowedTo('pm_draft');
67
		$context['drafts_autosave'] = !empty($context['drafts_pm_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('pm_autosave_draft');
68
69
		if (!empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']))
70
		{
71
			self::$_eventsManager = $eventsManager;
72
			self::$_autosave_enabled = !empty($modSettings['drafts_autosave_enabled']);
73
74
			add_integration_function('integrate_sa_pm_index', 'Drafts_PersonalMessage_Module::integrate_sa_pm_index', '', false);
75
			add_integration_function('integrate_pm_areas', 'Drafts_PersonalMessage_Module::integrate_pm_areas', '', false);
76
77
			if (!empty($modSettings['drafts_autosave_frequency']))
78
			{
79
				self::$_autosave_frequency = (int) $modSettings['drafts_autosave_frequency'] * 1000;
80
			}
81
82
			if (!empty($modSettings['draft_subject_length']))
83
			{
84
				self::$_subject_length = (int) $modSettings['draft_subject_length'];
85
			}
86
87
			// Events
88
			return array(
89
				array('before_set_context', array('Drafts_PersonalMessage_Module', 'before_set_context'), array()),
90
				array('prepare_send_context', array('Drafts_PersonalMessage_Module', 'prepare_send_context'), array('editorOptions', 'recipientList')),
91
				array('before_sending', array('Drafts_PersonalMessage_Module', 'before_sending'), array('recipientList')),
92
			);
93
		}
94
		else
95
		{
96
			return array();
97
		}
98
	}
99
100
	/**
101
	 * Insert the show drafts button in the PM menu
102
	 *
103
	 * @param array $pm_areas
104
	 */
105
	public static function integrate_pm_areas(&$pm_areas)
106
	{
107
		global $scripturl, $txt;
108
109
		$pm_areas['folders']['areas'] = elk_array_insert($pm_areas['folders']['areas'], 'sent', array(
110
			'drafts' => array(
111
				'label' => $txt['drafts_show'],
112
				'custom_url' => $scripturl . '?action=pm;sa=showpmdrafts',
113
				'permission' => 'pm_draft',
114
				'enabled' => true,
115
			)), 'after');
116
	}
117
118
	/**
119
	 * Add the draft controller show drafts to the available subactions
120
	 *
121
	 * @param array $subActions
122
	 */
123
	public static function integrate_sa_pm_index(&$subActions)
124
	{
125
		$subActions['showpmdrafts'] = array(
126
			'controller' => 'Draft_Controller',
127
			'function' => 'action_showPMDrafts',
128
			'permission' => 'pm_read'
129
		);
130
	}
131
132
	/**
133
	 * Displays a list of available drafts or selects a draft for adding to the editor
134
	 *
135
	 * @param int $pmsg
136
	 *
137
	 * @throws Pm_Error_Exception
138
	 */
139
	public function before_set_context($pmsg)
140
	{
141
		global $context, $user_info;
142
143
		// If drafts are enabled, lets generate a list of drafts that they can load in to the editor
144
		if (!empty($context['drafts_pm_save']))
145
		{
146
			// Has a specific draft has been selected?  Load it up if there is not already a message already in the editor
147
			if (isset($_REQUEST['id_draft']) && empty($_POST['subject']) && empty($_POST['message']))
148
			{
149
				$this->_loadDraft($user_info['id'], (int) $_REQUEST['id_draft']);
150
				throw new Pm_Error_Exception($this->_loaded_draft->to_list, $this->_loaded_draft);
1 ignored issue
show
Bug Best Practice introduced by
The property to_list does not exist on ElkArte\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
151
			}
152
			else
153
			{
154
				$this->_prepareDraftsContext($user_info['id'], $pmsg);
155
			}
156
		}
157
	}
158
159
	/**
160
	 * Loads in a group of PM drafts for the user.
161
	 *
162
	 * What it does:
163
	 *
164
	 * - Loads a specific draft for current use in pm editing box if selected.
165
	 * - Used in the posting screens to allow draft selection
166
	 * - Will load a draft if selected is supplied via post
167
	 *
168
	 * @param int $member_id
169
	 * @param int $id_draft The draft id
170
	 *
171
	 * @return false|null
172
	 */
173
	protected function _loadDraft($member_id, $id_draft)
174
	{
175
		// Need a member
176
		if (empty($member_id) || empty($id_draft))
177
		{
178
			return false;
179
		}
180
181
		// We haz drafts
182
		loadLanguage('Drafts');
183
		require_once(SUBSDIR . '/Drafts.subs.php');
184
185
		// Load the draft and add it to a object container
186
		$this->_loaded_draft = new \ElkArte\ValuesContainer(loadDraft($id_draft, 1, true, true));
0 ignored issues
show
Bug introduced by
It seems like loadDraft($id_draft, 1, true, true) can also be of type false; however, parameter $data of ElkArte\ValuesContainer::__construct() does only seem to accept array<mixed,mixed>|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

186
		$this->_loaded_draft = new \ElkArte\ValuesContainer(/** @scrutinizer ignore-type */ loadDraft($id_draft, 1, true, true));
Loading history...
187
	}
188
189
	/**
190
	 * Loads in a group of PM drafts for the user.
191
	 *
192
	 * What it does:
193
	 *
194
	 * - Loads a specific draft for current use in pm editing box if selected.
195
	 * - Used in the posting screens to allow draft selection
196
	 * - Will load a draft if selected is supplied via post
197
	 *
198
	 * @param int $member_id
199
	 * @param int|bool $id_pm = false if set, it will try to load drafts for this id
200
	 *
201
	 * @return bool
202
	 */
203
	protected function _prepareDraftsContext($member_id, $id_pm = false)
204
	{
205
		global $scripturl, $context, $txt;
206
207
		$context['drafts'] = array();
208
209
		// Need a member
210
		if (empty($member_id))
211
		{
212
			return false;
213
		}
214
215
		// We haz drafts
216
		loadLanguage('Drafts');
217
		require_once(SUBSDIR . '/Drafts.subs.php');
218
219
		// Load all the drafts for this user that meet the criteria
220
		$order = 'poster_time DESC';
221
		$user_drafts = load_user_drafts($member_id, 1, $id_pm, $order);
222
223
		// Add them to the context draft array for template display
224
		foreach ($user_drafts as $draft)
225
		{
226
			$short_subject = empty($draft['subject'])
227
				? $txt['drafts_none']
228
				: Util::shorten_text(stripslashes($draft['subject']), self::$_subject_length);
229
			$context['drafts'][] = array(
230
				'subject' => censor($short_subject),
231
				'poster_time' => standardTime($draft['poster_time']),
232
				'link' => '<a href="' . $scripturl . '?action=pm;sa=send;id_draft=' . $draft['id_draft'] . '">' . (!empty($draft['subject'])
233
						? $draft['subject']
234
						: $txt['drafts_none']) . '</a>',
235
			);
236
		}
237
238
		return true;
239
	}
240
241
	/**
242
	 * Activates the draft plugin for use in the editor
243
	 *
244
	 * @param array $editorOptions
245
	 */
246
	public function prepare_send_context(&$editorOptions)
247
	{
248
		global $context, $options, $txt;
249
250
		// PM drafts enabled, then we need to tell the editor before it initialises
251
		if (!empty($context['drafts_pm_save']) && !empty($options['drafts_autosave_enabled']))
252
		{
253
			if (!isset($editorOptions['plugin_addons']))
254
			{
255
				$editorOptions['plugin_addons'] = array();
256
			}
257
258
			if (!isset($editorOptions['plugin_options']))
259
			{
260
				$editorOptions['plugin_options'] = array();
261
			}
262
263
			// @todo remove
264
			$context['drafts_autosave_frequency'] = self::$_autosave_frequency;
265
266
			$editorOptions['plugin_addons'][] = 'draft';
267
			$editorOptions['plugin_options'][] = '
268
				draftOptions: {
269
					sLastNote: \'draft_lastautosave\',
270
					sSceditorID: \'' . $editorOptions['id'] . '\',
271
					sType: \'post\',
272
					iBoard: 0,
273
					iFreq: ' . self::$_autosave_frequency . ',
274
					sLastID: \'id_pm_draft\',
275
					sTextareaID: \'' . $editorOptions['id'] . '\',
276
					bPM: true
277
				}';
278
279
			loadJavascriptFile('drafts.plugin.js', array('defer' => true));
280
			loadLanguage('Post');
281
282
			// Our not so concise shortcut line
283
			if (!isset($context['shortcuts_text']))
284
			{
285
				$context['shortcuts_text'] = $txt['shortcuts_drafts' . (isBrowser('is_firefox') ? '_firefox' : '')];
286
			}
287
288
			if (!isset($editorOptions['buttons']))
289
			{
290
				$editorOptions['buttons'] = array();
291
			}
292
293
			if (!isset($editorOptions['hidden_fields']))
294
			{
295
				$editorOptions['hidden_fields'] = array();
296
			}
297
298
			$editorOptions['buttons'][] = array(
299
				'name' => 'save_draft',
300
				'value' => $txt['draft_save'],
301
				'options' => 'onclick="submitThisOnce(this);" accesskey="d"',
302
			);
303
304
			$editorOptions['hidden_fields'][] = array(
305
				'name' => 'id_pm_draft',
306
				'value' => empty($context['id_pm_draft']) ? 0 : $context['id_pm_draft'],
307
			);
308
		}
309
	}
310
311
	/**
312
	 * Saves a draft, either in reaction to autosave or pressing of save draft button
313
	 *
314
	 * @param array $recipientList
315
	 *
316
	 * @throws Controller_Redirect_Exception
317
	 * @throws Elk_Exception
318
	 */
319
	public function before_sending($recipientList)
320
	{
321
		global $context, $user_info, $modSettings;
322
323
		// Ajax calling
324
		if (!isset($context['drafts_pm_save']))
325
		{
326
			$context['drafts_pm_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_pm_enabled']) && allowedTo('pm_draft');
327
		}
328
329
		// Want to save this as a draft and think about it some more?
330
		if ($context['drafts_pm_save'] && isset($_POST['save_draft']))
331
		{
332
			// PM survey says ... can you stay or must you go
333
			if (!empty($context['drafts_pm_save']) && isset($_POST['id_pm_draft']))
334
			{
335
				// Prepare the data
336
				$draft = array(
337
					'id_pm_draft' => empty($_POST['id_pm_draft']) ? 0 : (int) $_POST['id_pm_draft'],
338
					'reply_id' => empty($_POST['replied_to']) ? 0 : (int) $_POST['replied_to'],
339
					'body' => Util::htmlspecialchars($_POST['message'], ENT_QUOTES, 'UTF-8', true),
340
					'subject' => strtr(Util::htmlspecialchars($_POST['subject']), array("\r" => '', "\n" => '', "\t" => '')),
341
					'id_member' => $user_info['id'],
342
					'is_usersaved' => (int) empty($_REQUEST['autosave']),
343
				);
344
345
				if (isset($_REQUEST['xml']))
346
				{
347
					$recipientList['to'] = isset($_POST['recipient_to']) ? explode(',', $_POST['recipient_to']) : array();
348
					$recipientList['bcc'] = isset($_POST['recipient_bcc']) ? explode(',', $_POST['recipient_bcc']) : array();
349
				}
350
351
				// Trigger any before_savepm_draft events
352
				self::$_eventsManager->trigger('before_savepm_draft', array('draft' => &$draft, 'recipientList' => &$recipientList));
353
354
				// Now save the draft
355
				savePMDraft($recipientList, $draft, isset($_REQUEST['xml']));
356
				throw new Controller_Redirect_Exception('', '');
357
			}
358
		}
359
	}
360
361
	/**
362
	 * If it sent, then remove the draft from the system
363
	 *
364
	 * @param $failed
365
	 */
366
	public function message_sent($failed)
367
	{
368
		global $context, $user_info;
369
370
		// If we had a PM draft for this one, then its time to remove it since it was just sent
371
		if (!$failed && $context['drafts_pm_save'] && !empty($_POST['id_pm_draft']))
372
		{
373
			deleteDrafts((int) $_POST['id_pm_draft'], $user_info['id']);
374
		}
375
	}
376
}
377