GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 78be4d...e155c6 )
by gyeong-won
15:27
created

documentController::moveDocumentToTrash()   C

Complexity

Conditions 12
Paths 90

Size

Total Lines 110
Code Lines 56

Duplication

Lines 21
Ratio 19.09 %
Metric Value
dl 21
loc 110
rs 5.034
cc 12
eloc 56
nc 90
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) NAVER <http://www.navercorp.com> */
3
/**
4
 * documentController class
5
 * document the module's controller class
6
 *
7
 * @author NAVER ([email protected])
8
 * @package /modules/document
9
 * @version 0.1
10
 */
11
class documentController extends document
12
{
13
	/**
14
	 * Initialization
15
	 * @return void
16
	 */
17
	function init()
18
	{
19
	}
20
21
	/**
22
	 * Action to handle vote-up of the post (Up)
23
	 * @return Object
24
	 */
25 View Code Duplication
	function procDocumentVoteUp()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
26
	{
27
		if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request');
28
29
		$document_srl = Context::get('target_srl');
30
		if(!$document_srl) return new Object(-1, 'msg_invalid_request');
31
32
		$oDocumentModel = getModel('document');
33
		$oDocument = $oDocumentModel->getDocument($document_srl, false, false);
34
		$module_srl = $oDocument->get('module_srl');
35
		if(!$module_srl) return new Object(-1, 'msg_invalid_request');
36
37
		$oModuleModel = getModel('module');
38
		$document_config = $oModuleModel->getModulePartConfig('document',$module_srl);
39
		if($document_config->use_vote_up=='N') return new Object(-1, 'msg_invalid_request');
40
41
		$point = 1;
42
		$output = $this->updateVotedCount($document_srl, $point);
43
		$this->add('voted_count', $output->get('voted_count'));
44
		return $output;
45
	}
46
47
	/**
48
	 * insert alias
49
	 * @param int $module_srl
50
	 * @param int $document_srl
51
	 * @param string $alias_title
52
	 * @return object
53
	 */
54
	function insertAlias($module_srl, $document_srl, $alias_title)
55
	{
56
		$args = new stdClass;
57
		$args->alias_srl = getNextSequence();
58
		$args->module_srl = $module_srl;
59
		$args->document_srl = $document_srl;
60
		$args->alias_title = urldecode($alias_title);
61
		$query = "document.insertAlias";
62
		$output = executeQuery($query, $args);
63
		return $output;
64
	}
65
66
	/**
67
	 * Action to handle vote-up of the post (Down)
68
	 * @return Object
69
	 */
70 View Code Duplication
	function procDocumentVoteDown()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
	{
72
		if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request');
73
74
		$document_srl = Context::get('target_srl');
75
		if(!$document_srl) return new Object(-1, 'msg_invalid_request');
76
77
		$oDocumentModel = getModel('document');
78
		$oDocument = $oDocumentModel->getDocument($document_srl, false, false);
79
		$module_srl = $oDocument->get('module_srl');
80
		if(!$module_srl) return new Object(-1, 'msg_invalid_request');
81
82
		$oModuleModel = getModel('module');
83
		$document_config = $oModuleModel->getModulePartConfig('document',$module_srl);
84
		if($document_config->use_vote_down=='N') return new Object(-1, 'msg_invalid_request');
85
86
		$point = -1;
87
		$output = $this->updateVotedCount($document_srl, $point);
88
		$this->add('blamed_count', $output->get('blamed_count'));
89
		return $output;
90
	}
91
92
	/**
93
	 * Action called when the post is reported by other member
94
	 * @return void|Object
95
	 */
96 View Code Duplication
	function procDocumentDeclare()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
	{
98
		if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request');
99
100
		$document_srl = Context::get('target_srl');
101
		if(!$document_srl) return new Object(-1, 'msg_invalid_request');
102
103
		return $this->declaredDocument($document_srl);
104
	}
105
106
	/**
107
	 * Delete alias when module deleted
108
	 * @param int $module_srl
109
	 * @return void
110
	 */
111
	function deleteDocumentAliasByModule($module_srl)
112
	{
113
		$args = new stdClass();
114
		$args->module_srl = $module_srl;
115
		executeQuery("document.deleteAlias", $args);
116
	}
117
118
	/**
119
	 * Delete alias when document deleted
120
	 * @param int $document_srl
121
	 * @return void
122
	 */
123
	function deleteDocumentAliasByDocument($document_srl)
124
	{
125
		$args = new stdClass();
126
		$args->document_srl = $document_srl;
127
		executeQuery("document.deleteAlias", $args);
128
	}
129
130
	/**
131
	 * Delete document history
132
	 * @param int $history_srl
133
	 * @param int $document_srl
134
	 * @param int $module_srl
135
	 * @return void
136
	 */
137
	function deleteDocumentHistory($history_srl, $document_srl, $module_srl)
138
	{
139
		$args = new stdClass();
140
		$args->history_srl = $history_srl;
141
		$args->module_srl = $module_srl;
142
		$args->document_srl = $document_srl;
143
		if(!$args->history_srl && !$args->module_srl && !$args->document_srl) return;
144
		executeQuery("document.deleteHistory", $args);
145
	}
146
147
	/**
148
	 * A trigger to delete all posts together when the module is deleted
149
	 * @param object $obj
150
	 * @return Object
151
	 */
152
	function triggerDeleteModuleDocuments(&$obj)
153
	{
154
		$module_srl = $obj->module_srl;
155
		if(!$module_srl) return new Object();
156
		// Delete the document
157
		$oDocumentAdminController = getAdminController('document');
158
		$output = $oDocumentAdminController->deleteModuleDocument($module_srl);
159
		if(!$output->toBool()) return $output;
160
		// Delete the category
161
		$oDocumentController = getController('document');
162
		$output = $oDocumentController->deleteModuleCategory($module_srl);
163
		if(!$output->toBool()) return $output;
164
		// Delete extra key and variable, because module deleted
165
		$this->deleteDocumentExtraKeys($module_srl);
166
167
		// remove aliases
168
		$this->deleteDocumentAliasByModule($module_srl);
169
170
		// remove histories
171
		$this->deleteDocumentHistory(null, null, $module_srl);
172
173
		return new Object();
174
	}
175
176
	/**
177
	 * Grant a permisstion of the document
178
	 * Available in the current connection with session value
179
	 * @param int $document_srl
180
	 * @return void
181
	 */
182
	function addGrant($document_srl)
183
	{
184
		$_SESSION['own_document'][$document_srl] = true;
185
	}
186
187
	/**
188
	 * Insert the document
189
	 * @param object $obj
190
	 * @param bool $manual_inserted
191
	 * @param bool $isRestore
192
	 * @return object
193
	 */
194
	function insertDocument($obj, $manual_inserted = false, $isRestore = false, $isLatest = true)
195
	{
196
		if(!$manual_inserted && !checkCSRF())
197
		{
198
			return new Object(-1, 'msg_invalid_request');
199
		}
200
201
		// begin transaction
202
		$oDB = &DB::getInstance();
203
		$oDB->begin();
204
		// List variables
205
		if($obj->comment_status) $obj->commentStatus = $obj->comment_status;
206
		if(!$obj->commentStatus) $obj->commentStatus = 'DENY';
207
		if($obj->commentStatus == 'DENY') $this->_checkCommentStatusForOldVersion($obj);
208
		if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N';
209 View Code Duplication
		if($obj->homepage) 
210
		{
211
			$obj->homepage = removeHackTag($obj->homepage);
212
			if(!preg_match('/^[a-z]+:\/\//i',$obj->homepage))
213
			{
214
				$obj->homepage = 'http://'.$obj->homepage;
215
			}
216
		}
217
		
218
		if($obj->notify_message != 'Y') $obj->notify_message = 'N';
219
		if(!$obj->email_address) $obj->email_address = '';
220
		if(!$isRestore) $obj->ipaddress = $_SERVER['REMOTE_ADDR'];
221
222
                // can modify regdate only manager
223
                $grant = Context::get('grant');
224
		if(!$grant->manager)
225
		{
226
			unset($obj->regdate);
227
		}
228
		
229
		// Serialize the $extra_vars, check the extra_vars type, because duplicate serialized avoid
230
		if(!is_string($obj->extra_vars)) $obj->extra_vars = serialize($obj->extra_vars);
231
		// Remove the columns for automatic saving
232
		unset($obj->_saved_doc_srl);
233
		unset($obj->_saved_doc_title);
234
		unset($obj->_saved_doc_content);
235
		unset($obj->_saved_doc_message);
236
		// Call a trigger (before)
237
		$output = ModuleHandler::triggerCall('document.insertDocument', 'before', $obj);
238
		if(!$output->toBool()) return $output;
239
		// Register it if no given document_srl exists
240 View Code Duplication
		if(!$obj->document_srl) $obj->document_srl = getNextSequence();
241
		elseif(!$manual_inserted && !$isRestore && !checkUserSequence($obj->document_srl)) return new Object(-1, 'msg_not_permitted');
242
243
		$oDocumentModel = getModel('document');
244
		// Set to 0 if the category_srl doesn't exist
245
		if($obj->category_srl)
246
		{
247
			$category_list = $oDocumentModel->getCategoryList($obj->module_srl);
248
			if(count($category_list) > 0 && !$category_list[$obj->category_srl]->grant)
249
			{
250
				return new Object(-1, 'msg_not_permitted');
251
			}
252
			if(count($category_list) > 0 && !$category_list[$obj->category_srl]) $obj->category_srl = 0;
253
		}
254
		// Set the read counts and update order.
255
		if(!$obj->readed_count) $obj->readed_count = 0;
256
		if($isLatest) $obj->update_order = $obj->list_order = $obj->document_srl * -1;
257
		else $obj->update_order = $obj->list_order;
258
		// Check the status of password hash for manually inserting. Apply hashing for otherwise.
259
		if($obj->password && !$obj->password_is_hashed)
260
		{
261
			$obj->password = getModel('member')->hashPassword($obj->password);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ModuleObject as the method hashPassword() does only exist in the following sub-classes of ModuleObject: memberModel. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
262
		}
263
		// Insert member's information only if the member is logged-in and not manually registered.
264
		$logged_info = Context::get('logged_info');
265
		if(Context::get('is_logged') && !$manual_inserted && !$isRestore)
266
		{
267
			$obj->member_srl = $logged_info->member_srl;
268
269
			// user_id, user_name and nick_name already encoded
270
			$obj->user_id = htmlspecialchars_decode($logged_info->user_id);
271
			$obj->user_name = htmlspecialchars_decode($logged_info->user_name);
272
			$obj->nick_name = htmlspecialchars_decode($logged_info->nick_name);
273
			$obj->email_address = $logged_info->email_address;
274
			$obj->homepage = $logged_info->homepage;
275
		}
276
		// If the tile is empty, extract string from the contents.
277
		$obj->title = htmlspecialchars($obj->title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
278
		settype($obj->title, "string");
279 View Code Duplication
		if($obj->title == '') $obj->title = cut_str(trim(strip_tags(nl2br($obj->content))),20,'...');
280
		// If no tile extracted from the contents, leave it untitled.
281
		if($obj->title == '') $obj->title = 'Untitled';
282
		// Remove XE's own tags from the contents.
283
		$obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content);
284 View Code Duplication
		if(Mobile::isFromMobilePhone())
285
		{
286
			if($obj->use_html != 'Y')
287
			{
288
				$obj->content = htmlspecialchars($obj->content, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
289
			}
290
			$obj->content = nl2br($obj->content);
291
		}
292
		// Remove iframe and script if not a top adminisrator in the session.
293
		if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content);
294
		// An error appears if both log-in info and user name don't exist.
295
		if(!$logged_info->member_srl && !$obj->nick_name) return new Object(-1,'msg_invalid_request');
296
297
		$obj->lang_code = Context::getLangType();
298
		// Insert data into the DB
299
		if(!$obj->status) $this->_checkDocumentStatusForOldVersion($obj);
300
		$output = executeQuery('document.insertDocument', $obj);
301
		if(!$output->toBool())
302
		{
303
			$oDB->rollback();
304
			return $output;
305
		}
306
		// Insert extra variables if the document successfully inserted.
307
		$extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl);
308 View Code Duplication
		if(count($extra_keys))
309
		{
310
			foreach($extra_keys as $idx => $extra_item)
311
			{
312
				$value = NULL;
313
				if(isset($obj->{'extra_vars'.$idx}))
314
				{
315
					$tmp = $obj->{'extra_vars'.$idx};
316
					if(is_array($tmp))
317
						$value = implode('|@|', $tmp);
318
					else
319
						$value = trim($tmp);
320
				}
321
				else if(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name});
322
				if($value == NULL) continue;
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $value of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
323
324
				$this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid);
325
			}
326
		}
327
		// Update the category if the category_srl exists.
328
		if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl);
329
		// Call a trigger (after)
330 View Code Duplication
		if($output->toBool())
