builder   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 355
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
eloc 104
c 5
b 1
f 0
dl 0
loc 355
ccs 0
cts 177
cp 0
rs 9.2
wmc 40

17 Methods

Rating   Name   Duplication   Size   Complexity  
A set_field_values() 0 9 3
A __construct() 0 13 1
A get_form() 0 3 1
A get_fields_data_from_post() 0 11 2
A force_state() 0 3 2
A add_field() 0 9 4
A generate_preview() 0 5 1
A generate_message() 0 12 3
A generate_form() 0 11 3
A get_redirect_url() 0 3 1
A get_moderator_options() 0 17 2
A modify_sql_data() 0 5 1
A init() 0 39 6
A save_db_fields() 0 3 1
A get_content_view() 0 19 3
A force_visibility() 0 12 5
A get_errors() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like builder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use builder, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * @package sitemaker
5
 * @copyright (c) 2016 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\content\services\form;
11
12
use Cocur\Slugify\Slugify;
13
14
class builder
15
{
16
	/** @var \phpbb\auth\auth */
17
	protected $auth;
18
19
	/** @var \phpbb\event\dispatcher_interface */
20
	protected $phpbb_dispatcher;
21
22
	/** @var \phpbb\language\language */
23
	protected $language;
24
25
	/** @var \phpbb\request\request_interface */
26
	protected $request;
27
28
	/** @var \phpbb\template\context */
29
	protected $template_context;
30
31
	/** @var \phpbb\user */
32
	protected $user;
33
34
	/* @var \blitze\content\services\fields */
35
	protected $fields;
36
37
	/* @var \blitze\content\services\types */
38
	protected $types;
39
40
	/** @var \blitze\content\services\form\form */
41
	protected $form;
42
43
	/** @var string */
44
	protected $phpbb_root_path;
45
46
	/** @var string */
47
	protected $php_ext;
48
49
	/** @var string */
50
	protected $mode = '';
51
52
	/** @var int */
53
	protected $topic_time = 0;
54
55
	/** @var bool */
56
	protected $req_approval = false;
57
58
	/** @var bool */
59
	protected $req_mod_input = false;
60
61
	/** @var bool */
62
	protected $user_is_mod = false;
63
64
	/** @var array */
65
	protected $content_fields = array();
66
67
	/**
68
	 * Constructor
69
	 *
70
	 * @param \phpbb\auth\auth							$auth				Auth object
71
	 * @param \phpbb\event\dispatcher_interface			$phpbb_dispatcher	Event dispatcher object
72
	 * @param \phpbb\language\language					$language			Language object
73
	 * @param \phpbb\request\request_interface			$request			Request object
74
	 * @param \phpbb\template\context					$template_context	Template context object
75
	 * @param \phpbb\user								$user				User object
76
	 * @param \blitze\content\services\fields			$fields				Content fields object
77
	 * @param \blitze\content\services\types			$types				Content types object
78
	 * @param \blitze\content\services\form\form		$form				Form object
79
	 * @param string									$phpbb_root_path	Path to the phpbb includes directory.
80
	 * @param string									$php_ext			php file extension
81
	 */
82
	public function __construct(\phpbb\auth\auth $auth, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\language\language $language, \phpbb\request\request_interface $request, \phpbb\template\context $template_context, \phpbb\user $user, \blitze\content\services\fields $fields, \blitze\content\services\types $types, \blitze\content\services\form\form $form, $phpbb_root_path, $php_ext)
83
	{
84
		$this->auth = $auth;
85
		$this->phpbb_dispatcher = $phpbb_dispatcher;
86
		$this->language = $language;
87
		$this->request = $request;
88
		$this->template_context = $template_context;
89
		$this->user = $user;
90
		$this->fields = $fields;
91
		$this->types = $types;
92
		$this->form = $form;
93
		$this->phpbb_root_path = $phpbb_root_path;
94
		$this->php_ext = $php_ext;
95
	}
96
97
	/**
98
	 * @param int $forum_id
99
	 * @param int $topic_id
100
	 * @param string $mode
101
	 * @param bool $save_draft
102
	 * @return array
103
	 */
104
	public function init($forum_id, $topic_id, $mode, $save_draft)
105
	{
106
		$content_langname = '';
107
		if ($type = $this->types->get_forum_type($forum_id))
108
		{
109
			$this->language->add_lang('posting', 'blitze/content');
110
111
			/** @var \blitze\content\model\entity\type $entity */
112
			$entity = $this->types->get_type($type, true);
113
			$content_langname = $entity->get_content_langname();
114
			$fields_data = $entity->get_content_fields();
115
116
			/**
117
			 * Event to set the values for fields that are stored in the database, for purposes of displaying the form field
118
			 *
119
			 * @event blitze.content.builder.set_field_values
120
			 * @var int									topic_id		Current topic id
121
			 * @var array								fields_data		Array containing fields data, minus 'field_value' prop, which is what we are setting here
122
			 * @var \blitze\content\model\entity\type	entity			Content type entity
123
			 */
124
			$vars = array('topic_id', 'fields_data', 'entity');
125
			extract($this->phpbb_dispatcher->trigger_event('blitze.content.builder.set_field_values', compact($vars)));
126
127
			$this->content_fields = $fields_data;
128
			$this->user_is_mod = $this->auth->acl_get('m_', $entity->get_forum_id());
129
			$this->req_approval = $entity->get_req_approval();
130
			$this->mode = $this->request->variable('cp', ($this->user_is_mod && $mode !== 'post') ? 'mcp' : 'ucp');
131
132
			$this->form->create('postform', 'posting')
133
				->add('cp', 'hidden', array('field_value' => $this->mode))
134
				->add('redirect', 'hidden', array('field_value' => $this->get_redirect_url()));
135
136
			if ($save_draft && !$this->request->is_set('message'))
137
			{
138
				$this->request->overwrite('message', $this->generate_message());
139
			}
140
		}
141
142
		return array($type, $content_langname);
143
	}
144
145
	/**
146
	 * @return string
147
	 */
148
	public function generate_message()
149
	{
150
		$fields_data = $this->form->get_submitted_data($this->content_fields, $this->req_mod_input, $this->mode);
151
152
		$message = '';
153
		foreach ($fields_data as $field => $value)
154
		{
155
			$value = is_array($value) ? join("\n", $value) : $value;
156
			$message .= '[smcf=' . $field . ']' . $value . '[/smcf]';
157
		}
158
159
		return $message;
160
	}
161
162
	/**
163
	 * @return array
164
	 */
165
	public function get_errors()
166
	{
167
		return $this->form->get_errors();
168
	}
169
170
	/**
171
	 * @return string
172
	 */
173
	public function get_redirect_url()
174
	{
175
		return $this->request->variable('redirect', '');
176
	}
177
178
	/**
179
	 * @param string $content_type
180
	 * @param array $post_data
181
	 * @param string $view
182
	 * @return string
183
	 */
184
	public function get_content_view($content_type, array $post_data, $view)
185
	{
186
		$text = '';
187
		if ($entity = $this->types->get_type($content_type))
188
		{
189
			$fields_accessor = 'get_' . $view . '_fields';
190
			$template_accessor = 'get_' . $view . '_tpl';
191
192
			// we do this to ensure topic_id keys exists when previewing a new topic
193
			$post_data += array('topic_id' => 0);
194
195
			$this->fields->prepare_to_show($entity, array($post_data['topic_id']), $entity->$fields_accessor(), $entity->$template_accessor(), $view);
196
			$this->fields->set_view_mode('preview');
197
198
			$content = $this->fields->build_content(array_change_key_case($post_data, CASE_UPPER));
199
200
			$text =  isset($content['CUSTOM_DISPLAY']) ? $content['CUSTOM_DISPLAY'] : join('', $content['FIELDS']['all']);
201
		}
202
		return $text;
203
	}
204
205
	/**
206
	 * @param string $content_type
207
	 * @param array $post_data
208
	 * @return string
209
	 */
210
	public function generate_preview($content_type, array $post_data)
211
	{
212
		$post_data['MESSAGE'] = $this->template_context->get_root_ref()['PREVIEW_MESSAGE'];
213
214
		return $this->get_content_view($content_type, $post_data, 'detail');
215
	}
216
217
	/**
218
	 * @param array $sql_data
219
	 * @return void
220
	 */
221
	public function modify_sql_data(array &$sql_data)
222
	{
223
		$slugify = new Slugify();
224
		$sql_data['topic_slug'] = $slugify->slugify($sql_data['topic_title']);
225
		$sql_data['req_mod_input'] = $this->req_mod_input;
226
	}
227
228
	/**
229
	 * @param array $topic_data
230
	 * @return void
231
	 */
232
	public function save_db_fields(array $topic_data)
233
	{
234
		$this->form->save_db_fields($topic_data, $this->content_fields);
235
	}
236
237
	/**
238
	 * @param int $topic_id
239
	 * @param array $post_data
240
	 * @param array $page_data
241
	 * @return void
242
	 */
243
	public function generate_form($topic_id, array $post_data, array $page_data = array())
244
	{
245
		$this->set_field_values($post_data['post_text']);
246
247
		foreach ($this->content_fields as $field => $field_data)
248
		{
249
			if ($field_data['field_type'] === 'textarea')
250
			{
251
				$field_data += $page_data;
252
			}
253
			$this->add_field($field, $field_data, $topic_id);
254
		}
255
	}
256
257
	/**
258
	 * @return string
259
	 */
260
	public function get_form()
261
	{
262
		return $this->form->get_form(false);
263
	}
264
265
	/**
266
	 * @param string $field
267
	 * @param array $field_data
268
	 * @param int $topic_id
269
	 * @return void
270
	 */
271
	protected function add_field($field, array $field_data, $topic_id)
272
	{
273
		if (!$field_data['field_mod_only'] || $this->mode === 'mcp')
274
		{
275
			$this->form->add($field, $field_data['field_type'], $field_data, $topic_id);
276
		}
277
		else if (!empty($field_data['field_value']))
278
		{
279
			$this->form->add($field, 'hidden', $field_data, $topic_id);
280
		}
281
	}
282
283
	/**
284
	 * @param string $mode
285
	 * @param array $data
286
	 * @return void
287
	 */
288
	public function force_visibility($mode, array &$data)
289
	{
290
		if ($this->mode === 'mcp')
291
		{
292
			if ('-1' !== $visibility = $this->request->variable('force_status', ''))
293
			{
294
				$data['force_visibility'] = $visibility;
295
			}
296
		}
297
		else if ($this->force_state())
298
		{
299
			$data['force_visibility'] = ($mode == 'edit_first_post') ? ITEM_REAPPROVE : ITEM_UNAPPROVED;
300
		}
301
	}
302
303
	/**
304
	 * @return bool
305
	 */
306
	protected function force_state()
307
	{
308
		return ($this->req_approval || $this->req_mod_input);
309
	}
310
311
	/**
312
	 * @param string $post_text
313
	 * @return void
314
	 */
315
	protected function set_field_values($post_text)
316
	{
317
		$fields_data = $this->get_fields_data_from_post($post_text, array_keys($this->content_fields));
318
319
		foreach ($fields_data as $field => $value)
320
		{
321
			if (isset($this->content_fields[$field]))
322
			{
323
				$this->content_fields[$field]['field_value'] = $value;
324
			}
325
		}
326
	}
327
328
	/**
329
	 * Get fields data from post
330
	 *
331
	 * @param string $post_text
332
	 * @param array $fields
333
	 * @return array
334
	 */
335
	protected function get_fields_data_from_post($post_text, array $fields)
336
	{
337
		$fields_data = array();
338
		$find_fields = join('|', $fields);
339
340
		if (preg_match_all("/\[smcf=($find_fields)\](.*?)\[\/smcf]/s", $post_text, $matches))
341
		{
342
			$fields_data = array_combine($matches[1], $matches[2]);
343
		}
344
345
		return $fields_data;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $fields_data could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
346
	}
347
348
	/**
349
	 * @param int $visibility
350
	 * @return array
351
	 */
352
	protected function get_moderator_options($visibility)
353
	{
354
		$options = array(
355
			'-1' => 'NO',
356
		);
357
358
		if ($visibility == ITEM_APPROVED)
359
		{
360
			$options[ITEM_REAPPROVE] = 'CONTENT_STATUS_REAPPROVE';
361
		}
362
		else
363
		{
364
			$options[ITEM_UNAPPROVED]	= 'CONTENT_STATUS_DISAPPROVE';
365
			$options[ITEM_APPROVED]		= 'CONTENT_STATUS_APPROVE';
366
		}
367
368
		return $options;
369
	}
370
}
371