CalendarEvent::insert()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 4
nop 2
dl 0
loc 11
ccs 0
cts 8
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * A class to handle the basics of calendar events.
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * This file contains code covered by:
11
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
12
 *
13
 * @version 2.0 dev
14
 *
15
 */
16
17
namespace ElkArte;
18
19
use ElkArte\Exceptions\Exception;
20
use ElkArte\Helper\Util;
21
22
/**
23
 * A class to handle the basics of calendar events.
24
 * Namely a certain kind of validation, inserting a new one, updating existing,
25
 * deleting, etc.
26
 */
27
class CalendarEvent
28
{
29
	/** @var null|int The id of the event. */
30
	protected $_event_id;
31
32
	/** @var array The general settings (in fact a copy of $modSettings). */
33
	protected $_settings = [];
34
35
	/**
36
	 * Construct the object requires the id of the event and the settings
37
	 *
38
	 * @param null|int $event_id Obviously the id of the event. If null or -1 the event is considered new
39
	 * @param array $settings An array of settings ($modSettings is the current one)
40
	 * @see CalendarEvent::isNew
41
	 */
42
	public function __construct($event_id, $settings = [])
43
	{
44
		$this->_settings = $settings;
45
		$this->_event_id = $event_id;
46
47
		// We need this for all kinds of useful functions.
48 36
		require_once(SUBSDIR . '/Calendar.subs.php');
49
	}
50 36
51 36
	/**
52
	 * Makes sure the calendar data are valid depending on settings
53
	 * and permissions.
54 36
	 *
55 36
	 * @param array $event The options may come from a form
56
	 *
57
	 * @return array
58
	 * @throws Exception
59
	 */
60
	public function validate($event): array
61
	{
62
		// Make sure they're allowed to post...
63
		isAllowedTo('calendar_post');
64
65
		if (isset($event['span']))
66 30
		{
67
			// Make sure it's turned on and not some fool trying to trick it.
68
			if (empty($this->_settings['cal_allowspan']))
69 30
			{
70
				throw new Exceptions\Exception('no_span', false);
71 30
			}
72
73
			if ($event['span'] < 1 || $event['span'] > $this->_settings['cal_maxspan'])
74 6
			{
75
				throw new Exceptions\Exception('invalid_days_numb', false);
76 2
			}
77
		}
78 4
79
		// There is no need to validate the following values if we are just deleting the event.
80 4
		if (!isset($event['deleteevent']))
81
		{
82
			// No month?  No year?
83
			if (!isset($event['month']))
84
			{
85
				throw new Exceptions\Exception('event_month_missing', false);
86 24
			}
87
88
			if (!isset($event['year']))
89 24
			{
90
				throw new Exceptions\Exception('event_year_missing', false);
91 2
			}
92
93 22
			// Check the month and year...
94
			$this->_settings['cal_limityear'] = empty($this->_settings['cal_limityear']) ? 20 : (int) $this->_settings['cal_limityear'];
95 2
96
			if ($event['month'] < 1 || $event['month'] > 12)
97
			{
98
				throw new Exceptions\Exception('invalid_month', false);
99 20
			}
100
101 6
			if ($event['year'] < $this->_settings['cal_minyear'] || $event['year'] > (int) date('Y') + $this->_settings['cal_limityear'])
102
			{
103 14
				throw new Exceptions\Exception('invalid_year', false);
104
			}
105 4
106
			// No day?
107
			if (!isset($event['day']))
108
			{
109 10
				throw new Exceptions\Exception('event_day_missing', false);
110
			}
111 2
112
			if (!isset($event['evtitle']) && !isset($event['subject']))
113
			{
114 8
				throw new Exceptions\Exception('event_title_missing', false);
115
			}
116 2
117
			if (!isset($event['evtitle']))
118 6
			{
119
				$event['evtitle'] = $event['subject'];
120 2
			}
121
122
			// Bad day?
123
			if (!checkdate($event['month'], $event['day'], $event['year']))
124 6
			{
125
				throw new Exceptions\Exception('invalid_date', false);
126 2
			}
127
128
			// No title?
129
			if (Util::htmltrim($event['evtitle']) === '')
130 4
			{
131
				throw new Exceptions\Exception('no_event_title', false);
132 2
			}
133
134 2
			if (Util::strlen($event['evtitle']) > 100)
135
			{
136 2
				$event['evtitle'] = Util::substr($event['evtitle'], 0, 100);
137
			}
138 2
139
			$event['evtitle'] = str_replace(';', '', $event['evtitle']);
140
		}
141 2
142
		return $event;
143
	}
144
145
	/**
146
	 * Does the save of an event.
147
	 *
148
	 * @param array $options - An array of options for the event.
149
	 * @param int $member_id - the id of the member saving the event.
150
	 */
151
	public function insert($options, $member_id): void
152
	{
153
		$eventOptions = [
154
			'id_board' => $options['id_board'] ?? 0,
155
			'id_topic' => $options['id_topic'] ?? 0,
156
			'title' => Util::substr($options['evtitle'], 0, 100),
157
			'member' => $member_id,
158
			'start_date' => sprintf('%04d-%02d-%02d', $options['year'], $options['month'], $options['day']),
159
			'span' => isset($options['span']) && $options['span'] > 0 ? min((int) $this->_settings['cal_maxspan'], (int) $options['span'] - 1) : 0,
160
		];
161
		insertEvent($eventOptions);
162
	}
163
164
	/**
165
	 * Deletes an event.
166
	 * No permission checks.
167 2
	 */
168
	public function remove(): void
169 2
	{
170
		removeEvent($this->_event_id);
171
	}
172
173
	/**
174
	 * Updates an existing event.
175
	 * Some options are validated to be sure the data inserted into the
176
	 * database are correct.
177
	 *
178
	 * @param array $options The options may come from a form
179
	 */
180
	public function update($options): void
181
	{
182
		// There could be already a topic you are not allowed to modify
183
		if (empty($this->_settings['disableNoPostingCalendarEdits']) && !allowedTo('post_new'))
184
		{
185
			$eventProperties = getEventProperties($this->_event_id, true);
186
		}
187
188
		$id_board = $eventProperties['id_board'] ?? (isset($options['id_board']) ? $options['board'] : 0);
189
		$id_topic = $eventProperties['id_topic'] ?? (isset($options['id_topic']) ? $options['topic'] : 0);
190
191
		if (empty($this->_settings['cal_allowspan']))
192
		{
193
			$span = 0;
194
		}
195
		elseif (empty($options['span']) || $options['span'] == 1)
196
		{
197
			$span = 0;
198
		}
199
		elseif (empty($this->_settings['cal_maxspan']) || $options['span'] > $this->_settings['cal_maxspan'])
200
		{
201
			$span = 0;
202
		}
203
		else
204
		{
205
			$span = min((int) $this->_settings['cal_maxspan'], (int) $options['span'] - 1);
206
		}
207
208
		$eventOptions = [
209
			'title' => Util::substr($options['evtitle'], 0, 100),
210
			'span' => $span,
211
			'start_date' => Util::strftime('%Y-%m-%d', mktime(0, 0, 0, (int) $options['month'], (int) $options['day'], (int) $options['year'])),
212
			'id_board' => (int) $id_board,
213
			'id_topic' => (int) $id_topic,
214
		];
215
216
		modifyEvent($this->_event_id, $eventOptions);
217
	}
218
219
	/**
220
	 * Loads up the data of an event for the template.
221
	 * If new the default values are loaded.
222
	 *
223
	 * @param array $options The options may come from a form. Used to set
224
	 *              some of the defaults in case of new events.
225
	 * @param int $member_id - the id of the member saving the event
226
	 *
227
	 * @return array The event structure.
228
	 * @throws Exception no_access
229
	 */
230
	public function load($options, $member_id): array
231
	{
232
		global $topic;
233
234
		// New?
235
		if ($this->isNew())
236
		{
237
			$today = getdate();
238
239
			$event = [
240
				'boards' => [],
241
				'board' => 0,
242
				'new' => 1,
243
				'eventid' => -1,
244
				'year' => $options['year'] ?? $today['year'],
245
				'month' => $options['month'] ?? $today['mon'],
246
				'day' => $options['day'] ?? $today['mday'],
247
				'title' => '',
248
				'span' => 1,
249
			];
250
			$event['last_day'] = (int) Util::strftime('%d', mktime(0, 0, 0, $event['month'] == 12 ? 1 : $event['month'] + 1, 0, $event['month'] == 12 ? $event['year'] + 1 : $event['year']));
251
		}
252
		else
253
		{
254
			// Reload the event after making changes
255
			$event = getEventProperties($this->_event_id);
256
257
			if ($event === false)
0 ignored issues
show
introduced by
The condition $event === false is always false.
Loading history...
258
			{
259
				throw new Exceptions\Exception('no_access', false);
260
			}
261
262
			// If it has a board, then they should be editing it within the topic.
263
			if (!empty($event['topic']['id']) && !empty($event['topic']['first_msg']))
264
			{
265
				// We load the board up, for a check on the board access rights...
266
				$topic = $event['topic']['id'];
267
				loadBoard();
268
			}
269
270
			// Make sure the user is allowed to edit this event.
271
			if ($event['member'] != $member_id)
272
			{
273
				isAllowedTo('calendar_edit_any');
274
			}
275
			elseif (!allowedTo('calendar_edit_any'))
276
			{
277
				isAllowedTo('calendar_edit_own');
278
			}
279
		}
280
281
		return $event;
282
	}
283
284
	/**
285
	 * Determines if the current calendar event is new or not.
286
	 *
287
	 * @return bool
288 2
	 */
289
	public function isNew(): bool
290 2
	{
291
		return $this->_event_id === null || $this->_event_id === -1;
292
	}
293
294
	/**
295
	 * Determines if the passed member is the one that originally posted the event.
296
	 *
297
	 * @param int $member_id
298
	 * @return bool
299 2
	 */
300
	public function isStarter($member_id): bool
301 2
	{
302
		return !empty($member_id) && getEventPoster($this->_event_id) == $member_id;
303
	}
304
}
305