331
		{
332
			$trigger_output = ModuleHandler::triggerCall('document.insertDocument', 'after', $obj);
333
			if(!$trigger_output->toBool())
334
			{
335
				$oDB->rollback();
336
				return $trigger_output;
337
			}
338
		}
339
340
		// commit
341
		$oDB->commit();
342
343
		// return
344
		if(!$manual_inserted)
345
		{
346
			$this->addGrant($obj->document_srl);
347
		}
348
		$output->add('document_srl',$obj->document_srl);
349
		$output->add('category_srl',$obj->category_srl);
350
351
		return $output;
352
	}
353
354
	/**
355
	 * Update the document
356
	 * @param object $source_obj
357
	 * @param object $obj
358
	 * @param bool $manual_updated
359
	 * @return object
360
	 */
361
	function updateDocument($source_obj, $obj, $manual_updated = FALSE)
362
	{
363
		if(!$manual_updated && !checkCSRF())
364
		{
365
			return new Object(-1, 'msg_invalid_request');
366
		}
367
368
		if(!$source_obj->document_srl || !$obj->document_srl) return new Object(-1,'msg_invalied_request');
369
		if(!$obj->status && $obj->is_secret == 'Y') $obj->status = 'SECRET';
370
		if(!$obj->status) $obj->status = 'PUBLIC';
371
372
		// Call a trigger (before)
373
		$output = ModuleHandler::triggerCall('document.updateDocument', 'before', $obj);
374
		if(!$output->toBool()) return $output;
375
376
		// begin transaction
377
		$oDB = &DB::getInstance();
378
		$oDB->begin();
379
380
		$oModuleModel = getModel('module');
381
		if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl');
382
		$module_srl = $obj->module_srl;
383
		$document_config = $oModuleModel->getModulePartConfig('document', $module_srl);
384
		if(!$document_config)
385
		{
386
			$document_config = new stdClass();
387
		}
388
		if(!isset($document_config->use_history)) $document_config->use_history = 'N';
389
		$bUseHistory = $document_config->use_history == 'Y' || $document_config->use_history == 'Trace';
390
391
		if($bUseHistory)
392
		{
393
			$args = new stdClass;
394
			$args->history_srl = getNextSequence();
395
			$args->document_srl = $obj->document_srl;
396
			$args->module_srl = $module_srl;
397
			if($document_config->use_history == 'Y') $args->content = $source_obj->get('content');
398
			$args->nick_name = $source_obj->get('nick_name');
399
			$args->member_srl = $source_obj->get('member_srl');
400
			$args->regdate = $source_obj->get('last_update');
401
			$args->ipaddress = $source_obj->get('ipaddress');
402
			$output = executeQuery("document.insertHistory", $args);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
403
		}
404
		else
405
		{
406
			$obj->ipaddress = $source_obj->get('ipaddress');
407
		}
408
		// List variables
409
		if($obj->comment_status) $obj->commentStatus = $obj->comment_status;
410
		if(!$obj->commentStatus) $obj->commentStatus = 'DENY';
411
		if($obj->commentStatus == 'DENY') $this->_checkCommentStatusForOldVersion($obj);
412
		if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N';
413 View Code Duplication
		if($obj->homepage)
414
		{
415
			$obj->homepage = removeHackTag($obj->homepage);
416
			if(!preg_match('/^[a-z]+:\/\//i',$obj->homepage))
417
			{
418
				$obj->homepage = 'http://'.$obj->homepage;
419
			}
420
		}
421
		
422
		if($obj->notify_message != 'Y') $obj->notify_message = 'N';
423
		
424
		// can modify regdate only manager
425
                $grant = Context::get('grant');
426
		if(!$grant->manager)
427
		{
428
			unset($obj->regdate);
429
		}
430
		
431
		// Serialize the $extra_vars
432
		if(!is_string($obj->extra_vars)) $obj->extra_vars = serialize($obj->extra_vars);
433
		// Remove the columns for automatic saving
434
		unset($obj->_saved_doc_srl);
435
		unset($obj->_saved_doc_title);
436
		unset($obj->_saved_doc_content);
437
		unset($obj->_saved_doc_message);
438
439
		$oDocumentModel = getModel('document');
440
		// Set the category_srl to 0 if the changed category is not exsiting.
441
		if($source_obj->get('category_srl')!=$obj->category_srl)
442
		{
443
			$category_list = $oDocumentModel->getCategoryList($obj->module_srl);
444
			if(!$category_list[$obj->category_srl]) $obj->category_srl = 0;
445
		}
446
		// Change the update order
447
		$obj->update_order = getNextSequence() * -1;
448
		// Hash the password if it exists
449
		if($obj->password)
450
		{
451
			$obj->password = getModel('member')->hashPassword($obj->password);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ModuleObject as the method hashPassword() does only exist in the following sub-classes of ModuleObject: memberModel. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
452
		}
453
		// If an author is identical to the modifier or history is used, use the logged-in user's information.
454 View Code Duplication
		if(Context::get('is_logged'))
455
		{
456
			$logged_info = Context::get('logged_info');
457
			if($source_obj->get('member_srl')==$logged_info->member_srl)
458
			{
459
				$obj->member_srl = $logged_info->member_srl;
460
				$obj->user_name = htmlspecialchars_decode($logged_info->user_name);
461
				$obj->nick_name = htmlspecialchars_decode($logged_info->nick_name);
462
				$obj->email_address = $logged_info->email_address;
463
				$obj->homepage = $logged_info->homepage;
464
			}
465
		}
466
		// For the document written by logged-in user however no nick_name exists
467 View Code Duplication
		if($source_obj->get('member_srl')&& !$obj->nick_name)
468
		{
469
			$obj->member_srl = $source_obj->get('member_srl');
470
			$obj->user_name = $source_obj->get('user_name');
471
			$obj->nick_name = $source_obj->get('nick_name');
472
			$obj->email_address = $source_obj->get('email_address');
473
			$obj->homepage = $source_obj->get('homepage');
474
		}
475
		// If the tile is empty, extract string from the contents.
476
		$obj->title = htmlspecialchars($obj->title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
477
		settype($obj->title, "string");
478 View Code Duplication
		if($obj->title == '') $obj->title = cut_str(strip_tags($obj->content),20,'...');
479
		// If no tile extracted from the contents, leave it untitled.
480
		if($obj->title == '') $obj->title = 'Untitled';
481
		// Remove XE's own tags from the contents.
482
		$obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content);
483 View Code Duplication
		if(Mobile::isFromMobilePhone())
484
		{
485
			if($obj->use_html != 'Y')
486
			{
487
				$obj->content = htmlspecialchars($obj->content, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
488
			}
489
			$obj->content = nl2br($obj->content);
490
		}
491
		// Change not extra vars but language code of the original document if document's lang_code is different from author's setting.
492
		if($source_obj->get('lang_code') != Context::getLangType())
493
		{
494
			// Change not extra vars but language code of the original document if document's lang_code doesn't exist.
495
			if(!$source_obj->get('lang_code'))
496
			{
497
				$lang_code_args->document_srl = $source_obj->get('document_srl');
0 ignored issues
show
Bug introduced by
The variable $lang_code_args does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
498
				$lang_code_args->lang_code = Context::getLangType();
499
				$output = executeQuery('document.updateDocumentsLangCode', $lang_code_args);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
500
			}
501
			else
502
			{
503
				$extra_content = new stdClass;
504
				$extra_content->title = $obj->title;
505
				$extra_content->content = $obj->content;
506
507
				$document_args = new stdClass;
508
				$document_args->document_srl = $source_obj->get('document_srl');
509
				$document_output = executeQuery('document.getDocument', $document_args);
510
				$obj->title = $document_output->data->title;
511
				$obj->content = $document_output->data->content;
512
			}
513
		}
514
		// Remove iframe and script if not a top adminisrator in the session.
515
		if($logged_info->is_admin != 'Y')
0 ignored issues
show
Bug introduced by
The variable $logged_info does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
516
		{
517
			$obj->content = removeHackTag($obj->content);
518
		}
519
		// if temporary document, regdate is now setting
520
		if($source_obj->get('status') == $this->getConfigStatus('temp')) $obj->regdate = date('YmdHis');
521
522
		// Insert data into the DB
523
		$output = executeQuery('document.updateDocument', $obj);
524
		if(!$output->toBool())
525
		{
526
			$oDB->rollback();
527
			return $output;
528
		}
529
		// Remove all extra variables
530
		if(Context::get('act')!='procFileDelete')
531
		{
532
			$this->deleteDocumentExtraVars($source_obj->get('module_srl'), $obj->document_srl, null, Context::getLangType());
533
			// Insert extra variables if the document successfully inserted.
534
			$extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl);
535 View Code Duplication
			if(count($extra_keys))
536
			{
537
				foreach($extra_keys as $idx => $extra_item)
538
				{
539
					$value = NULL;
540
					if(isset($obj->{'extra_vars'.$idx}))
541
					{
542
						$tmp = $obj->{'extra_vars'.$idx};
543
						if(is_array($tmp))
544
							$value = implode('|@|', $tmp);
545
						else
546
							$value = trim($tmp);
547
					}
548
					else if(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name});
549
					if($value == NULL) continue;
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $value of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
550
					$this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid);
551
				}
552
			}
553
			// Inert extra vars for multi-language support of title and contents.
554 View Code Duplication
			if($extra_content->title) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -1, $extra_content->title, 'title_'.Context::getLangType());
0 ignored issues
show
Bug introduced by
The variable $extra_content does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
555 View Code Duplication
			if($extra_content->content) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -2, $extra_content->content, 'content_'.Context::getLangType());
556
		}
557
		// Update the category if the category_srl exists.
558
		if($source_obj->get('category_srl') != $obj->category_srl || $source_obj->get('module_srl') == $logged_info->member_srl)
559
		{
560
			if($source_obj->get('category_srl') != $obj->category_srl) $this->updateCategoryCount($obj->module_srl, $source_obj->get('category_srl'));
561
			if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl);
562
		}
563
		// Call a trigger (after)
564 View Code Duplication
		if($output->toBool())
565
		{
566
			$trigger_output = ModuleHandler::triggerCall('document.updateDocument', 'after', $obj);
567
			if(!$trigger_output->toBool())
568
			{
569
				$oDB->rollback();
570
				return $trigger_output;
571
			}
572
		}
573
574
		// commit
575
		$oDB->commit();
576
		// Remove the thumbnail file
577
		FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($obj->document_srl, 3)));
578
579
		$output->add('document_srl',$obj->document_srl);
580
		//remove from cache
581
		$oCacheHandler = CacheHandler::getInstance('object');
582 View Code Duplication
		if($oCacheHandler->isSupport())
583
		{
584
			//remove document item from cache
585
			$cache_key = 'document_item:'. getNumberingPath($obj->document_srl) . $obj->document_srl;
586
			$oCacheHandler->delete($cache_key);
587
		}
588
589
		return $output;
590
	}
591
592
	/**
593
	 * Deleting Documents
594
	 * @param int $document_srl
595
	 * @param bool $is_admin
596
	 * @param bool $isEmptyTrash
597
	 * @param documentItem $oDocument
598
	 * @return object
599
	 */
600
	function deleteDocument($document_srl, $is_admin = false, $isEmptyTrash = false, $oDocument = null)
601
	{
602
		// Call a trigger (before)
603
		$trigger_obj = new stdClass();
604
		$trigger_obj->document_srl = $document_srl;
605
		$output = ModuleHandler::triggerCall('document.deleteDocument', 'before', $trigger_obj);
606
		if(!$output->toBool()) return $output;
607
608
		// begin transaction
609
		$oDB = &DB::getInstance();
610
		$oDB->begin();
611
612
		if(!$isEmptyTrash)
613
		{
614
			// get model object of the document
615
			$oDocumentModel = getModel('document');
616
			// Check if the documnet exists
617
			$oDocument = $oDocumentModel->getDocument($document_srl, $is_admin);
618
		}
619
		else if($isEmptyTrash && $oDocument == null) return new Object(-1, 'document is not exists');
620
621
		if(!$oDocument->isExists() || $oDocument->document_srl != $document_srl) return new Object(-1, 'msg_invalid_document');
622
		// Check if a permossion is granted
623
		if(!$oDocument->isGranted()) return new Object(-1, 'msg_not_permitted');
624
625
		//if empty trash, document already deleted, therefore document not delete
626
		$args = new stdClass();
627
		$args->document_srl = $document_srl;
628
		if(!$isEmptyTrash)
629
		{
630
			// Delete the document
631
			$output = executeQuery('document.deleteDocument', $args);
632
			if(!$output->toBool())
633
			{
634
				$oDB->rollback();
635
				return $output;
636
			}
637
		}
638
639
		$this->deleteDocumentAliasByDocument($document_srl);
640
641
		$this->deleteDocumentHistory(null, $document_srl, null);
642
		// Update category information if the category_srl exists.
643
		if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl'));
644
		// Delete a declared list
645
		executeQuery('document.deleteDeclared', $args);
646
		// Delete extra variable
647
		$this->deleteDocumentExtraVars($oDocument->get('module_srl'), $oDocument->document_srl);
648
649
		//this
650
		// Call a trigger (after)
651 View Code Duplication
		if($output->toBool())
652
		{
653
			$trigger_obj = $oDocument->getObjectVars();
654
			$trigger_output = ModuleHandler::triggerCall('document.deleteDocument', 'after', $trigger_obj);
655
			if(!$trigger_output->toBool())
656
			{
657
				$oDB->rollback();
658
				return $trigger_output;
659
			}
660
		}
661
		// declared document, log delete
662
		$this->_deleteDeclaredDocuments($args);
0 ignored issues
show
Documentation introduced by
$args is of type object<stdClass>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
663
		$this->_deleteDocumentReadedLog($args);
0 ignored issues
show
Documentation introduced by
$args is of type object<stdClass>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
664
		$this->_deleteDocumentVotedLog($args);
0 ignored issues
show
Documentation introduced by
$args is of type object<stdClass>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
665
666
		// Remove the thumbnail file
667
		FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($document_srl, 3)));
668
669
		// commit
670
		$oDB->commit();
671
672
		//remove from cache
673
		$oCacheHandler = CacheHandler::getInstance('object');
674
		if($oCacheHandler->isSupport())
675
		{
676
			$cache_key = 'document_item:'. getNumberingPath($document_srl) . $document_srl;
677
			$oCacheHandler->delete($cache_key);
678
		}
679
680
		return $output;
681
	}
682
683
	/**
684
	 * Delete declared document, log
685
	 * @param string $documentSrls (ex: 1, 2,56, 88)
686
	 * @return void
687
	 */
688
	function _deleteDeclaredDocuments($documentSrls)
689
	{
690
		executeQuery('document.deleteDeclaredDocuments', $documentSrls);
0 ignored issues
show
Documentation introduced by
$documentSrls is of type string, but the function expects a object|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
691
		executeQuery('document.deleteDocumentDeclaredLog', $documentSrls);
0 ignored issues
show
Documentation introduced by
$documentSrls is of type string, but the function expects a object|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
692
	}
693
694
	/**
695
	 * Delete readed log
696
	 * @param string $documentSrls (ex: 1, 2,56, 88)
697
	 * @return void
698
	 */
699
	function _deleteDocumentReadedLog($documentSrls)
700
	{
701
		executeQuery('document.deleteDocumentReadedLog', $documentSrls);
0 ignored issues
show
Documentation introduced by
$documentSrls is of type string, but the function expects a object|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
702
	}
703
704
	/**
705
	 * Delete voted log
706
	 * @param string $documentSrls (ex: 1, 2,56, 88)
707
	 * @return void
708
	 */
709
	function _deleteDocumentVotedLog($documentSrls)
710
	{
711
		executeQuery('document.deleteDocumentVotedLog', $documentSrls);
0 ignored issues
show
Documentation introduced by
$documentSrls is of type string, but the function expects a object|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
712
	}
713
714
	/**
715
	 * Move the doc into the trash
716
	 * @param object $obj
717
	 * @return object
718
	 */
719
	function moveDocumentToTrash($obj)
720
	{
721
		$trash_args = new stdClass();
722
		// Get trash_srl if a given trash_srl doesn't exist
723
		if(!$obj->trash_srl) $trash_args->trash_srl = getNextSequence();
724
		else $trash_args->trash_srl = $obj->trash_srl;
725
		// Get its module_srl which the document belongs to
726
		$oDocumentModel = getModel('document');
727
		$oDocument = $oDocumentModel->getDocument($obj->document_srl);
728
729
		$trash_args->module_srl = $oDocument->get('module_srl');
730
		$obj->module_srl = $oDocument->get('module_srl');
731
		// Cannot throw data from the trash to the trash
732
		if($trash_args->module_srl == 0) return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by documentController::moveDocumentToTrash of type object.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
733
		// Data setting
734
		$trash_args->document_srl = $obj->document_srl;
735
		$trash_args->description = $obj->description;
736
		// Insert member's information only if the member is logged-in and not manually registered.
737
		if(Context::get('is_logged')&&!$manual_inserted)
0 ignored issues
show
Bug introduced by
The variable $manual_inserted does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
738
		{
739
			$logged_info = Context::get('logged_info');
740
			$trash_args->member_srl = $logged_info->member_srl;
741
742
			// user_id, user_name and nick_name already encoded
743
			$trash_args->user_id = htmlspecialchars_decode($logged_info->user_id);
744
			$trash_args->user_name = htmlspecialchars_decode($logged_info->user_name);
745
			$trash_args->nick_name = htmlspecialchars_decode($logged_info->nick_name);
746
		}
747
		// Date setting for updating documents
748
		$document_args = new stdClass;
749
		$document_args->module_srl = 0;
750
		$document_args->document_srl = $obj->document_srl;
751
752
		// begin transaction
753
		$oDB = &DB::getInstance();
754
		$oDB->begin();
755
756
		/*$output = executeQuery('document.insertTrash', $trash_args);
757
		  if (!$output->toBool()) {
758
		  $oDB->rollback();
759
		  return $output;
760
		  }*/
761
762
		// new trash module
763
		require_once(_XE_PATH_.'modules/trash/model/TrashVO.php');
764
		$oTrashVO = new TrashVO();
765
		$oTrashVO->setTrashSrl(getNextSequence());
766
		$oTrashVO->setTitle($oDocument->variables['title']);
767
		$oTrashVO->setOriginModule('document');
768
		$oTrashVO->setSerializedObject(serialize($oDocument->variables));
769
		$oTrashVO->setDescription($obj->description);
770
771
		$oTrashAdminController = getAdminController('trash');
772
		$output = $oTrashAdminController->insertTrash($oTrashVO);
773
		if(!$output->toBool())
774
		{
775
			$oDB->rollback();
776
			return $output;
777
		}
778
779
		$output = executeQuery('document.deleteDocument', $trash_args);
780
		if(!$output->toBool())
781
		{
782
			$oDB->rollback();
783
			return $output;
784
		}
785
786
		/*$output = executeQuery('document.updateDocument', $document_args);
787
		  if (!$output->toBool()) {
788
		  $oDB->rollback();
789
		  return $output;
790
		  }*/
791
792
		// update category
793
		if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl'));
794
795
		// remove thumbnails
796
		FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($obj->document_srl, 3)));
797
		// Set the attachment to be invalid state
798 View Code Duplication
		if($oDocument->hasUploadedFiles())
799
		{
800
			$args = new stdClass();
801
			$args->upload_target_srl = $oDocument->document_srl;
802
			$args->isvalid = 'N';
803
			executeQuery('file.updateFileValid', $args);
804
		}
805
		// Call a trigger (after)
806 View Code Duplication
		if($output->toBool())
807
		{
808
			$trigger_output = ModuleHandler::triggerCall('document.moveDocumentToTrash', 'after', $obj);
809
			if(!$trigger_output->toBool())
810
			{
811
				$oDB->rollback();
812
				return $trigger_output;
813
			}
814
		}
815
816
		// commit
817
		$oDB->commit();
818
819
		// Clear cache
820
		$oCacheHandler = CacheHandler::getInstance('object');
821 View Code Duplication
		if($oCacheHandler->isSupport())
822
		{
823
			$cache_key = 'document_item:'. getNumberingPath($oDocument->document_srl) . $oDocument->document_srl;
824
			$oCacheHandler->delete($cache_key);
825
		}
826
827
		return $output;
828
	}
829
830
	/**
831
	 * Update read counts of the document
832
	 * @param documentItem $oDocument
833
	 * @return bool|void
834
	 */
835
	function updateReadedCount(&$oDocument)
836
	{
837
		// Pass if Crawler access
838
		if(isCrawler()) return false;
839
		
840
		$document_srl = $oDocument->document_srl;
0 ignored issues
show
Bug introduced by
The property document_srl cannot be accessed from this context as it is declared private in class documentItem.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
841
		$member_srl = $oDocument->get('member_srl');
842
		$logged_info = Context::get('logged_info');
843
844
		// Call a trigger when the read count is updated (before)
845
		$trigger_output = ModuleHandler::triggerCall('document.updateReadedCount', 'before', $oDocument);
846
		if(!$trigger_output->toBool()) return $trigger_output;
847
848
		// Pass if read count is increaded on the session information
849
		if($_SESSION['readed_document'][$document_srl]) return false;
850
851
		// Pass if the author's IP address is as same as visitor's.
852
		if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR'])
853
		{
854
			$_SESSION['readed_document'][$document_srl] = true;
855
			return false;
856
		}
857
		// Pass ater registering sesscion if the author is a member and has same information as the currently logged-in user.
858
		if($member_srl && $logged_info->member_srl == $member_srl)
859
		{
860
			$_SESSION['readed_document'][$document_srl] = true;
861
			return false;
862
		}
863
864
		$oDB = DB::getInstance();
865
		$oDB->begin();
866
867
		// Update read counts
868
		$args = new stdClass;
869
		$args->document_srl = $document_srl;
870
		$output = executeQuery('document.updateReadedCount', $args);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
871
872
		// Call a trigger when the read count is updated (after)
873
		$trigger_output = ModuleHandler::triggerCall('document.updateReadedCount', 'after', $oDocument);
874
		if(!$trigger_output->toBool())
875
		{
876
			$oDB->rollback();
877
			return $trigger_output;
878
		}
879
880
		$oDB->commit();
881
882
		$oCacheHandler = CacheHandler::getInstance('object');
883
		if($oCacheHandler->isSupport())
884
		{
885
			//remove document item from cache
886
			$cache_key = 'document_item:'. getNumberingPath($document_srl) . $document_srl;
887
			$oCacheHandler->delete($cache_key);
888
		}
889
890
		// Register session
891
		if(!$_SESSION['banned_document'][$document_srl]) 
892
		{
893
			$_SESSION['readed_document'][$document_srl] = true;
894
		}
895
896
		return TRUE;
897
	}
898
899
	/**
900
	 * Insert extra variables into the document table
901
	 * @param int $module_srl
902
	 * @param int $var_idx
903
	 * @param string $var_name
904
	 * @param string $var_type
905
	 * @param string $var_is_required
906
	 * @param string $var_search
907
	 * @param string $var_default
908
	 * @param string $var_desc
909
	 * @param int $eid
910
	 * @return object
911
	 */
912
	function insertDocumentExtraKey($module_srl, $var_idx, $var_name, $var_type, $var_is_required = 'N', $var_search = 'N', $var_default = '', $var_desc = '', $eid)
913
	{
914
		if(!$module_srl || !$var_idx || !$var_name || !$var_type || !$eid) return new Object(-1,'msg_invalid_request');
915
916
		$obj = new stdClass();
917
		$obj->module_srl = $module_srl;
918
		$obj->var_idx = $var_idx;
919
		$obj->var_name = $var_name;
920
		$obj->var_type = $var_type;
921
		$obj->var_is_required = $var_is_required=='Y'?'Y':'N';
922
		$obj->var_search = $var_search=='Y'?'Y':'N';
923
		$obj->var_default = $var_default;
924
		$obj->var_desc = $var_desc;
925
		$obj->eid = $eid;
926
927
		$output = executeQuery('document.getDocumentExtraKeys', $obj);
928
		if(!$output->data)
929
		{
930
			$output = executeQuery('document.insertDocumentExtraKey', $obj);
931
		}
932
		else
933
		{
934
			$output = executeQuery('document.updateDocumentExtraKey', $obj);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
935
			// Update the extra var(eid)
936
			$output = executeQuery('document.updateDocumentExtraVar', $obj);
937
		}
938
939
		$oCacheHandler = CacheHandler::getInstance('object', NULL, TRUE);
940
		if($oCacheHandler->isSupport())
941
		{
942
			$object_key = 'module_document_extra_keys:'.$module_srl;
943
			$cache_key = $oCacheHandler->getGroupKey('site_and_module', $object_key);
944
			$oCacheHandler->delete($cache_key);
945
		}
946
947
		return $output;
948
	}
949
950
	/**
951
	 * Remove the extra variables of the documents
952
	 * @param int $module_srl
953
	 * @param int $var_idx
954
	 * @return Object
955
	 */
956
	function deleteDocumentExtraKeys($module_srl, $var_idx = null)
957
	{
958
		if(!$module_srl) return new Object(-1,'msg_invalid_request');
959
		$obj = new stdClass();
960
		$obj->module_srl = $module_srl;
961
		if(!is_null($var_idx)) $obj->var_idx = $var_idx;
962
963
		$oDB = DB::getInstance();
964
		$oDB->begin();
965
966
		$output = $oDB->executeQuery('document.deleteDocumentExtraKeys', $obj);
967
		if(!$output->toBool())
968
		{
969
			$oDB->rollback();
970
			return $output;
971
		}
972
973
		if($var_idx != NULL)
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $var_idx of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
974
		{
975
			$output = $oDB->executeQuery('document.updateDocumentExtraKeyIdxOrder', $obj);
976
			if(!$output->toBool())
977
			{
978
				$oDB->rollback();
979
				return $output;
980
			}
981
		}
982
983
		$output =  executeQuery('document.deleteDocumentExtraVars', $obj);
984
		if(!$output->toBool())
985
		{
986
			$oDB->rollback();
987
			return $output;
988
		}
989
990
		if($var_idx != NULL)
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $var_idx of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
991
		{
992
			$output = $oDB->executeQuery('document.updateDocumentExtraVarIdxOrder', $obj);
993
			if(!$output->toBool())
994
			{
995
				$oDB->rollback();
996
				return $output;
997
			}
998
		}
999
1000
		$oDB->commit();
1001
1002
		$oCacheHandler = CacheHandler::getInstance('object', NULL, TRUE);
1003
		if($oCacheHandler->isSupport())
1004
		{
1005
			$object_key = 'module_document_extra_keys:'.$module_srl;
1006
			$cache_key = $oCacheHandler->getGroupKey('site_and_module', $object_key);
1007
			$oCacheHandler->delete($cache_key);
1008
		}
1009
1010
		return new Object();
1011
	}
1012
1013
	/**
1014
	 * Insert extra vaiable to the documents table
1015
	 * @param int $module_srl
1016
	 * @param int $document_srl
1017
	 * @param int $var_idx
1018
	 * @param mixed $value
1019
	 * @param int $eid
1020
	 * @param string $lang_code
1021
	 * @return Object|void
1022
	 */
1023
	function insertDocumentExtraVar($module_srl, $document_srl, $var_idx, $value, $eid = null, $lang_code = '')
1024
	{
1025
		if(!$module_srl || !$document_srl || !$var_idx || !isset($value)) return new Object(-1,'msg_invalid_request');
1026
		if(!$lang_code) $lang_code = Context::getLangType();
1027
1028
		$obj = new stdClass;
1029
		$obj->module_srl = $module_srl;
1030
		$obj->document_srl = $document_srl;
1031
		$obj->var_idx = $var_idx;
1032
		$obj->value = $value;
1033
		$obj->lang_code = $lang_code;
1034
		$obj->eid = $eid;
1035
1036
		executeQuery('document.insertDocumentExtraVar', $obj);
1037
	}
1038
1039
	/**
1040
	 * Remove values of extra variable from the document
1041
	 * @param int $module_srl
1042
	 * @param int $document_srl
1043
	 * @param int $var_idx
1044
	 * @param string $lang_code
1045
	 * @param int $eid
1046
	 * @return $output
0 ignored issues
show
Documentation introduced by
The doc-type $output could not be parsed: Unknown type name "$output" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1047
	 */
1048
	function deleteDocumentExtraVars($module_srl, $document_srl = null, $var_idx = null, $lang_code = null, $eid = null)
1049
	{
1050
		$obj = new stdClass();
1051
		$obj->module_srl = $module_srl;
1052
		if(!is_null($document_srl)) $obj->document_srl = $document_srl;
1053
		if(!is_null($var_idx)) $obj->var_idx = $var_idx;
1054
		if(!is_null($lang_code)) $obj->lang_code = $lang_code;
1055
		if(!is_null($eid)) $obj->eid = $eid;
1056
		$output = executeQuery('document.deleteDocumentExtraVars', $obj);
1057
		return $output;
1058
	}
1059
1060
1061
	/**
1062
	 * Increase the number of vote-up of the document
1063
	 * @param int $document_srl
1064
	 * @param int $point
1065
	 * @return Object
1066
	 */
1067
	function updateVotedCount($document_srl, $point = 1)
1068
	{
1069
		if($point > 0) $failed_voted = 'failed_voted';
1070
		else $failed_voted = 'failed_blamed';
1071
		// Return fail if session already has information about votes
1072
		if($_SESSION['voted_document'][$document_srl])
1073
		{
1074
			return new Object(-1, $failed_voted);
1075
		}
1076
		// Get the original document
1077
		$oDocumentModel = getModel('document');
1078
		$oDocument = $oDocumentModel->getDocument($document_srl, false, false);
1079
		// Pass if the author's IP address is as same as visitor's.
1080
		if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR'])
1081
		{
1082
			$_SESSION['voted_document'][$document_srl] = true;
1083
			return new Object(-1, $failed_voted);
1084
		}
1085
1086
		// Create a member model object
1087
		$oMemberModel = getModel('member');
1088
		$member_srl = $oMemberModel->getLoggedMemberSrl();
1089
1090
		// Check if document's author is a member.
1091
		if($oDocument->get('member_srl'))
1092
		{
1093
			// Pass after registering a session if author's information is same as the currently logged-in user's.
1094
			if($member_srl && $member_srl == $oDocument->get('member_srl'))
1095
			{
1096
				$_SESSION['voted_document'][$document_srl] = true;
1097
				return new Object(-1, $failed_voted);
1098
			}
1099
		}
1100
1101
		// Use member_srl for logged-in members and IP address for non-members.
1102
		$args = new stdClass;
1103
		if($member_srl)
1104
		{
1105
			$args->member_srl = $member_srl;
1106
		}
1107
		else
1108
		{
1109
			$args->ipaddress = $_SERVER['REMOTE_ADDR'];
1110
		}
1111
		$args->document_srl = $document_srl;
1112
		$output = executeQuery('document.getDocumentVotedLogInfo', $args);
1113
		// Pass after registering a session if log information has vote-up logs
1114
		if($output->data->count)
1115
		{
1116
			$_SESSION['voted_document'][$document_srl] = true;
1117
			return new Object(-1, $failed_voted);
1118
		}
1119
1120
		// begin transaction
1121
		$oDB = DB::getInstance();
1122
		$oDB->begin();
1123
1124
		// Update the voted count
1125 View Code Duplication
		if($point < 0)
1126
		{
1127
			$args->blamed_count = $oDocument->get('blamed_count') + $point;
1128
			$output = executeQuery('document.updateBlamedCount', $args);
1129
		}
1130
		else
1131
		{
1132
			$args->voted_count = $oDocument->get('voted_count') + $point;
1133
			$output = executeQuery('document.updateVotedCount', $args);
1134
		}
1135
		if(!$output->toBool()) return $output;
1136
		// Leave logs
1137
		$args->point = $point;
1138
		$output = executeQuery('document.insertDocumentVotedLog', $args);
1139
		if(!$output->toBool()) return $output;
1140
1141
		$obj = new stdClass;
1142
		$obj->member_srl = $oDocument->get('member_srl');
1143
		$obj->module_srl = $oDocument->get('module_srl');
1144
		$obj->document_srl = $oDocument->get('document_srl');
1145
		$obj->update_target = ($point < 0) ? 'blamed_count' : 'voted_count';
1146
		$obj->point = $point;
1147
		$obj->before_point = ($point < 0) ? $oDocument->get('blamed_count') : $oDocument->get('voted_count');
1148
		$obj->after_point = ($point < 0) ? $args->blamed_count : $args->voted_count;
1149
		$trigger_output = ModuleHandler::triggerCall('document.updateVotedCount', 'after', $obj);
1150
		if(!$trigger_output->toBool())
1151
		{
1152
			$oDB->rollback();
1153
			return $trigger_output;
1154
		}
1155
1156
		$oDB->commit();
1157
1158
		$oCacheHandler = CacheHandler::getInstance('object');
1159
		if($oCacheHandler->isSupport())
1160
		{
1161
			//remove document item from cache
1162
			$cache_key = 'document_item:'. getNumberingPath($document_srl) . $document_srl;
1163
			$oCacheHandler->delete($cache_key);
1164
		}
1165
1166
		// Leave in the session information
1167
		$_SESSION['voted_document'][$document_srl] = true;
1168
1169
		// Return result
1170
		$output = new Object();
1171
		if($point > 0)
1172
		{
1173
			$output->setMessage('success_voted');
1174
			$output->add('voted_count', $obj->after_point);
1175
		}
1176
		else
1177
		{
1178
			$output->setMessage('success_blamed');
1179
			$output->add('blamed_count', $obj->after_point);
1180
		}
1181
		
1182
		return $output;
1183
	}
1184
1185
	/**
1186
	 * Report posts
1187
	 * @param int $document_srl
1188
	 * @return void|Object
1189
	 */
1190
	function declaredDocument($document_srl)
1191
	{
1192
		// Fail if session information already has a reported document
1193
		if($_SESSION['declared_document'][$document_srl]) return new Object(-1, 'failed_declared');
1194
1195
		// Check if previously reported
1196
		$args = new stdClass();
1197
		$args->document_srl = $document_srl;
1198
		$output = executeQuery('document.getDeclaredDocument', $args);
1199
		if(!$output->toBool()) return $output;
1200
1201
		$declared_count = ($output->data->declared_count) ? $output->data->declared_count : 0;
1202
1203
		$trigger_obj = new stdClass();
1204
		$trigger_obj->document_srl = $document_srl;
1205
		$trigger_obj->declared_count = $declared_count;
1206
1207
		// Call a trigger (before)
1208
		$trigger_output = ModuleHandler::triggerCall('document.declaredDocument', 'before', $trigger_obj);
1209
		if(!$trigger_output->toBool())
1210
		{
1211
			return $trigger_output;
1212
		}
1213
1214
		// Get the original document
1215
		$oDocumentModel = getModel('document');
1216
		$oDocument = $oDocumentModel->getDocument($document_srl, false, false);
1217
1218
		// Pass if the author's IP address is as same as visitor's.
1219 View Code Duplication
		if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR']) {
1220
			$_SESSION['declared_document'][$document_srl] = true;
1221
			return new Object(-1, 'failed_declared');
1222
		}
1223
1224
		// Check if document's author is a member.
1225 View Code Duplication
		if($oDocument->get('member_srl'))
1226
		{
1227
			// Create a member model object
1228
			$oMemberModel = getModel('member');
1229
			$member_srl = $oMemberModel->getLoggedMemberSrl();
1230
			// Pass after registering a session if author's information is same as the currently logged-in user's.
1231
			if($member_srl && $member_srl == $oDocument->get('member_srl'))
1232
			{
1233
				$_SESSION['declared_document'][$document_srl] = true;
1234
				return new Object(-1, 'failed_declared');
1235
			}
1236
		}
1237
1238
		// Use member_srl for logged-in members and IP address for non-members.
1239
		$args = new stdClass;
1240
		if($member_srl)
1241
		{
1242
			$args->member_srl = $member_srl;
0 ignored issues
show
Bug introduced by
The variable $member_srl does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1243
		}
1244
		else
1245
		{
1246
			$args->ipaddress = $_SERVER['REMOTE_ADDR'];
1247
		}
1248
1249
		$args->document_srl = $document_srl;
1250
		$output = executeQuery('document.getDocumentDeclaredLogInfo', $args);
1251
1252
		// Pass after registering a sesson if reported/declared documents are in the logs.
1253
		if($output->data->count)
1254
		{
1255
			$_SESSION['declared_document'][$document_srl] = true;
1256
			return new Object(-1, 'failed_declared');
1257
		}
1258
1259
		// begin transaction
1260
		$oDB = &DB::getInstance();
1261
		$oDB->begin();
1262
1263
		// Add the declared document
1264
		if($declared_count > 0) $output = executeQuery('document.updateDeclaredDocument', $args);
1265
		else $output = executeQuery('document.insertDeclaredDocument', $args);
1266
		if(!$output->toBool()) return $output;
1267
		// Leave logs
1268
		$output = executeQuery('document.insertDocumentDeclaredLog', $args);
1269
		if(!$output->toBool())
1270
		{
1271
			$oDB->rollback();
1272
			return $output;
1273
		}
1274
1275
		$this->add('declared_count', $declared_count+1);
1276
1277
		// Call a trigger (after)
1278
		$trigger_obj->declared_count = $declared_count + 1;
1279
		$trigger_output = ModuleHandler::triggerCall('document.declaredDocument', 'after', $trigger_obj);
1280
		if(!$trigger_output->toBool())
1281
		{
1282
			$oDB->rollback();
1283
			return $trigger_output;
1284
		}
1285
1286
		// commit
1287
		$oDB->commit();
1288
1289
		// Leave in the session information
1290
		$_SESSION['declared_document'][$document_srl] = true;
1291
1292
		$this->setMessage('success_declared');
1293
	}
1294
1295
	/**
1296
	 * Increase the number of comments in the document
1297
	 * Update modified date, modifier, and order with increasing comment count
1298
	 * @param int $document_srl
1299
	 * @param int $comment_count
1300
	 * @param string $last_updater
1301
	 * @param bool $comment_inserted
1302
	 * @return object
1303
	 */
1304
	function updateCommentCount($document_srl, $comment_count, $last_updater, $comment_inserted = false)
1305
	{
1306
		$args = new stdClass();
1307
		$args->document_srl = $document_srl;
1308
		$args->comment_count = $comment_count;
1309
1310
		if($comment_inserted)
1311
		{
1312
			$args->update_order = -1*getNextSequence();
1313
			$args->last_updater = $last_updater;
1314
1315
			$oCacheHandler = CacheHandler::getInstance('object');
1316
			if($oCacheHandler->isSupport())
1317
			{
1318
				//remove document item from cache
1319
				$cache_key = 'document_item:'. getNumberingPath($document_srl) . $document_srl;
1320
				$oCacheHandler->delete($cache_key);
1321
			}
1322
		}
1323
1324
		return executeQuery('document.updateCommentCount', $args);
1325
	}
1326
1327
	/**
1328
	 * Increase trackback count of the document
1329
	 * @param int $document_srl
1330
	 * @param int $trackback_count
1331
	 * @return object
1332
	 */
1333
	function updateTrackbackCount($document_srl, $trackback_count)
1334
	{
1335
		$args = new stdClass;
1336
		$args->document_srl = $document_srl;
1337
		$args->trackback_count = $trackback_count;
1338
1339
		$oCacheHandler = CacheHandler::getInstance('object');
1340
		if($oCacheHandler->isSupport())
1341
		{
1342
			//remove document item from cache
1343
			$cache_key = 'document_item:'. getNumberingPath($document_srl) . $document_srl;
1344
			$oCacheHandler->delete($cache_key);
1345
		}
1346
1347
		return executeQuery('document.updateTrackbackCount', $args);
1348
	}
1349
1350
	/**
1351
	 * Add a category
1352
	 * @param object $obj
1353
	 * @return object
1354
	 */
1355
	function insertCategory($obj)
1356
	{
1357
		// Sort the order to display if a child category is added
1358
		if($obj->parent_srl)
1359
		{
1360
			// Get its parent category
1361
			$oDocumentModel = getModel('document');
1362
			$parent_category = $oDocumentModel->getCategory($obj->parent_srl);
1363
			$obj->list_order = $parent_category->list_order;
1364
			$this->updateCategoryListOrder($parent_category->module_srl, $parent_category->list_order+1);
1365
			if(!$obj->category_srl) $obj->category_srl = getNextSequence();
1366
		}
1367
		else
1368
		{
1369
			$obj->list_order = $obj->category_srl = getNextSequence();
1370
		}
1371
1372
		$output = executeQuery('document.insertCategory', $obj);
1373
		if($output->toBool())
1374
		{
1375
			$output->add('category_srl', $obj->category_srl);
1376
			$this->makeCategoryFile($obj->module_srl);
1377
		}
1378
1379
		return $output;
1380
	}
1381
1382
	/**
1383
	 * Increase list_count from a specific category
1384
	 * @param int $module_srl
1385
	 * @param int $list_order
1386
	 * @return object
1387
	 */
1388
	function updateCategoryListOrder($module_srl, $list_order)
1389
	{
1390
		$args = new stdClass;
1391
		$args->module_srl = $module_srl;
1392
		$args->list_order = $list_order;
1393
		return executeQuery('document.updateCategoryOrder', $args);
1394
	}
1395
1396
	/**
1397
	 * Update document_count in the category.
1398
	 * @param int $module_srl
1399
	 * @param int $category_srl
1400
	 * @param int $document_count
1401
	 * @return object
1402
	 */
1403
	function updateCategoryCount($module_srl, $category_srl, $document_count = 0)
1404
	{
1405
		// Create a document model object
1406
		$oDocumentModel = getModel('document');
1407
		if(!$document_count) $document_count = $oDocumentModel->getCategoryDocumentCount($module_srl,$category_srl);
1408
1409
		$args = new stdClass;
1410
		$args->category_srl = $category_srl;
1411
		$args->document_count = $document_count;
1412
		$output = executeQuery('document.updateCategoryCount', $args);
1413
		if($output->toBool()) $this->makeCategoryFile($module_srl);
1414
1415
		return $output;
1416
	}
1417
1418
	/**
1419
	 * Update category information
1420
	 * @param object $obj
1421
	 * @return object
1422
	 */
1423
	function updateCategory($obj)
1424
	{
1425
		$output = executeQuery('document.updateCategory', $obj);
1426
		if($output->toBool()) $this->makeCategoryFile($obj->module_srl);
1427
		return $output;
1428
	}
1429
1430
	/**
1431
	 * Delete a category
1432
	 * @param int $category_srl
1433
	 * @return object
1434
	 */
1435
	function deleteCategory($category_srl)
1436
	{
1437
		$args = new stdClass();
1438
		$args->category_srl = $category_srl;
1439
		$oDocumentModel = getModel('document');
1440
		$category_info = $oDocumentModel->getCategory($category_srl);
1441
		// Display an error that the category cannot be deleted if it has a child
1442
		$output = executeQuery('document.getChildCategoryCount', $args);
1443
		if(!$output->toBool()) return $output;
1444
		if($output->data->count>0) return new Object(-1, 'msg_cannot_delete_for_child');
1445
		// Delete a category information
1446
		$output = executeQuery('document.deleteCategory', $args);
1447
		if(!$output->toBool()) return $output;
1448
1449
		$this->makeCategoryFile($category_info->module_srl);
1450
		// remvove cache
1451
		$oCacheHandler = CacheHandler::getInstance('object');
1452
		if($oCacheHandler->isSupport())
1453
		{
1454
			$page = 0;
1455
			while(true) {
1456
				$args = new stdClass();
1457
				$args->category_srl = $category_srl;
1458
				$args->list_count = 100;
1459
				$args->page = ++$page;
1460
				$output = executeQuery('document.getDocumentList', $args, array('document_srl'));
1461
1462
				if($output->data == array())
1463
					break;
1464
1465
				foreach($output->data as $val)
1466
				{
1467
					//remove document item from cache
1468
					$cache_key = 'document_item:'. getNumberingPath($val->document_srl) . $val->document_srl;
1469
					$oCacheHandler->delete($cache_key);
1470
				}
1471
			}
1472
		}
1473
1474
		// Update category_srl of the documents in the same category to 0
1475
		$args = new stdClass();
1476
		$args->target_category_srl = 0;
1477
		$args->source_category_srl = $category_srl;
1478
		$output = executeQuery('document.updateDocumentCategory', $args);
1479
1480
		return $output;
1481
	}
1482
1483
	/**
1484
	 * Delete all categories in a module
1485
	 * @param int $module_srl
1486
	 * @return object
1487
	 */
1488
	function deleteModuleCategory($module_srl)
1489
	{
1490
		$args = new stdClass();
1491
		$args->module_srl = $module_srl;
1492
		$output = executeQuery('document.deleteModuleCategory', $args);
1493
		return $output;
1494
	}
1495
1496
	/**
1497
	 * Move the category level to higher
1498
	 * @param int $category_srl
1499
	 * @return Object
1500
	 */
1501
	function moveCategoryUp($category_srl)
1502
	{
1503
		$oDocumentModel = getModel('document');
1504
		// Get information of the selected category
1505
		$args = new stdClass;
1506
		$args->category_srl = $category_srl;
1507
		$output = executeQuery('document.getCategory', $args);
1508
1509
		$category = $output->data;
1510
		$list_order = $category->list_order;
1511
		$module_srl = $category->module_srl;
1512
		// Seek a full list of categories
1513
		$category_list = $oDocumentModel->getCategoryList($module_srl);
1514
		$category_srl_list = array_keys($category_list);
1515
		if(count($category_srl_list)<2) return new Object();
1516
1517
		$prev_category = NULL;
1518
		foreach($category_list as $key => $val)
1519
		{
1520
			if($key==$category_srl) break;
1521
			$prev_category = $val;
1522
		}
1523
		// Return if the previous category doesn't exist
1524
		if(!$prev_category) return new Object(-1,Context::getLang('msg_category_not_moved'));
1525
		// Return if the selected category is the top level
1526
		if($category_srl_list[0]==$category_srl) return new Object(-1,Context::getLang('msg_category_not_moved'));
1527
		// Information of the selected category
1528
		$cur_args = new stdClass;
1529
		$cur_args->category_srl = $category_srl;
1530
		$cur_args->list_order = $prev_category->list_order;
1531
		$cur_args->title = $category->title;
1532
		$this->updateCategory($cur_args);
1533
		// Category information
1534
		$prev_args = new stdClass;
1535
		$prev_args->category_srl = $prev_category->category_srl;
1536
		$prev_args->list_order = $list_order;
1537
		$prev_args->title = $prev_category->title;
1538
		$this->updateCategory($prev_args);
1539
1540
		return new Object();
1541
	}
1542
1543
	/**
1544
	 * Move the category down
1545
	 * @param int $category_srl
1546
	 * @return Object
1547
	 */
1548
	function moveCategoryDown($category_srl)
1549
	{
1550
		$oDocumentModel = getModel('document');
1551
		// Get information of the selected category
1552
		$args = new stdClass;
1553
		$args->category_srl = $category_srl;
1554
		$output = executeQuery('document.getCategory', $args);
1555
1556
		$category = $output->data;
1557
		$list_order = $category->list_order;
1558
		$module_srl = $category->module_srl;
1559
		// Seek a full list of categories
1560
		$category_list = $oDocumentModel->getCategoryList($module_srl);
1561
		$category_srl_list = array_keys($category_list);
1562
		if(count($category_srl_list)<2) return new Object();
1563
1564
		for($i=0;$i<count($category_srl_list);$i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1565
		{
1566
			if($category_srl_list[$i]==$category_srl) break;
1567
		}
1568
1569
		$next_category_srl = $category_srl_list[$i+1];
1570
		if(!$category_list[$next_category_srl]) return new Object(-1,Context::getLang('msg_category_not_moved'));
1571
		$next_category = $category_list[$next_category_srl];
1572
		// Information of the selected category
1573
		$cur_args = new stdClass;
1574
		$cur_args->category_srl = $category_srl;
1575
		$cur_args->list_order = $next_category->list_order;
1576
		$cur_args->title = $category->title;
1577
		$this->updateCategory($cur_args);
1578
		// Category information
1579
		$next_args = new stdClass;
1580
		$next_args->category_srl = $next_category->category_srl;
1581
		$next_args->list_order = $list_order;
1582
		$next_args->title = $next_category->title;
1583
		$this->updateCategory($next_args);
1584
1585
		return new Object();
1586
	}
1587
1588
	/**
1589
	 * Add javascript codes into the header by checking values of document_extra_keys type, required and others
1590
	 * @param int $module_srl
1591
	 * @return void
1592
	 */
1593
	function addXmlJsFilter($module_srl)
1594
	{
1595
		$oDocumentModel = getModel('document');
1596
		$extra_keys = $oDocumentModel->getExtraKeys($module_srl);
1597
		if(!count($extra_keys)) return;
1598
1599
		$js_code = array();
1600
		$js_code[] = '<script>//<![CDATA[';
1601
		$js_code[] = '(function($){';
1602
		$js_code[] = 'var validator = xe.getApp("validator")[0];';
1603
		$js_code[] = 'if(!validator) return false;';
1604
1605
		$logged_info = Context::get('logged_info');
0 ignored issues
show
Unused Code introduced by
$logged_info is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1606
1607
		foreach($extra_keys as $idx => $val)
1608
		{
1609
			$idx = $val->idx;
1610
			if($val->type == 'kr_zip')
1611
			{
1612
				$idx .= '[]';
1613
			}
1614
			$name = str_ireplace(array('<script', '</script'), array('<scr" + "ipt', '</scr" + "ipt'), $val->name);
1615
			$js_code[] = sprintf('validator.cast("ADD_MESSAGE", ["extra_vars%s","%s"]);', $idx, $name);
1616
			if($val->is_required == 'Y') $js_code[] = sprintf('validator.cast("ADD_EXTRA_FIELD", ["extra_vars%s", { required:true }]);', $idx);
1617
		}
1618
1619
		$js_code[] = '})(jQuery);';
1620
		$js_code[] = '//]]></script>';
1621
		$js_code   = implode("\n", $js_code);
1622
1623
		Context::addHtmlHeader($js_code);
1624
	}
1625
1626
	/**
1627
	 * Add a category
1628
	 * @param object $args
1629
	 * @return void
1630
	 */
1631
	function procDocumentInsertCategory($args = null)
1632
	{
1633
		// List variables
1634
		if(!$args) $args = Context::gets('module_srl','category_srl','parent_srl','category_title','category_description','expand','group_srls','category_color','mid');
1635
		$args->title = $args->category_title;
1636
		$args->description = $args->category_description;
1637
		$args->color = $args->category_color;
1638
1639
		if(!$args->module_srl && $args->mid)
1640
		{
1641
			$mid = $args->mid;
0 ignored issues
show
Unused Code introduced by
$mid is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1642
			unset($args->mid);
1643
			$args->module_srl = $this->module_srl;
0 ignored issues
show
Bug introduced by
The property module_srl cannot be accessed from this context as it is declared private in class ModuleObject.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1644
		}
1645
		// Check permissions
1646
		$oModuleModel = getModel('module');
1647
		$columnList = array('module_srl', 'module');
1648
		$module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl, $columnList);
1649
		$grant = $oModuleModel->getGrant($module_info, Context::get('logged_info'));
1650
		if(!$grant->manager) return new Object(-1,'msg_not_permitted');
1651
1652
		if($args->expand !="Y") $args->expand = "N";
1653
		if(!is_array($args->group_srls)) $args->group_srls = str_replace('|@|',',',$args->group_srls);
1654
		else $args->group_srls = implode(',', $args->group_srls);
1655
		$args->parent_srl = (int)$args->parent_srl;
1656
1657
		$oDocumentModel = getModel('document');
1658
1659
		$oDB = &DB::getInstance();
1660
		$oDB->begin();
1661
		// Check if already exists
1662
		if($args->category_srl)
1663
		{
1664
			$category_info = $oDocumentModel->getCategory($args->category_srl);
1665
			if($category_info->category_srl != $args->category_srl) $args->category_srl = null;
1666
		}
1667
		// Update if exists
1668
		if($args->category_srl)
1669
		{
1670
			$output = $this->updateCategory($args);
1671
			if(!$output->toBool())
1672
			{
1673
				$oDB->rollback();
1674
				return $output;
1675
			}
1676
			// Insert if not exist
1677
		}
1678
		else
1679
		{
1680
			$output = $this->insertCategory($args);
1681
			if(!$output->toBool())
1682
			{
1683
				$oDB->rollback();
1684
				return $output;
1685
			}
1686
		}
1687
		// Update the xml file and get its location
1688
		$xml_file = $this->makeCategoryFile($args->module_srl);
1689
1690
		$oDB->commit();
1691
1692
		$this->add('xml_file', $xml_file);
1693
		$this->add('module_srl', $args->module_srl);
1694
		$this->add('category_srl', $args->category_srl);
1695
		$this->add('parent_srl', $args->parent_srl);
1696
1697
		$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : Context::get('error_return_url');
1698
		$this->setRedirectUrl($returnUrl);
1699
	}
1700
1701
	/**
1702
	 * Move a category
1703
	 * @return void
1704
	 */
1705
	function procDocumentMoveCategory()
1706
	{
1707
		$source_category_srl = Context::get('source_srl');
1708
		// If parent_srl exists, be the first child
1709
		$parent_category_srl = Context::get('parent_srl');
1710
		// If target_srl exists, be a sibling
1711
		$target_category_srl = Context::get('target_srl');
1712
1713
		$oDocumentModel = getModel('document');
1714
		$source_category = $oDocumentModel->getCategory($source_category_srl);
1715
		// Check permissions
1716
		$oModuleModel = getModel('module');
1717
		$columnList = array('module_srl', 'module');
1718
		$module_info = $oModuleModel->getModuleInfoByModuleSrl($source_category->module_srl, $columnList);
1719
		$grant = $oModuleModel->getGrant($module_info, Context::get('logged_info'));
1720
		if(!$grant->manager) return new Object(-1,'msg_not_permitted');
1721
1722
		// First child of the parent_category_srl
1723
		$source_args = new stdClass;
1724
		if($parent_category_srl > 0 || ($parent_category_srl == 0 && $target_category_srl == 0))
1725
		{
1726
			$parent_category = $oDocumentModel->getCategory($parent_category_srl);
0 ignored issues
show
Unused Code introduced by
$parent_category is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1727
1728
			$args = new stdClass;
1729
			$args->module_srl = $source_category->module_srl;
1730
			$args->parent_srl = $parent_category_srl;
1731
			$output = executeQuery('document.getChildCategoryMinListOrder', $args);
1732
1733
			if(!$output->toBool()) return $output;
1734
			$args->list_order = (int)$output->data->list_order;
1735
			if(!$args->list_order) $args->list_order = 0;
1736
			$args->list_order--;
1737
1738
			$source_args->category_srl = $source_category_srl;
1739
			$source_args->parent_srl = $parent_category_srl;
1740
			$source_args->list_order = $args->list_order;
1741
			$output = $this->updateCategory($source_args);
1742
			if(!$output->toBool()) return $output;
1743
			// Sibling of the $target_category_srl
1744
		}
1745
		else if($target_category_srl > 0)
1746
		{
1747
			$target_category = $oDocumentModel->getCategory($target_category_srl);
1748
			// Move all siblings of the $target_category down
1749
			$output = $this->updateCategoryListOrder($target_category->module_srl, $target_category->list_order+1);
1750
			if(!$output->toBool()) return $output;
1751
1752
			$source_args->category_srl = $source_category_srl;
1753
			$source_args->parent_srl = $target_category->parent_srl;
1754
			$source_args->list_order = $target_category->list_order+1;
1755
			$output = $this->updateCategory($source_args);
1756
			if(!$output->toBool()) return $output;
1757
		}
1758
		// Re-generate the xml file
1759
		$xml_file = $this->makeCategoryFile($source_category->module_srl);
1760
		// Variable settings
1761
		$this->add('xml_file', $xml_file);
1762
		$this->add('source_category_srl', $source_category_srl);
1763
	}
1764
1765
	/**
1766
	 * Delete a category
1767
	 * @return void
1768
	 */
1769
	function procDocumentDeleteCategory()
1770
	{
1771
		// List variables
1772
		$args = Context::gets('module_srl','category_srl');
1773
1774
		$oDB = &DB::getInstance();
1775
		$oDB->begin();
1776
		// Check permissions
1777
		$oModuleModel = getModel('module');
1778
		$columnList = array('module_srl', 'module');
1779
		$module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl, $columnList);
1780
		$grant = $oModuleModel->getGrant($module_info, Context::get('logged_info'));
1781
		if(!$grant->manager) return new Object(-1,'msg_not_permitted');
1782
1783
		$oDocumentModel = getModel('document');
1784
		// Get original information
1785
		$category_info = $oDocumentModel->getCategory($args->category_srl);
1786
		if($category_info->parent_srl) $parent_srl = $category_info->parent_srl;
1787
		// Display an error that the category cannot be deleted if it has a child node
1788
		if($oDocumentModel->getCategoryChlidCount($args->category_srl)) return new Object(-1, 'msg_cannot_delete_for_child');
1789
		// Remove from the DB
1790
		$output = $this->deleteCategory($args->category_srl);
1791
		if(!$output->toBool())
1792
		{
1793
			$oDB->rollback();
1794
			return $output;
1795
		}
1796
		// Update the xml file and get its location
1797
		$xml_file = $this->makeCategoryFile($args->module_srl);
1798
1799
		$oDB->commit();
1800
1801
		$this->add('xml_file', $xml_file);
1802
		$this->add('category_srl', $parent_srl);
0 ignored issues
show
Bug introduced by
The variable $parent_srl does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1803
		$this->setMessage('success_deleted');
1804
	}
1805
1806
	/**
1807
	 * Xml files updated
1808
	 * Occasionally the xml file is not generated after menu is configued on the admin page \n
1809
	 * The administrator can manually update the file in this case \n
1810
	 * Although the issue is not currently reproduced, it is unnecessay to remove.
1811
	 * @return void
1812
	 */
1813
	function procDocumentMakeXmlFile()
1814
	{
1815
		// Check input values
1816
		$module_srl = Context::get('module_srl');
1817
		// Check permissions
1818
		$oModuleModel = getModel('module');
1819
		$columnList = array('module_srl', 'module');
1820
		$module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl, $columnList);
1821
		$grant = $oModuleModel->getGrant($module_info, Context::get('logged_info'));
1822
		if(!$grant->manager) return new Object(-1,'msg_not_permitted');
1823
1824
		$xml_file = $this->makeCategoryFile($module_srl);
1825
		// Set return value
1826
		$this->add('xml_file',$xml_file);
1827
	}
1828
1829
	/**
1830
	 * Save the category in a cache file
1831
	 * @param int $module_srl
1832
	 * @return string
1833
	 */
1834
	function makeCategoryFile($module_srl)
1835
	{
1836
		// Return if there is no information you need for creating a cache file
1837
		if(!$module_srl) return false;
1838
		// Get module information (to obtain mid)
1839
		$oModuleModel = getModel('module');
1840
		$columnList = array('module_srl', 'mid', 'site_srl');
1841
		$module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl, $columnList);
1842
		$mid = $module_info->mid;
1843
1844
		if(!is_dir('./files/cache/document_category')) FileHandler::makeDir('./files/cache/document_category');
1845
		// Cache file's name
1846
		$xml_file = sprintf("./files/cache/document_category/%s.xml.php", $module_srl);
1847
		$php_file = sprintf("./files/cache/document_category/%s.php", $module_srl);
1848
		// Get a category list
1849
		$args = new stdClass();
1850
		$args->module_srl = $module_srl;
1851
		$args->sort_index = 'list_order';
1852
		$output = executeQueryArray('document.getCategoryList', $args);
1853
1854
		$category_list = $output->data;
1855
1856
		if(!is_array($category_list)) $category_list = array($category_list);
1857
1858
		$category_count = count($category_list);
1859
		for($i=0;$i<$category_count;$i++)
1860
		{
1861
			$category_srl = $category_list[$i]->category_srl;
1862
			if(!preg_match('/^[0-9,]+$/', $category_list[$i]->group_srls)) $category_list[$i]->group_srls = '';
1863
			$list[$category_srl] = $category_list[$i];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$list was never initialized. Although not strictly required by PHP, it is generally a good practice to add $list = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1864
		}
1865
		// Create the xml file without node data if no data is obtained
1866 View Code Duplication
		if(!$list)
0 ignored issues
show
Bug introduced by
The variable $list does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug Best Practice introduced by
The expression $list of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1867
		{
1868
			$xml_buff = "<root />";
1869
			FileHandler::writeFile($xml_file, $xml_buff);
1870
			FileHandler::writeFile($php_file, '<?php if(!defined("__XE__")) exit(); ?>');
1871
			return $xml_file;
1872
		}
1873
		// Change to an array if only a single data is obtained
1874
		if(!is_array($list)) $list = array($list);
1875
		// Create a tree for loop
1876
		foreach($list as $category_srl => $node)
1877
		{
1878
			$node->mid = $mid;
1879
			$parent_srl = (int)$node->parent_srl;
1880
			$tree[$parent_srl][$category_srl] = $node;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$tree was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tree = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1881
		}
1882
		// A common header to set permissions and groups of the cache file
1883
		$header_script =
1884
			'$lang_type = Context::getLangType(); '.
1885
			'$is_logged = Context::get(\'is_logged\'); '.
1886
			'$logged_info = Context::get(\'logged_info\'); '.
1887
			'if($is_logged) {'.
1888
			'if($logged_info->is_admin=="Y") $is_admin = true; '.
1889
			'else $is_admin = false; '.
1890
			'$group_srls = array_keys($logged_info->group_list); '.
1891
			'} else { '.
1892
			'$is_admin = false; '.
1893
			'$group_srsl = array(); '.
1894
			'} '."\n";
1895
1896
		// Create the xml cache file (a separate session is needed for xml cache)
1897
		$xml_header_buff = '';
1898
		$xml_body_buff = $this->getXmlTree($tree[0], $tree, $module_info->site_srl, $xml_header_buff);
0 ignored issues
show
Bug introduced by
The variable $tree does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1899
		$xml_buff = sprintf(
1900
			'<?php '.
1901
			'define(\'__XE__\', true); '.
1902
			'require_once(\''.FileHandler::getRealPath('./config/config.inc.php').'\'); '.
1903
			'$oContext = &Context::getInstance(); '.
1904
			'$oContext->init(); '.
1905
			'header("Content-Type: text/xml; charset=UTF-8"); '.
1906
			'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '.
1907
			'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '.
1908
			'header("Cache-Control: no-store, no-cache, must-revalidate"); '.
1909
			'header("Cache-Control: post-check=0, pre-check=0", false); '.
1910
			'header("Pragma: no-cache"); '.
1911
			'%s'.
1912
			'%s '.
1913
			'$oContext->close();'.
1914
			'?>'.
1915
			'<root>%s</root>',
1916
			$header_script,
1917
			$xml_header_buff,
1918
			$xml_body_buff
1919
		);
1920
		// Create php cache file
1921
		$php_header_buff = '$_titles = array();';
1922
		$php_header_buff .= '$_descriptions = array();';
1923
		$php_output = $this->getPhpCacheCode($tree[0], $tree, $module_info->site_srl, $php_header_buff);
1924
		$php_buff = sprintf(
1925
			'<?php '.
1926
			'if(!defined("__XE__")) exit(); '.
1927
			'%s'.
1928
			'%s'.
1929
			'$menu = new stdClass;'.
1930
			'$menu->list = array(%s); ',
1931
			$header_script,
1932
			$php_header_buff,
1933
			$php_output['buff']
1934
		);
1935
		// Save File
1936
		FileHandler::writeFile($xml_file, $xml_buff);
1937
		FileHandler::writeFile($php_file, $php_buff);
1938
		return $xml_file;
1939
	}
1940
1941
	/**
1942
	 * Create the xml data recursively referring to parent_srl
1943
	 * In the menu xml file, node tag is nested and xml doc enables the admin page to have a menu\n
1944
	 * (tree menu is implemented by reading xml file from the tree_menu.js)
1945
	 * @param array $source_node
1946
	 * @param array $tree
1947
	 * @param int $site_srl
1948
	 * @param string $xml_header_buff
1949
	 * @return string
1950
	 */
1951
	function getXmlTree($source_node, $tree, $site_srl, &$xml_header_buff)
1952
	{
1953
		if(!$source_node) return;
0 ignored issues
show
Bug Best Practice introduced by
The expression $source_node of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1954
1955
		foreach($source_node as $category_srl => $node)
1956
		{
1957
			$child_buff = "";
1958
			// Get data of the child nodes
1959
			if($category_srl && $tree[$category_srl]) $child_buff = $this->getXmlTree($tree[$category_srl], $tree, $site_srl, $xml_header_buff);
1960
			// List variables
1961
			$expand = $node->expand;
1962
			$group_srls = $node->group_srls;
1963
			$mid = $node->mid;
1964
			$module_srl = $node->module_srl;
1965
			$parent_srl = $node->parent_srl;
1966
			$color = $node->color;
1967
			$description = $node->description;
1968
			// If node->group_srls value exists
1969
			if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls);
1970
			else $group_check_code = "true";
1971
1972
			$title = $node->title;
1973
			$oModuleAdminModel = getAdminModel('module');
1974
1975
			$langs = $oModuleAdminModel->getLangCode($site_srl, $title);
1976
			if(count($langs))
1977
			{
1978
				foreach($langs as $key => $val)
1979
				{
1980
					$xml_header_buff .= sprintf('$_titles[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false)));
1981
				}
1982
			}
1983
1984
			$langx = $oModuleAdminModel->getLangCode($site_srl, $description);
1985
			if(count($langx))
1986
			{
1987
				foreach($langx as $key => $val)
1988
				{
1989
					$xml_header_buff .= sprintf('$_descriptions[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false)));
1990
				}
1991
			}
1992
1993
			$attribute = sprintf(
1994
				'mid="%s" module_srl="%d" node_srl="%d" parent_srl="%d" category_srl="%d" text="<?php echo (%s?($_titles[%d][$lang_type]):"")?>" url="%s" expand="%s" color="%s" description="<?php echo (%s?($_descriptions[%d][$lang_type]):"")?>" document_count="%d" ',
1995
				$mid,
1996
				$module_srl,
1997
				$category_srl,
1998
				$parent_srl,
1999
				$category_srl,
2000
				$group_check_code,
2001
				$category_srl,
2002
				getUrl('','mid',$node->mid,'category',$category_srl),
2003
				$expand,
2004
				htmlspecialchars($color, ENT_COMPAT | ENT_HTML401, 'UTF-8', false),
2005
				$group_check_code,
2006
				$category_srl,
2007
				$node->document_count
2008
			);
2009
2010 View Code Duplication
			if($child_buff) $buff .= sprintf('<node %s>%s</node>', $attribute, $child_buff);
0 ignored issues
show
Bug introduced by
The variable $buff does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2011
			else $buff .=  sprintf('<node %s />', $attribute);
2012
		}
2013
		return $buff;
2014
	}
2015
2016
	/**
2017
	 * Change sorted nodes in an array to the php code and then return
2018
	 * When using menu on tpl, you can directly xml data. howver you may need javascrips additionally.
2019
	 * Therefore, you can configure the menu info directly from php cache file, not through DB.
2020
	 * You may include the cache in the ModuleHandler::displayContent()
2021
	 * @param array $source_node
2022
	 * @param array $tree
2023
	 * @param int $site_srl
2024
	 * @param string $php_header_buff
2025
	 * @return array
2026
	 */
2027
	function getPhpCacheCode($source_node, $tree, $site_srl, &$php_header_buff)
2028
	{
2029
		$output = array("buff"=>"", "category_srl_list"=>array());
2030
		if(!$source_node) return $output;
0 ignored issues
show
Bug Best Practice introduced by
The expression $source_node of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
2031
2032
		// Set to an arraty for looping and then generate php script codes to be included
2033
		foreach($source_node as $category_srl => $node)
2034
		{
2035
			// Get data from child nodes first if exist.
2036
			if($category_srl && $tree[$category_srl]){
2037
				$child_output = $this->getPhpCacheCode($tree[$category_srl], $tree, $site_srl, $php_header_buff);
2038
			} else {
2039
				$child_output = array("buff"=>"", "category_srl_list"=>array());
2040
			}
2041
2042
			// Set values into category_srl_list arrary if url of the current node is not empty
2043
			$child_output['category_srl_list'][] = $node->category_srl;
2044
			$output['category_srl_list'] = array_merge($output['category_srl_list'], $child_output['category_srl_list']);
2045
2046
			// If node->group_srls value exists
2047
			if($node->group_srls) {
2048
				$group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls);
2049
			} else {
2050
				$group_check_code = "true";
2051
			}
2052
2053
			// List variables
2054
			$selected = '"' . implode('","', $child_output['category_srl_list']) . '"';
2055
			$child_buff = $child_output['buff'];
2056
			$expand = $node->expand;
2057
2058
			$title = $node->title;
2059
			$description = $node->description;
2060
			$oModuleAdminModel = getAdminModel('module');
2061
			$langs = $oModuleAdminModel->getLangCode($site_srl, $title);
2062
2063 View Code Duplication
			if(count($langs))
2064
			{
2065
				foreach($langs as $key => $val)
2066
				{
2067
					$val = htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
2068
					$php_header_buff .= sprintf(
2069
						'$_titles[%d]["%s"] = "%s"; ',
2070
						$category_srl,
2071
						$key,
2072
						str_replace('"','\\"', $val)
2073
					);
2074
				}
2075
			}
2076
2077
			$langx = $oModuleAdminModel->getLangCode($site_srl, $description);
2078
2079 View Code Duplication
			if(count($langx))
2080
			{
2081
				foreach($langx as $key => $val)
2082
				{
2083
					$val = htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
2084
					$php_header_buff .= sprintf(
2085
						'$_descriptions[%d]["%s"] = "%s"; ',
2086
						$category_srl,
2087
						$key,
2088
						str_replace('"','\\"', $val)
2089
					);
2090
				}
2091
			}
2092
2093
			// Create attributes(Use the category_srl_list to check whether to belong to the menu's node. It seems to be tricky but fast fast and powerful;)
2094
			$attribute = sprintf(
2095
				'"mid" => "%s", "module_srl" => "%d","node_srl"=>"%s","category_srl"=>"%s","parent_srl"=>"%s","text"=>$_titles[%d][$lang_type],"selected"=>(in_array(Context::get("category"),array(%s))?1:0),"expand"=>"%s","color"=>"%s","description"=>$_descriptions[%d][$lang_type],"list"=>array(%s),"document_count"=>"%d","grant"=>%s?true:false',
2096
				$node->mid,
2097
				$node->module_srl,
2098
				$node->category_srl,
2099
				$node->category_srl,
2100
				$node->parent_srl,
2101
				$node->category_srl,
2102
				$selected,
2103
				$expand,
2104
				$node->color,
2105
				$node->category_srl,
2106
				$child_buff,
2107
				$node->document_count,
2108
				$group_check_code
2109
			);
2110
2111
			// Generate buff data
2112
			$output['buff'] .=  sprintf('%s=>array(%s),', $node->category_srl, $attribute);
2113
		}
2114
2115
		return $output;
2116
	}
2117
2118
	/**
2119
	 * A method to add a pop-up menu which appears when clicking
2120
	 * @param string $url
2121
	 * @param string $str
2122
	 * @param string $icon
2123
	 * @param string $target
2124
	 * @return void
2125
	 */
2126 View Code Duplication
	function addDocumentPopupMenu($url, $str, $icon = '', $target = 'self')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2127
	{
2128
		$document_popup_menu_list = Context::get('document_popup_menu_list');
2129
		if(!is_array($document_popup_menu_list)) $document_popup_menu_list = array();
2130
2131
		$obj = new stdClass();
2132
		$obj->url = $url;
2133
		$obj->str = $str;
2134
		$obj->icon = $icon;
2135
		$obj->target = $target;
2136
		$document_popup_menu_list[] = $obj;
2137
2138
		Context::set('document_popup_menu_list', $document_popup_menu_list);
0 ignored issues
show
Documentation introduced by
$document_popup_menu_list is of type array<integer,object<stdClass>>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2139
	}
2140
2141
	/**
2142
	 * Saved in the session when an administrator selects a post
2143
	 * @return void|Object
2144
	 */
2145
	function procDocumentAddCart()
2146
	{
2147
		if(!Context::get('is_logged')) return new Object(-1, 'msg_not_permitted');
2148
2149
		// Get document_srl
2150
		$srls = explode(',',Context::get('srls'));
2151
		for($i = 0; $i < count($srls); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2152
		{
2153
			$srl = trim($srls[$i]);
2154
2155
			if(!$srl) continue;
2156
2157
			$document_srls[] = $srl;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$document_srls was never initialized. Although not strictly required by PHP, it is generally a good practice to add $document_srls = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2158
		}
2159
		if(!count($document_srls)) return;
0 ignored issues
show
Bug introduced by
The variable $document_srls does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2160
2161
		// Get module_srl of the documents
2162
		$args = new stdClass;
2163
		$args->list_count = count($document_srls);
2164
		$args->document_srls = implode(',',$document_srls);
2165
		$args->order_type = 'asc';
2166
		$output = executeQueryArray('document.getDocuments', $args);
2167
		if(!$output->data) return new Object();
2168
2169
		unset($document_srls);
2170
		foreach($output->data as $key => $val)
2171
		{
2172
			$document_srls[$val->module_srl][] = $val->document_srl;
2173
		}
2174
		if(!$document_srls || !count($document_srls)) return new Object();
0 ignored issues
show
Bug Best Practice introduced by
The expression $document_srls of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
2175
2176
		// Check if each of module administrators exists. Top-level administator will have a permission to modify every document of all modules.(Even to modify temporarily saved or trashed documents)
2177
		$oModuleModel = getModel('module');
2178
		$module_srls = array_keys($document_srls);
2179
		for($i=0;$i<count($module_srls);$i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2180
		{
2181
			$module_srl = $module_srls[$i];
2182
			$module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl);
2183
			$logged_info = Context::get('logged_info');
2184
			if($logged_info->is_admin != 'Y')
2185
			{
2186
				if(!$module_info)
2187
				{
2188
					unset($document_srls[$module_srl]);
2189
					continue;
2190
				}
2191
				$grant = $oModuleModel->getGrant($module_info, $logged_info);
2192
				if(!$grant->manager)
2193
				{
2194
					unset($document_srls[$module_srl]);
2195
					continue;
2196
				}
2197
			}
2198
		}
2199
		if(!count($document_srls)) return new Object();
2200
2201
		foreach($document_srls as $module_srl => $documents)
2202
		{
2203
			$cnt = count($documents);
2204
			for($i=0;$i<$cnt;$i++)
2205
			{
2206
				$document_srl = (int)trim($documents[$i]);
2207
				if(!$document_srls) continue;
0 ignored issues
show
Bug Best Practice introduced by
The expression $document_srls of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
2208
				if($_SESSION['document_management'][$document_srl]) unset($_SESSION['document_management'][$document_srl]);
2209
				else $_SESSION['document_management'][$document_srl] = true;
2210
			}
2211
		}
2212
	}
2213
2214
	/**
2215
	 * Move/ Delete the document in the seession
2216
	 * @return void|Object
2217
	 */
2218
	function procDocumentManageCheckedDocument()
2219
	{
2220
		@set_time_limit(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2221
		if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted');
2222
2223
		if(!checkCSRF())
2224
		{
2225
			return new Object(-1, 'msg_invalid_request');
2226
		}
2227
2228
		$type = Context::get('type');
2229
		$target_module = Context::get('target_module');
2230
		$module_srl = Context::get('module_srl');
2231
		if($target_module && !$module_srl) $module_srl = $target_module;
2232
		$category_srl = Context::get('target_category');
2233
		$message_content = Context::get('message_content');
2234
		if($message_content) $message_content = nl2br($message_content);
2235
2236
		$cart = Context::get('cart');
2237
		if(!is_array($cart)) $document_srl_list = explode('|@|', $cart);
2238
		else $document_srl_list = $cart;
2239
2240
		$document_srl_count = count($document_srl_list);
2241
2242
		$oDocumentModel = getModel('document');
2243
		$document_items = array();
2244
		foreach($document_srl_list as $document_srl)
2245
		{
2246
			$oDocument = $oDocumentModel->getDocument($document_srl);
2247
			$document_items[] = $oDocument;
2248
			if(!$oDocument->isGranted()) return $this->stop('msg_not_permitted');
2249
		}
2250
2251
		// Send a message
2252
		if($message_content)
2253
		{
2254
2255
			$oCommunicationController = getController('communication');
2256
2257
			$logged_info = Context::get('logged_info');
2258
2259
			$title = cut_str($message_content,10,'...');
2260
			$sender_member_srl = $logged_info->member_srl;
2261
2262
			foreach($document_items as $oDocument)
2263
			{
2264
				if(!$oDocument->get('member_srl') || $oDocument->get('member_srl')==$sender_member_srl) continue;
2265
2266
				if($type=='move') $purl = sprintf("<a href=\"%s\" onclick=\"window.open(this.href);return false;\">%s</a>", $oDocument->getPermanentUrl(), $oDocument->getPermanentUrl());
2267
				else $purl = "";
2268
				$content = sprintf("<div>%s</div><hr />%s<div style=\"font-weight:bold\">%s</div>%s",$message_content, $purl, $oDocument->getTitleText(), $oDocument->getContent(false, false, false));
2269
2270
				$oCommunicationController->sendMessage($sender_member_srl, $oDocument->get('member_srl'), $title, $content, false);
2271
			}
2272
		}
2273
		// Set a spam-filer not to be filtered to spams
2274
		$oSpamController = getController('spamfilter');
2275
		$oSpamController->setAvoidLog();
2276
2277
		$oDocumentAdminController = getAdminController('document');
2278
		if($type == 'move')
2279
		{
2280
			if(!$module_srl) return new Object(-1, 'fail_to_move');
2281
2282
			$output = $oDocumentAdminController->moveDocumentModule($document_srl_list, $module_srl, $category_srl);
2283
			if(!$output->toBool()) return new Object(-1, 'fail_to_move');
2284
2285
			$msg_code = 'success_moved';
2286
2287
		}
2288
		else if($type == 'copy')
2289
		{
2290
			if(!$module_srl) return new Object(-1, 'fail_to_move');
2291
2292
			$output = $oDocumentAdminController->copyDocumentModule($document_srl_list, $module_srl, $category_srl);
2293
			if(!$output->toBool()) return new Object(-1, 'fail_to_move');
2294
2295
			$msg_code = 'success_copied';
2296
		}
2297
		else if($type =='delete')
2298
		{
2299
			$oDB = &DB::getInstance();
2300
			$oDB->begin();
2301 View Code Duplication
			for($i=0;$i<$document_srl_count;$i++)
2302
			{
2303
				$document_srl = $document_srl_list[$i];
2304
				$output = $this->deleteDocument($document_srl, true);
2305
				if(!$output->toBool()) return new Object(-1, 'fail_to_delete');
2306
			}
2307
			$oDB->commit();
2308
			$msg_code = 'success_deleted';
2309
		}
2310
		else if($type == 'trash')
2311
		{
2312
			$args = new stdClass();
2313
			$args->description = $message_content;
2314
2315
			$oDB = &DB::getInstance();
2316
			$oDB->begin();
2317 View Code Duplication
			for($i=0;$i<$document_srl_count;$i++) {
2318
				$args->document_srl = $document_srl_list[$i];
2319
				$output = $this->moveDocumentToTrash($args);
2320
				if(!$output || !$output->toBool()) return new Object(-1, 'fail_to_trash');
2321
			}
2322
			$oDB->commit();
2323
			$msg_code = 'success_trashed';
2324
		}
2325
		else if($type == 'cancelDeclare')
2326
		{
2327
			$args->document_srl = $document_srl_list;
0 ignored issues
show
Bug introduced by
The variable $args seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
2328
			$output = executeQuery('document.deleteDeclaredDocuments', $args);
0 ignored issues
show
Bug introduced by
The variable $args seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2329
			$msg_code = 'success_declare_canceled';
2330
		}
2331
2332
		$_SESSION['document_management'] = array();
2333
2334
		$this->setMessage($msg_code);
0 ignored issues
show
Bug introduced by
The variable $msg_code does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2335
2336
		$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispDocumentAdminList');
2337
		$this->setRedirectUrl($returnUrl);
2338
	}
2339
2340
	/**
2341
	 * Insert document module config
2342
	 * @return void
2343
	 */
2344
	function procDocumentInsertModuleConfig()
2345
	{
2346
		$module_srl = Context::get('target_module_srl');
2347 View Code Duplication
		if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl);
2348
		else $module_srl = array($module_srl);
2349
2350
		$document_config = new stdClass();
2351
		$document_config->use_history = Context::get('use_history');
2352
		if(!$document_config->use_history) $document_config->use_history = 'N';
2353
2354
		$document_config->use_vote_up = Context::get('use_vote_up');
2355
		if(!$document_config->use_vote_up) $document_config->use_vote_up = 'Y';
2356
2357
		$document_config->use_vote_down = Context::get('use_vote_down');
2358
		if(!$document_config->use_vote_down) $document_config->use_vote_down = 'Y';
2359
2360
		$document_config->use_status = Context::get('use_status');
2361
2362
		$oModuleController = getController('module');
2363 View Code Duplication
		for($i=0;$i<count($module_srl);$i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2364
		{
2365
			$srl = trim($module_srl[$i]);
2366
			if(!$srl) continue;
2367
			$output = $oModuleController->insertModulePartConfig('document',$srl,$document_config);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2368
		}
2369
		$this->setError(-1);
2370
		$this->setMessage('success_updated', 'info');
2371
2372
		$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispBoardAdminContent');
2373
		$this->setRedirectUrl($returnUrl);
2374
	}
2375
2376
	/**
2377
	 * Document temporary save
2378
	 * @return void|Object
2379
	 */
2380
	function procDocumentTempSave()
2381
	{
2382
		// Check login information
2383
		if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged');
2384
		$module_info = Context::get('module_info');
2385
		$logged_info = Context::get('logged_info');
0 ignored issues
show
Unused Code introduced by
$logged_info is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2386
2387
		// Get form information
2388
		$obj = Context::getRequestVars();
2389
		// Change the target module to log-in information
2390
		$obj->module_srl = $module_info->module_srl;
2391
		$obj->status = $this->getConfigStatus('temp');
2392
		unset($obj->is_notice);
2393
2394
		// Extract from beginning part of contents in the guestbook
2395
		if(!$obj->title)
2396
		{
2397
			$obj->title = cut_str(strip_tags($obj->content), 20, '...');
2398
		}
2399
2400
		$oDocumentModel = getModel('document');
2401
		$oDocumentController = getController('document');
2402
		// Check if already exist geulinji
2403
		$oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager);
0 ignored issues
show
Bug introduced by
The property grant does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
2404
2405
		// Update if already exists
2406
		if($oDocument->isExists() && $oDocument->document_srl == $obj->document_srl)
2407
		{
2408
			if($oDocument->get('module_srl') != $obj->module_srl)
2409
			{
2410
				return new Object(-1, 'msg_invalid_request');
2411
			}
2412
			if(!$oDocument->isGranted())
2413
			{
2414
				return new Object(-1, 'msg_invalid_request');
2415
			}
2416
			//if exist document status is already public, use temp status can point problem
2417
			$obj->status = $oDocument->get('status');
2418
			$output = $oDocumentController->updateDocument($oDocument, $obj);
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2419
			$msg_code = 'success_updated';
0 ignored issues
show
Unused Code introduced by
$msg_code is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2420
			// Otherwise, get a new
2421
		}
2422
		else
2423
		{
2424
			$output = $oDocumentController->insertDocument($obj);
2425
			$msg_code = 'success_registed';
0 ignored issues
show
Unused Code introduced by
$msg_code is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2426
			$obj->document_srl = $output->get('document_srl');
2427
			$oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager);
2428
		}
2429
		// Set the attachment to be invalid state
2430 View Code Duplication
		if($oDocument->hasUploadedFiles())
2431
		{
2432
			$args = new stdClass;
2433
			$args->upload_target_srl = $oDocument->document_srl;
2434
			$args->isvalid = 'N';
2435
			executeQuery('file.updateFileValid', $args);
2436
		}
2437
2438
		$this->setMessage('success_saved');
2439
		$this->add('document_srl', $obj->document_srl);
2440
	}
2441
2442
	/**
2443
	 * Return Document List for exec_xml
2444
	 * @return void|Object
2445
	 */
2446
	function procDocumentGetList()
2447
	{
2448
		if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted');
2449
		$documentSrls = Context::get('document_srls');
2450
		if($documentSrls) $documentSrlList = explode(',', $documentSrls);
2451
2452
		if(count($documentSrlList) > 0)
2453
		{
2454
			$oDocumentModel = getModel('document');
2455
			$columnList = array('document_srl', 'title', 'nick_name', 'status');
2456
			$documentList = $oDocumentModel->getDocuments($documentSrlList, $this->grant->is_admin, false, $columnList);
0 ignored issues
show
Bug introduced by
The variable $documentSrlList does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2457
		}
2458
		else
2459
		{
2460
			global $lang;
2461
			$documentList = array();
2462
			$this->setMessage($lang->no_documents);
2463
		}
2464
		$oSecurity = new Security($documentList);
2465
		$oSecurity->encodeHTML('..variables.');
2466
		$this->add('document_list', $documentList);
2467
	}
2468
2469
	/**
2470
	 * For old version, comment allow status check.
2471
	 * @param object $obj
2472
	 * @return void
2473
	 */
2474
	function _checkCommentStatusForOldVersion(&$obj)
2475
	{
2476
		if(!isset($obj->allow_comment)) $obj->allow_comment = 'N';
2477
		if(!isset($obj->lock_comment)) $obj->lock_comment = 'N';
2478
2479
		if($obj->allow_comment == 'Y' && $obj->lock_comment == 'N') $obj->commentStatus = 'ALLOW';
2480
		else $obj->commentStatus = 'DENY';
2481
	}
2482
2483
	/**
2484
	 * For old version, document status check.
2485
	 * @param object $obj
2486
	 * @return void
2487
	 */
2488
	function _checkDocumentStatusForOldVersion(&$obj)
2489
	{
2490
		if(!$obj->status && $obj->is_secret == 'Y') $obj->status = $this->getConfigStatus('secret');
2491
		if(!$obj->status && $obj->is_secret != 'Y') $obj->status = $this->getConfigStatus('public');
2492
	}
2493
2494
	public function updateUploaedCount($documentSrlList)
2495
	{
2496
		$oDocumentModel = getModel('document');
0 ignored issues
show
Unused Code introduced by
$oDocumentModel is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2497
		$oFileModel = getModel('file');
2498
2499
		if(is_array($documentSrlList))
2500
		{
2501
			$documentSrlList = array_unique($documentSrlList);
2502
			foreach($documentSrlList AS $key => $documentSrl)
2503
			{
2504
				$fileCount = $oFileModel->getFilesCount($documentSrl);
2505
				$args = new stdClass();
2506
				$args->document_srl = $documentSrl;
2507
				$args->uploaded_count = $fileCount;
2508
				executeQuery('document.updateUploadedCount', $args);
2509
			}
2510
		}
2511
	}
2512
2513
	/**
2514
	 * Copy extra keys when module copied
2515
	 * @param object $obj
2516
	 * @return void
2517
	 */
2518
	function triggerCopyModuleExtraKeys(&$obj)
2519
	{
2520
		$oDocumentModel = getModel('document');
2521
		$documentExtraKeys = $oDocumentModel->getExtraKeys($obj->originModuleSrl);
2522
2523
		if(is_array($documentExtraKeys) && is_array($obj->moduleSrlList))
2524
		{
2525
			$oDocumentController=getController('document');
2526
			foreach($obj->moduleSrlList AS $key=>$value)
2527
			{
2528 View Code Duplication
				foreach($documentExtraKeys AS $extraItem)
2529
				{
2530
					$oDocumentController->insertDocumentExtraKey($value, $extraItem->idx, $extraItem->name, $extraItem->type, $extraItem->is_required , $extraItem->search , $extraItem->default , $extraItem->desc, $extraItem->eid) ;
2531
				}
2532
			}
2533
		}
2534
	}
2535
2536 View Code Duplication
	function triggerCopyModule(&$obj)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2537
	{
2538
		$oModuleModel = getModel('module');
2539
		$documentConfig = $oModuleModel->getModulePartConfig('document', $obj->originModuleSrl);
2540
2541
		$oModuleController = getController('module');
2542
		if(is_array($obj->moduleSrlList))
2543
		{
2544
			foreach($obj->moduleSrlList AS $key=>$moduleSrl)
2545
			{
2546
				$oModuleController->insertModulePartConfig('document', $moduleSrl, $documentConfig);
2547
			}
2548
		}
2549
	}
2550
}
2551
/* End of file document.controller.php */
2552
/* Location: ./modules/document/document.controller.php */
2553