*/ /** * documentController class * document the module's controller class * * @author NAVER (developers@xpressengine.com) * @package /modules/document * @version 0.1 */ class documentController extends document { /** * Initialization * @return void */ function init() { } /** * Action to handle vote-up of the post (Up) * @return Object */ function procDocumentVoteUp() { $document_srl = Context::get('target_srl'); if(!$document_srl) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } $module_info = $this->module_info; if(!$module_info->module_srl) { $module_info = ModuleModel::getModuleInfoByDocumentSrl($document_srl); } if($module_info->non_login_vote !== 'Y') { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\NotPermitted; } } $oDocument = DocumentModel::getDocument($document_srl, false, false); $module_srl = $oDocument->get('module_srl'); if(!$module_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest; $document_config = ModuleModel::getModulePartConfig('document',$module_srl); if($document_config->use_vote_up=='N') throw new Rhymix\Framework\Exceptions\FeatureDisabled; $point = 1; $output = $this->updateVotedCount($document_srl, $point); if(!$output->toBool()) { return $output; } $this->add('voted_count', $output->get('voted_count')); return $output; } function procDocumentVoteUpCancel() { $document_srl = Context::get('target_srl'); if(!$document_srl) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } $module_info = $this->module_info; if(!$module_info->module_srl) { $module_info = ModuleModel::getModuleInfoByDocumentSrl($document_srl); } if($module_info->non_login_vote !== 'Y') { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\NotPermitted; } } if($module_info->cancel_vote !== 'Y') { throw new Rhymix\Framework\Exception('failed_voted_cancel'); } $oDocument = DocumentModel::getDocument($document_srl, false, false); if($oDocument->get('voted_count') <= 0) { throw new Rhymix\Framework\Exception('failed_voted_canceled'); } $point = 1; $output = $this->updateVotedCountCancel($document_srl, $oDocument, $point); if(!$output->toBool()) { return $output; } $output = new BaseObject(); $output->setMessage('success_voted_canceled'); return $output; } /** * insert alias * @param int $module_srl * @param int $document_srl * @param string $alias_title * @return object */ function insertAlias($module_srl, $document_srl, $alias_title) { $args = new stdClass; $args->alias_srl = getNextSequence(); $args->module_srl = $module_srl; $args->document_srl = $document_srl; $args->alias_title = urldecode($alias_title); $query = "document.insertAlias"; $output = executeQuery($query, $args); return $output; } /** * Action to handle vote-up of the post (Down) * @return Object */ function procDocumentVoteDown() { if($this->module_info->non_login_vote !== 'Y') { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\NotPermitted; } } $document_srl = Context::get('target_srl'); if(!$document_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest; $oDocument = DocumentModel::getDocument($document_srl, false, false); $module_srl = $oDocument->get('module_srl'); if(!$module_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest; $document_config = ModuleModel::getModulePartConfig('document',$module_srl); if($document_config->use_vote_down=='N') throw new Rhymix\Framework\Exceptions\FeatureDisabled; $point = -1; $output = $this->updateVotedCount($document_srl, $point); if(!$output->toBool()) { return $output; } $this->add('blamed_count', $output->get('blamed_count')); return $output; } function procDocumentVoteDownCancel() { if($this->module_info->non_login_vote !== 'Y') { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\NotPermitted; } } if($this->module_info->cancel_vote !== 'Y') { return new Rhymix\Framework\Exception('failed_voted_canceled'); } $document_srl = Context::get('target_srl'); if(!$document_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest; $oDocument = DocumentModel::getDocument($document_srl, false, false); if($oDocument->get('blamed_count') >= 0) { throw new Rhymix\Framework\Exception('failed_blamed_canceled'); } $point = -1; $output = $this->updateVotedCountCancel($document_srl, $oDocument, $point); if(!$output->toBool()) { return $output; } $output = new BaseObject(); $output->setMessage('success_blamed_canceled'); return $output; } /** * Update Document Voted Cancel * @param int $document_srl * @param Document $oDocument * @param int $point * @return object */ function updateVotedCountCancel($document_srl, $oDocument, $point) { if(!$_SESSION['voted_document'][$document_srl] && !$this->user->member_srl) { return new BaseObject(-1, $point > 0 ? 'failed_voted_canceled' : 'failed_blamed_canceled'); } // Check if the current user has voted previously. $args = new stdClass; $args->document_srl = $document_srl; if($this->user->member_srl) { $args->member_srl = $this->user->member_srl; } else { $args->ipaddress = \RX_CLIENT_IP; } $output = executeQuery('document.getDocumentVotedLogInfo', $args); if(!$output->data->count) { return new BaseObject(-1, $point > 0 ? 'failed_voted_canceled' : 'failed_blamed_canceled'); } $point = $output->data->point; // Call a trigger (before) $trigger_obj = new stdClass; $trigger_obj->member_srl = $oDocument->get('member_srl'); $trigger_obj->module_srl = $oDocument->get('module_srl'); $trigger_obj->document_srl = $oDocument->get('document_srl'); $trigger_obj->update_target = ($point < 0) ? 'blamed_count' : 'voted_count'; $trigger_obj->point = $point; $trigger_obj->before_point = ($point < 0) ? $oDocument->get('blamed_count') : $oDocument->get('voted_count'); $trigger_obj->after_point = $trigger_obj->before_point - $point; $trigger_obj->cancel = true; $trigger_output = ModuleHandler::triggerCall('document.updateVotedCountCancel', 'before', $trigger_obj); if(!$trigger_output->toBool()) { return $trigger_output; } // begin transaction $oDB = DB::getInstance(); $oDB->begin(); if($point != 0) { $args = new stdClass(); $d_args = new stdClass(); $args->document_srl = $d_args->document_srl = $document_srl; $d_args->member_srl = $this->user->member_srl; if ($trigger_obj->update_target === 'voted_count') { $args->voted_count = $trigger_obj->after_point; $output = executeQuery('document.updateVotedCount', $args); } else { $args->blamed_count = $trigger_obj->after_point; $output = executeQuery('document.updateBlamedCount', $args); } $d_output = executeQuery('document.deleteDocumentVotedLog', $d_args); if(!$d_output->toBool()) return $d_output; } // session reset unset($_SESSION['voted_document'][$document_srl]); // Call a trigger (after) ModuleHandler::triggerCall('document.updateVotedCountCancel', 'after', $trigger_obj); $oDB->commit(); return $output; } /** * Action called when the post is reported by other member * @return void|Object */ function procDocumentDeclare() { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\MustLogin; } $document_srl = intval(Context::get('target_srl')); if(!$document_srl) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } // if an user select message from options, message would be the option. $message_option = strval(Context::get('message_option')); $improper_document_reasons = lang('improper_document_reasons'); $declare_message = ($message_option !== 'others' && isset($improper_document_reasons[$message_option])) ? $improper_document_reasons[$message_option] : trim(Context::get('declare_message')); // if there is return url, set that. if(Context::get('success_return_url')) { $this->setRedirectUrl(Context::get('success_return_url')); } return $this->declaredDocument($document_srl, $declare_message); } /** * 신고를 취소하는 액션 * @return BaseObject|object * @throws \Rhymix\Framework\Exceptions\InvalidRequest * @throws \Rhymix\Framework\Exceptions\MustLogin */ function procDocumentDeclareCancel() { if(!Context::get('is_logged')) { throw new Rhymix\Framework\Exceptions\MustLogin; } $document_srl = intval(Context::get('target_srl')); $oDocument = DocumentModel::getDocument($document_srl); if(!$oDocument->isExists()) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } $module_info = ModuleModel::getModuleInfoByDocumentSrl($document_srl); if($module_info->cancel_vote !== 'Y') { throw new Rhymix\Framework\Exception('failed_declared_cancel'); } if(Context::get('success_return_url')) { $this->setRedirectUrl(Context::get('success_return_url')); } return $this->declaredDocumentCancel($document_srl); } /** * Delete alias when module deleted * @param int $module_srl * @return void */ function deleteDocumentAliasByModule($module_srl) { $args = new stdClass(); $args->module_srl = $module_srl; executeQuery("document.deleteAlias", $args); } /** * Delete alias when document deleted * @param int $document_srl * @return void */ function deleteDocumentAliasByDocument($document_srl) { $args = new stdClass(); $args->document_srl = $document_srl; executeQuery("document.deleteAlias", $args); } /** * Delete document history * @param int $history_srl * @param int $document_srl * @param int $module_srl * @return void */ function deleteDocumentHistory($history_srl, $document_srl, $module_srl) { $args = new stdClass(); $args->history_srl = $history_srl; $args->module_srl = $module_srl; $args->document_srl = $document_srl; if(!$args->history_srl && !$args->module_srl && !$args->document_srl) return; executeQuery("document.deleteHistory", $args); } /** * A trigger to delete all posts together when the module is deleted * @param object $obj * @return Object */ function triggerDeleteModuleDocuments(&$obj) { $module_srl = $obj->module_srl; if(!$module_srl) return; // Delete the document $oDocumentAdminController = getAdminController('document'); $output = $oDocumentAdminController->deleteModuleDocument($module_srl); if(!$output->toBool()) return $output; // Delete the category $oDocumentController = getController('document'); $output = $oDocumentController->deleteModuleCategory($module_srl); if(!$output->toBool()) return $output; // Delete extra key and variable, because module deleted $this->deleteDocumentExtraKeys($module_srl); // remove aliases $this->deleteDocumentAliasByModule($module_srl); // remove histories $this->deleteDocumentHistory(null, null, $module_srl); } /** * Grant a permisstion of the document * Available in the current connection with session value * @param int $document_srl * @return void */ function addGrant($document_srl) { $oDocument = DocumentModel::getDocument($document_srl); if ($oDocument->isExists()) { $oDocument->setGrant(); } } /** * Insert the document * @param object $obj * @param bool $manual_inserted * @param bool $isRestore * @return object */ function insertDocument($obj, $manual_inserted = false, $isRestore = false, $isLatest = true) { if(!$manual_inserted && !checkCSRF()) { return new BaseObject(-1, 'msg_security_violation'); } // begin transaction $oDB = DB::getInstance(); $oDB->begin(); // List variables if($obj->comment_status) $obj->commentStatus = $obj->comment_status; if(!$obj->commentStatus) $obj->commentStatus = 'DENY'; if($obj->commentStatus == 'DENY') $this->_checkCommentStatusForOldVersion($obj); if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; if($obj->homepage) { $obj->homepage = escape($obj->homepage); if(!preg_match('/^[a-z]+:\/\//i',$obj->homepage)) { $obj->homepage = 'http://'.$obj->homepage; } } if($obj->notify_message != 'Y') $obj->notify_message = 'N'; if(!$obj->email_address) $obj->email_address = ''; if(!$isRestore) $obj->ipaddress = \RX_CLIENT_IP; $obj->isRestore = $isRestore ? true : false; // Sanitize variables $obj->document_srl = intval($obj->document_srl); $obj->category_srl = intval($obj->category_srl); $obj->module_srl = intval($obj->module_srl); // Default Status if($obj->status) { if(!in_array($obj->status, $this->getStatusList())) { $obj->status = $this->getDefaultStatus(); } } else { $this->_checkDocumentStatusForOldVersion($obj); } // can modify regdate only manager $grant = Context::get('grant'); if(!$grant->manager) { unset($obj->regdate); } // Serialize the $extra_vars, check the extra_vars type, because duplicate serialized avoid if(!is_string($obj->extra_vars)) $obj->extra_vars = serialize($obj->extra_vars); // Remove the columns for automatic saving unset($obj->_saved_doc_srl); unset($obj->_saved_doc_title); unset($obj->_saved_doc_content); unset($obj->_saved_doc_message); // Remove manual member info to prevent forgery. This variable can be set by triggers only. unset($obj->manual_member_info); $obj->uploaded_count = FileModel::getFilesCount($obj->document_srl); // Call a trigger (before) $output = ModuleHandler::triggerCall('document.insertDocument', 'before', $obj); if(!$output->toBool()) { return $output; } // Register it if no given document_srl exists if(!$obj->document_srl) { $obj->document_srl = getNextSequence(); } elseif(!$manual_inserted && !$isRestore && !checkUserSequence($obj->document_srl)) { return new BaseObject(-1, 'msg_not_permitted'); } // Set to 0 if the category_srl doesn't exist if($obj->category_srl) { $category_list = DocumentModel::getCategoryList($obj->module_srl); if(count($category_list) > 0 && !$category_list[$obj->category_srl]->grant) { return new BaseObject(-1, 'msg_not_permitted'); } if(count($category_list) > 0 && !$category_list[$obj->category_srl]) $obj->category_srl = 0; } // Set the read counts and update order. if(!$obj->readed_count) $obj->readed_count = 0; if($isLatest) $obj->update_order = $obj->list_order = $obj->document_srl * -1; else $obj->update_order = $obj->list_order; // Check the status of password hash for manually inserting. Apply hashing for otherwise. if($obj->password && !$obj->password_is_hashed) { $obj->password = MemberModel::hashPassword($obj->password); } // Insert member's information only if the member is logged-in and not manually registered. $logged_info = Context::get('logged_info'); if(Context::get('is_logged') && !$manual_inserted && !$isRestore && !$obj->manual_member_info) { $obj->member_srl = $logged_info->member_srl; // user_id, user_name and nick_name already encoded $obj->user_id = htmlspecialchars_decode($logged_info->user_id); $obj->user_name = htmlspecialchars_decode($logged_info->user_name); $obj->nick_name = htmlspecialchars_decode($logged_info->nick_name); $obj->email_address = $logged_info->email_address; $obj->homepage = $logged_info->homepage; } // If the tile is empty, extract string from the contents. $obj->title = escape($obj->title, false); if($obj->title == '') { $obj->title = cut_str(trim(strip_tags(nl2br($obj->content))),20,'...'); } if($obj->title == '') { $obj->title = 'Untitled'; } // Remove XE's own tags from the contents. $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); // Return error if content is empty. if (!$manual_inserted && is_empty_html_content($obj->content)) { return new BaseObject(-1, 'msg_empty_content'); } // if use editor of nohtml, Remove HTML tags from the contents. if(!$manual_inserted || isset($obj->allow_html) || isset($obj->use_html)) { $obj->content = getModel('editor')->converter($obj, 'document'); } // Remove iframe and script if not a top adminisrator in the session. if($logged_info->is_admin != 'Y') { $obj->content = removeHackTag($obj->content); } // An error appears if both log-in info and user name don't exist. if(!$logged_info->member_srl && !$obj->nick_name) return new BaseObject(-1, 'msg_invalid_request'); // Fix encoding of non-BMP UTF-8 characters. $obj->title = utf8_mbencode($obj->title); $obj->content = utf8_mbencode($obj->content); $obj->lang_code = Context::getLangType(); // Insert data into the DB $output = executeQuery('document.insertDocument', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } // Insert extra variables if the document successfully inserted. $extra_vars = array(); $extra_keys = DocumentModel::getExtraKeys($obj->module_srl); if(count($extra_keys)) { foreach($extra_keys as $idx => $extra_item) { $value = NULL; if(isset($obj->{'extra_vars'.$idx})) { $tmp = $obj->{'extra_vars'.$idx}; if(is_array($tmp)) { $value = implode('|@|', $tmp); } else { $value = trim($tmp); } } else if(isset($obj->{$extra_item->name})) { $value = trim($obj->{$extra_item->name}); } if($value == NULL) continue; $extra_vars[$extra_item->name] = $value; $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); } } // Update the category if the category_srl exists. if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); // Call a trigger (after) if($obj->update_log_setting === 'Y') { $obj->extra_vars = serialize($extra_vars); $update_output = $this->insertDocumentUpdateLog($obj); if(!$update_output->toBool()) { $oDB->rollback(); return $update_output; } } $attachOutput = getController('file')->setFilesValid($obj->document_srl, 'doc'); if(!$attachOutput->toBool()) { $oDB->rollback(); return $attachOutput; } $obj->updated_file_count = $attachOutput->get('updated_file_count'); ModuleHandler::triggerCall('document.insertDocument', 'after', $obj); // commit $oDB->commit(); // return if(!$manual_inserted) { $this->addGrant($obj->document_srl); } $output->add('document_srl',$obj->document_srl); $output->add('category_srl',$obj->category_srl); return $output; } /** * Update the document * @param object $source_obj * @param object $obj * @param bool $manual_updated * @return object */ function updateDocument($source_obj, $obj, $manual_updated = FALSE) { if(!$manual_updated && !checkCSRF()) { return new BaseObject(-1, 'msg_security_violation'); } if(!$source_obj->document_srl || !$obj->document_srl) { return new BaseObject(-1, 'msg_invalied_request'); } // Sanitize variables $obj->document_srl = intval($obj->document_srl); $obj->category_srl = intval($obj->category_srl); $obj->module_srl = intval($obj->module_srl); // Default Status if($obj->status) { if(!in_array($obj->status, $this->getStatusList())) { $obj->status = $this->getDefaultStatus(); } // Do not update to temp document (point problem) if($obj->status == $this->getConfigStatus('temp')) { $obj->status = $source_obj->get('status'); } } else { $this->_checkDocumentStatusForOldVersion($obj); } // Remove manual member info to prevent forgery. This variable can be set by triggers only. unset($obj->manual_member_info); $obj->uploaded_count = FileModel::getFilesCount($obj->document_srl); // Call a trigger (before) $output = ModuleHandler::triggerCall('document.updateDocument', 'before', $obj); if(!$output->toBool()) { return $output; } // begin transaction $oDB = &DB::getInstance(); $oDB->begin(); if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl'); $document_config = ModuleModel::getModulePartConfig('document', $obj->module_srl); if(!$document_config) { $document_config = new stdClass(); } if(!isset($document_config->use_history)) $document_config->use_history = 'N'; $bUseHistory = $document_config->use_history == 'Y' || $document_config->use_history == 'Trace'; $logged_info = Context::get('logged_info'); if($bUseHistory) { $args = new stdClass; $args->history_srl = getNextSequence(); $args->document_srl = $obj->document_srl; $args->module_srl = $obj->module_srl; if($document_config->use_history == 'Y') $args->content = $source_obj->get('content'); $args->nick_name = $source_obj->get('nick_name'); $args->member_srl = $source_obj->get('member_srl'); $args->regdate = $source_obj->get('last_update'); $args->ipaddress = $source_obj->get('ipaddress'); $output = executeQuery("document.insertHistory", $args); } else { $obj->ipaddress = $source_obj->get('ipaddress'); } // List variables if($obj->comment_status) $obj->commentStatus = $obj->comment_status; if(!$obj->commentStatus) $obj->commentStatus = 'DENY'; if($obj->commentStatus == 'DENY') $this->_checkCommentStatusForOldVersion($obj); if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; if($obj->homepage) { $obj->homepage = escape($obj->homepage); if(!preg_match('/^[a-z]+:\/\//i',$obj->homepage)) { $obj->homepage = 'http://'.$obj->homepage; } } if($obj->notify_message != 'Y') $obj->notify_message = 'N'; // can modify regdate only manager $grant = Context::get('grant'); if(!$grant->manager) { unset($obj->regdate); } // Serialize the $extra_vars if(!is_string($obj->extra_vars)) $obj->extra_vars = serialize($obj->extra_vars); // Remove the columns for automatic saving unset($obj->_saved_doc_srl); unset($obj->_saved_doc_title); unset($obj->_saved_doc_content); unset($obj->_saved_doc_message); // Set the category_srl to 0 if the changed category is not exsiting. if($source_obj->get('category_srl')!=$obj->category_srl) { $category_list = DocumentModel::getCategoryList($obj->module_srl); if(!$category_list[$obj->category_srl]) $obj->category_srl = 0; } // Change the update order $obj->update_order = getNextSequence() * -1; // Hash the password if it exists if($obj->password) { $obj->password = MemberModel::hashPassword($obj->password); } // If an author is identical to the modifier or history is used, use the logged-in user's information. if(Context::get('is_logged') && !$manual_updated && !$obj->manual_member_info) { if($source_obj->get('member_srl')==$logged_info->member_srl) { $obj->member_srl = $logged_info->member_srl; $obj->user_name = htmlspecialchars_decode($logged_info->user_name); $obj->nick_name = htmlspecialchars_decode($logged_info->nick_name); $obj->email_address = $logged_info->email_address; $obj->homepage = $logged_info->homepage; } } // For the document written by logged-in user however no nick_name exists if($source_obj->get('member_srl')&& !$obj->nick_name && !$obj->manual_member_info) { $obj->member_srl = $source_obj->get('member_srl'); $obj->user_name = $source_obj->get('user_name'); $obj->nick_name = $source_obj->get('nick_name'); $obj->email_address = $source_obj->get('email_address'); $obj->homepage = $source_obj->get('homepage'); } // If the tile is empty, extract string from the contents. $obj->title = escape($obj->title, false); if($obj->title == '') { $obj->title = cut_str(strip_tags($obj->content),20,'...'); } if($obj->title == '') { $obj->title = 'Untitled'; } // Remove XE's own tags from the contents. $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); // Return error if content is empty. if (!$manual_updated && is_empty_html_content($obj->content)) { return new BaseObject(-1, 'msg_empty_content'); } // if use editor of nohtml, Remove HTML tags from the contents. if(!$manual_updated || isset($obj->allow_html) || isset($obj->use_html)) { $obj->content = getModel('editor')->converter($obj, 'document'); } // Change not extra vars but language code of the original document if document's lang_code is different from author's setting. if($source_obj->get('lang_code') != Context::getLangType()) { // Change not extra vars but language code of the original document if document's lang_code doesn't exist. if(!$source_obj->get('lang_code')) { $lang_code_args = new stdClass(); $lang_code_args->document_srl = $source_obj->get('document_srl'); $lang_code_args->lang_code = Context::getLangType(); $output = executeQuery('document.updateDocumentsLangCode', $lang_code_args); } else { $extra_content = new stdClass; $extra_content->title = $obj->title; $extra_content->content = $obj->content; $document_args = new stdClass; $document_args->document_srl = $source_obj->get('document_srl'); $document_output = executeQuery('document.getDocument', $document_args); $obj->title = $document_output->data->title; $obj->content = $document_output->data->content; } } // Remove iframe and script if not a top adminisrator in the session. if($logged_info->is_admin != 'Y') { $obj->content = removeHackTag($obj->content); } // if temporary document, regdate is now setting if($source_obj->get('status') == $this->getConfigStatus('temp')) $obj->regdate = date('YmdHis'); // Fix encoding of non-BMP UTF-8 characters. $obj->title = utf8_mbencode($obj->title); $obj->content = utf8_mbencode($obj->content); // Insert data into the DB $output = executeQuery('document.updateDocument', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } // Remove all extra variables $extra_vars = array(); if(Context::get('act')!='procFileDelete') { $this->deleteDocumentExtraVars($source_obj->get('module_srl'), $obj->document_srl, null, Context::getLangType()); // Insert extra variables if the document successfully inserted. $extra_keys = DocumentModel::getExtraKeys($obj->module_srl); if(count($extra_keys)) { foreach($extra_keys as $idx => $extra_item) { $value = NULL; if(isset($obj->{'extra_vars'.$idx})) { $tmp = $obj->{'extra_vars'.$idx}; if(is_array($tmp)) $value = implode('|@|', $tmp); else $value = trim($tmp); } else if(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); if($value == NULL) continue; $extra_vars[$extra_item->name] = $value; $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); } } // Inert extra vars for multi-language support of title and contents. if($extra_content->title) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -1, $extra_content->title, 'title_'.Context::getLangType()); if($extra_content->content) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -2, $extra_content->content, 'content_'.Context::getLangType()); } // Update the category if the category_srl exists. if($source_obj->get('category_srl') != $obj->category_srl || $source_obj->get('module_srl') == $logged_info->member_srl) { if($source_obj->get('category_srl') != $obj->category_srl) $this->updateCategoryCount($obj->module_srl, $source_obj->get('category_srl')); if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); } // Call a trigger (after) if($obj->update_log_setting === 'Y') { $obj->extra_vars = serialize($extra_vars); if($this->grant->manager) { $obj->is_admin = 'Y'; } $update_output = $this->insertDocumentUpdateLog($obj, $source_obj); if(!$update_output->toBool()) { $oDB->rollback(); return $update_output; } } $attachOutput = getController('file')->setFilesValid($obj->document_srl, 'doc'); if(!$attachOutput->toBool()) { $oDB->rollback(); return $attachOutput; } $obj->updated_file_count = $attachOutput->get('updated_file_count'); ModuleHandler::triggerCall('document.updateDocument', 'after', $obj); // commit $oDB->commit(); // Remove the thumbnail file FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); $output->add('document_srl',$obj->document_srl); //remove from cache self::clearDocumentCache($obj->document_srl); return $output; } function insertDocumentUpdateLog($obj, $source_obj = null) { $update_args = new stdClass(); $logged_info = Context::get('logged_info'); if($source_obj === null) { $update_args->category_srl = $obj->category_srl; $update_args->module_srl = $obj->module_srl; $update_args->nick_name = $obj->nick_name; } else { if($obj->category_srl) { $update_args->category_srl = $obj->category_srl; } else { $update_args->category_srl = $source_obj->get('category_srl'); } $update_args->module_srl = $source_obj->get('module_srl'); $update_args->nick_name = $source_obj->get('nick_name'); } $update_args->document_srl = $obj->document_srl; $update_args->update_member_srl = $logged_info->member_srl; $update_args->title = $obj->title; $update_args->title_bold = $obj->title_bold; $update_args->title_color = $obj->title_color; $update_args->content = $obj->content; $update_args->update_nick_name = $logged_info->nick_name; $update_args->tags = $obj->tags; $update_args->extra_vars = $obj->extra_vars; $update_args->reason_update = $obj->reason_update; $update_args->is_admin = $obj->is_admin; $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); return $update_output; } /** * Deleting Documents * @param int $document_srl * @param bool $is_admin * @param bool $isEmptyTrash * @param documentItem $oDocument * @return object */ function deleteDocument($document_srl, $is_admin = false, $isEmptyTrash = false, $oDocument = null) { // Call a trigger (before) $trigger_obj = new stdClass(); $trigger_obj->document_srl = $document_srl; $trigger_obj->isEmptyTrash = $isEmptyTrash ? true : false; $output = ModuleHandler::triggerCall('document.deleteDocument', 'before', $trigger_obj); if(!$output->toBool()) return $output; // begin transaction $oDB = &DB::getInstance(); $oDB->begin(); // Check if the document exists if(!$isEmptyTrash) { $oDocument = DocumentModel::getDocument($document_srl, $is_admin); } else if($isEmptyTrash && $oDocument == null) { return new BaseObject(-1, 'msg_not_founded'); } // Check permission if(!$oDocument->isExists()) { return new BaseObject(-1, 'msg_invalid_document'); } if(!$oDocument->isGranted()) { return new BaseObject(-1, 'msg_not_permitted'); } $member_info = MemberModel::getMemberInfo($oDocument->get('member_srl')); if($member_info->is_admin === 'Y' && $this->user->is_admin !== 'Y') { return new BaseObject(-1, 'msg_document_is_admin_not_permitted'); } //if empty trash, document already deleted, therefore document not delete $args = new stdClass(); $args->document_srl = $document_srl; if(!$isEmptyTrash) { // Delete the document $output = executeQuery('document.deleteDocument', $args); if(!$output->toBool()) { $oDB->rollback(); return $output; } } $this->deleteDocumentAliasByDocument($document_srl); $this->deleteDocumentHistory(null, $document_srl, null); // Update category information if the category_srl exists. if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); // Delete a declared list executeQuery('document.deleteDeclared', $args); // Delete extra variable $this->deleteDocumentExtraVars($oDocument->get('module_srl'), $oDocument->document_srl); // Call a trigger (after) $trigger_obj = $oDocument->getObjectVars(); $trigger_obj->isEmptyTrash = $isEmptyTrash ? true : false; ModuleHandler::triggerCall('document.deleteDocument', 'after', $trigger_obj); // declared document, log delete $this->_deleteDeclaredDocuments($args); $this->_deleteDocumentReadedLog($args); $this->_deleteDocumentVotedLog($args); $this->_deleteDocumentUpdateLog($args); // Remove the thumbnail file Rhymix\Framework\Storage::deleteEmptyDirectory(RX_BASEDIR . sprintf('files/thumbnails/%s', getNumberingPath($document_srl, 3)), true); // commit $oDB->commit(); //remove from cache self::clearDocumentCache($document_srl); return $output; } /** * Delete declared document, log * @param string $documentSrls (ex: 1, 2,56, 88) * @return void */ function _deleteDeclaredDocuments($documentSrls) { executeQuery('document.deleteDeclaredDocuments', $documentSrls); executeQuery('document.deleteDocumentDeclaredLog', $documentSrls); } /** * Delete readed log * @param string $documentSrls (ex: 1, 2,56, 88) * @return void */ function _deleteDocumentReadedLog($documentSrls) { executeQuery('document.deleteDocumentReadedLog', $documentSrls); } /** * Delete voted log * @param string $documentSrls (ex: 1, 2,56, 88) * @return void */ function _deleteDocumentVotedLog($documentSrls) { executeQuery('document.deleteDocumentVotedLog', $documentSrls); } function _deleteDocumentUpdateLog($document_srl) { executeQuery('document.deleteDocumentUpdateLog', $document_srl); } /** * Move the doc into the trash * @param object $obj * @return object */ function moveDocumentToTrash($obj) { $trash_args = new stdClass(); // Get trash_srl if a given trash_srl doesn't exist if(!$obj->trash_srl) $trash_args->trash_srl = getNextSequence(); else $trash_args->trash_srl = $obj->trash_srl; // Get its module_srl which the document belongs to $oDocument = DocumentModel::getDocument($obj->document_srl); if(!$oDocument->isExists()) { return new BaseObject(-1, 'msg_not_founded'); } if(!$oDocument->isGranted()) { return new BaseObject(-1, 'msg_not_permitted'); } if($this->user->is_admin !== 'Y') { $member_info = MemberModel::getMemberInfo($oDocument->get('member_srl')); if($member_info->is_admin === 'Y') { return new BaseObject(-1, 'msg_admin_document_no_move_to_trash'); } } $trash_args->module_srl = $oDocument->get('module_srl'); $obj->module_srl = $oDocument->get('module_srl'); // Cannot throw data from the trash to the trash if($trash_args->module_srl == 0) { return new BaseObject(-1, 'Cannot throw data from the trash to the trash'); } // Data setting $trash_args->document_srl = $obj->document_srl; $trash_args->description = $obj->description; // Insert member's information only if the member is logged-in and not manually registered. if($this->user->isMember()) { $trash_args->member_srl = $this->user->member_srl; $trash_args->user_id = htmlspecialchars_decode($this->user->user_id); $trash_args->user_name = htmlspecialchars_decode($this->user->user_name); $trash_args->nick_name = htmlspecialchars_decode($this->user->nick_name); } // Date setting for updating documents $document_args = new stdClass; $document_args->module_srl = 0; $document_args->document_srl = $obj->document_srl; // begin transaction $oDB = &DB::getInstance(); $oDB->begin(); /*$output = executeQuery('document.insertTrash', $trash_args); if (!$output->toBool()) { $oDB->rollback(); return $output; }*/ // new trash module require_once(RX_BASEDIR.'modules/trash/model/TrashVO.php'); $oTrashVO = new TrashVO(); $oTrashVO->setTrashSrl(getNextSequence()); $oTrashVO->setTitle($oDocument->variables['title']); $oTrashVO->setOriginModule('document'); $oTrashVO->setSerializedObject(serialize($oDocument->variables)); $oTrashVO->setDescription($obj->description); $oTrashAdminController = getAdminController('trash'); $output = $oTrashAdminController->insertTrash($oTrashVO); if(!$output->toBool()) { $oDB->rollback(); return $output; } $output = executeQuery('document.deleteDocument', $trash_args); if(!$output->toBool()) { $oDB->rollback(); return $output; } /*$output = executeQuery('document.updateDocument', $document_args); if (!$output->toBool()) { $oDB->rollback(); return $output; }*/ // update category if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); // remove thumbnails FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); // Set the attachment to be invalid state if($oDocument->hasUploadedFiles()) { $args = new stdClass(); $args->upload_target_srl = $oDocument->document_srl; $args->isvalid = 'N'; executeQuery('file.updateFileValid', $args); } // Call a trigger (after) $obj->module_srl = $oDocument->get('module_srl'); $obj->member_srl = $oDocument->get('member_srl'); $obj->regdate = $oDocument->get('regdate'); $obj->last_update = $oDocument->get('last_update'); ModuleHandler::triggerCall('document.moveDocumentToTrash', 'after', $obj); // commit $oDB->commit(); // Clear cache self::clearDocumentCache($oDocument->document_srl); return $output; } /** * Update read counts of the document * @param documentItem $oDocument * @return bool|void */ function updateReadedCount(&$oDocument) { // Pass if Crawler access if (\Rhymix\Framework\UA::isRobot()) { return false; } // Get the view count option, and use the default if the value is empty or invalid. $valid_options = array( 'all' => true, 'some' => true, 'once' => true, 'none' => true, ); $config = DocumentModel::getDocumentConfig(); if (!$config->view_count_option || !isset($valid_options[$config->view_count_option])) { $config->view_count_option = 'once'; } // If not counting, return now. if ($config->view_count_option == 'none') { return false; } // Get document and user information. $document_srl = $oDocument->document_srl; $member_srl = $oDocument->get('member_srl'); $logged_info = Context::get('logged_info'); // Option 'some': only count once per session. if ($config->view_count_option != 'all' && $_SESSION['readed_document'][$document_srl]) { return false; } // Option 'once': check member_srl and IP address. if ($config->view_count_option == 'once') { // Pass if the author's IP address is as same as visitor's. if($oDocument->get('ipaddress') == \RX_CLIENT_IP) { if (Context::getSessionStatus()) { $_SESSION['readed_document'][$document_srl] = true; } return false; } // Pass if the author's member_srl is the same as the visitor's. if($member_srl && $logged_info->member_srl && $logged_info->member_srl == $member_srl) { $_SESSION['readed_document'][$document_srl] = true; return false; } } // Call a trigger when the read count is updated (before) $trigger_output = ModuleHandler::triggerCall('document.updateReadedCount', 'before', $oDocument); if(!$trigger_output->toBool()) return $trigger_output; // Update read counts $oDB = DB::getInstance(); $oDB->begin(); $args = new stdClass; $args->document_srl = $document_srl; executeQuery('document.updateReadedCount', $args); // Call a trigger when the read count is updated (after) ModuleHandler::triggerCall('document.updateReadedCount', 'after', $oDocument); $oDB->commit(); // Register session if(!$_SESSION['banned_document'][$document_srl] && Context::getSessionStatus()) { $_SESSION['readed_document'][$document_srl] = true; } return TRUE; } /** * Insert extra variables into the document table * @param int $module_srl * @param int $var_idx * @param string $var_name * @param string $var_type * @param string $var_is_required * @param string $var_search * @param string $var_default * @param string $var_desc * @param int $eid * @return object */ function insertDocumentExtraKey($module_srl, $var_idx, $var_name, $var_type, $var_is_required = 'N', $var_search = 'N', $var_default = '', $var_desc = '', $eid) { if(!$module_srl || !$var_idx || !$var_name || !$var_type || !$eid) return new BaseObject(-1, 'msg_invalid_request'); $obj = new stdClass(); $obj->module_srl = $module_srl; $obj->var_idx = $var_idx; $obj->var_name = $var_name; $obj->var_type = $var_type; $obj->var_is_required = $var_is_required=='Y'?'Y':'N'; $obj->var_search = $var_search=='Y'?'Y':'N'; $obj->var_default = $var_default; $obj->var_desc = $var_desc; $obj->eid = $eid; $output = executeQuery('document.getDocumentExtraKeys', $obj); if(!$output->data) { $output = executeQuery('document.insertDocumentExtraKey', $obj); } else { $output = executeQuery('document.updateDocumentExtraKey', $obj); // Update the extra var(eid) $output = executeQuery('document.updateDocumentExtraVar', $obj); } Rhymix\Framework\Cache::delete("site_and_module:module_document_extra_keys:$module_srl"); return $output; } /** * Remove the extra variables of the documents * @param int $module_srl * @param int $var_idx * @return Object */ function deleteDocumentExtraKeys($module_srl, $var_idx = null) { if(!$module_srl) return new BaseObject(-1, 'msg_invalid_request'); $obj = new stdClass(); $obj->module_srl = $module_srl; if(!is_null($var_idx)) $obj->var_idx = $var_idx; $oDB = DB::getInstance(); $oDB->begin(); $output = $oDB->executeQuery('document.deleteDocumentExtraKeys', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } if($var_idx != NULL) { $output = $oDB->executeQuery('document.updateDocumentExtraKeyIdxOrder', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } } $output = executeQuery('document.deleteDocumentExtraVars', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } if($var_idx != NULL) { $output = $oDB->executeQuery('document.updateDocumentExtraVarIdxOrder', $obj); if(!$output->toBool()) { $oDB->rollback(); return $output; } } $oDB->commit(); Rhymix\Framework\Cache::delete("site_and_module:module_document_extra_keys:$module_srl"); return new BaseObject(); } /** * Insert extra vaiable to the documents table * @param int $module_srl * @param int $document_srl * @param int $var_idx * @param mixed $value * @param int $eid * @param string $lang_code * @return Object|void */ function insertDocumentExtraVar($module_srl, $document_srl, $var_idx, $value, $eid = null, $lang_code = '') { if(!$module_srl || !$document_srl || !$var_idx || !isset($value)) return new BaseObject(-1, 'msg_invalid_request'); if(!$lang_code) $lang_code = Context::getLangType(); $obj = new stdClass; $obj->module_srl = $module_srl; $obj->document_srl = $document_srl; $obj->var_idx = $var_idx; $obj->value = $value; $obj->lang_code = $lang_code; $obj->eid = $eid; executeQuery('document.insertDocumentExtraVar', $obj); } /** * Remove values of extra variable from the document * @param int $module_srl * @param int $document_srl * @param int $var_idx * @param string $lang_code * @param int $eid * @return $output */ function deleteDocumentExtraVars($module_srl, $document_srl = null, $var_idx = null, $lang_code = null, $eid = null) { $obj = new stdClass(); $obj->module_srl = $module_srl; if(!is_null($document_srl)) $obj->document_srl = $document_srl; if(!is_null($var_idx)) $obj->var_idx = $var_idx; if(!is_null($lang_code)) $obj->lang_code = $lang_code; if(!is_null($eid)) $obj->eid = $eid; $output = executeQuery('document.deleteDocumentExtraVars', $obj); return $output; } /** * Increase the number of vote-up of the document * @param int $document_srl * @param int $point * @return Object */ function updateVotedCount($document_srl, $point = 1) { if($point > 0) { $failed_voted = 'failed_voted'; } else { $failed_voted = 'failed_blamed'; } // Return fail if session already has information about votes if($_SESSION['voted_document'][$document_srl]) { return new BaseObject(-1, $failed_voted); } // Get the original document $oDocument = DocumentModel::getDocument($document_srl, false, false); // Pass if the author's IP address is as same as visitor's. if($oDocument->get('ipaddress') == \RX_CLIENT_IP) { $_SESSION['voted_document'][$document_srl] = false; return new BaseObject(-1, $failed_voted); } // Get current member_srl $member_srl = MemberModel::getLoggedMemberSrl(); // Check if document's author is a member. if($oDocument->get('member_srl')) { // Pass after registering a session if author's information is same as the currently logged-in user's. if($member_srl && $member_srl == abs($oDocument->get('member_srl'))) { $_SESSION['voted_document'][$document_srl] = false; return new BaseObject(-1, $failed_voted); } } // Use member_srl for logged-in members and IP address for non-members. $args = new stdClass(); if($member_srl) { $args->member_srl = $member_srl; } else { $args->ipaddress = \RX_CLIENT_IP; } $args->document_srl = $document_srl; $output = executeQuery('document.getDocumentVotedLogInfo', $args); // Pass after registering a session if log information has vote-up logs if($output->data->count) { $_SESSION['voted_document'][$document_srl] = false; return new BaseObject(-1, $failed_voted); } // Call a trigger (before) $trigger_obj = new stdClass; $trigger_obj->member_srl = $oDocument->get('member_srl'); $trigger_obj->module_srl = $oDocument->get('module_srl'); $trigger_obj->document_srl = $oDocument->get('document_srl'); $trigger_obj->update_target = ($point < 0) ? 'blamed_count' : 'voted_count'; $trigger_obj->point = $point; $trigger_obj->before_point = ($point < 0) ? $oDocument->get('blamed_count') : $oDocument->get('voted_count'); $trigger_obj->after_point = $trigger_obj->before_point + $point; $trigger_obj->cancel = false; $trigger_output = ModuleHandler::triggerCall('document.updateVotedCount', 'before', $trigger_obj); if(!$trigger_output->toBool()) { return $trigger_output; } // begin transaction $oDB = DB::getInstance(); $oDB->begin(); // Update the voted count if($trigger_obj->update_target === 'blamed_count') { $args->blamed_count = $trigger_obj->after_point; $output = executeQuery('document.updateBlamedCount', $args); } else { $args->voted_count = $trigger_obj->after_point; $output = executeQuery('document.updateVotedCount', $args); } if(!$output->toBool()) return $output; // Leave in the session information $_SESSION['voted_document'][$document_srl] = $trigger_obj->point; // Leave logs $args->point = $trigger_obj->point; $output = executeQuery('document.insertDocumentVotedLog', $args); if(!$output->toBool()) return $output; // Call a trigger (after) ModuleHandler::triggerCall('document.updateVotedCount', 'after', $trigger_obj); $oDB->commit(); //remove document item from cache Rhymix\Framework\Cache::delete('document_item:' . getNumberingPath($document_srl) . $document_srl); // Return result $output = new BaseObject(); if($trigger_obj->update_target === 'voted_count') { $output->setMessage('success_voted'); $output->add('voted_count', $trigger_obj->after_point); } else { $output->setMessage('success_blamed'); $output->add('blamed_count', $trigger_obj->after_point); } return $output; } /** * Report posts * @param int $document_srl * @param string $declare_message * @return void|Object */ function declaredDocument($document_srl, $declare_message = '') { // Fail if session information already has a reported document if($_SESSION['declared_document'][$document_srl]) { return new BaseObject(-1, 'failed_declared'); } // Check if previously reported $args = new stdClass(); $args->document_srl = $document_srl; $output = executeQuery('document.getDeclaredDocument', $args); if(!$output->toBool()) { return $output; } $declared_count = ($output->data->declared_count) ? $output->data->declared_count : 0; $declare_message = trim(htmlspecialchars($declare_message)); $trigger_obj = new stdClass(); $trigger_obj->document_srl = $document_srl; $trigger_obj->declared_count = $declared_count; $trigger_obj->declare_message = $declare_message; // Call a trigger (before) $trigger_output = ModuleHandler::triggerCall('document.declaredDocument', 'before', $trigger_obj); if(!$trigger_output->toBool()) { return $trigger_output; } // Get the original document $oDocument = DocumentModel::getDocument($document_srl, false, false); // Pass if the author's IP address is as same as visitor's. if($oDocument->get('ipaddress') == \RX_CLIENT_IP) { $_SESSION['declared_document'][$document_srl] = true; return new BaseObject(-1, 'failed_declared'); } // Get currently logged in user. $member_srl = $this->user->member_srl; // Check if document's author is a member. if($oDocument->get('member_srl')) { // Pass after registering a session if author's information is same as the currently logged-in user's. if($member_srl && $member_srl == abs($oDocument->get('member_srl'))) { $_SESSION['declared_document'][$document_srl] = true; return new BaseObject(-1, 'failed_declared'); } } // Pass after registering a sesson if reported/declared documents are in the logs. $args = new stdClass; $args->document_srl = $document_srl; if($member_srl) { $args->member_srl = $member_srl; } else { $args->ipaddress = \RX_CLIENT_IP; } $output = executeQuery('document.getDocumentDeclaredLogInfo', $args); if($output->data->count) { $_SESSION['declared_document'][$document_srl] = true; return new BaseObject(-1, 'failed_declared'); } // Fill in remaining information for logging. $args->member_srl = $member_srl; $args->ipaddress = \RX_CLIENT_IP; $args->declare_message = $declare_message; // begin transaction $oDB = DB::getInstance(); $oDB->begin(); // Add the declared document if($declared_count > 0) { $output = executeQuery('document.updateDeclaredDocument', $args); } else { $output = executeQuery('document.insertDeclaredDocument', $args); } if(!$output->toBool()) { $oDB->rollback(); return $output; } // Leave logs $output = executeQuery('document.insertDocumentDeclaredLog', $args); if(!$output->toBool()) { $oDB->rollback(); return $output; } $this->add('declared_count', $declared_count + 1); // Send message to admin $message_targets = array(); $module_srl = $oDocument->get('module_srl'); $document_config = ModuleModel::getModulePartConfig('document', $module_srl); if ($document_config->declared_message && in_array('admin', $document_config->declared_message)) { $output = executeQueryArray('member.getAdmins', new stdClass); foreach ($output->data as $admin) { $message_targets[$admin->member_srl] = true; } } if ($document_config->declared_message && in_array('manager', $document_config->declared_message)) { $output = executeQueryArray('module.getModuleAdmin', (object)['module_srl' => $module_srl]); foreach ($output->data as $manager) { $message_targets[$manager->member_srl] = true; } } if ($message_targets) { $oCommunicationController = getController('communication'); $message_title = lang('document.declared_message_title'); $message_content = sprintf('
%s
', $oDocument->getPermanentUrl(), $oDocument->getTitleText(), $declare_message); foreach ($message_targets as $target_member_srl => $val) { $oCommunicationController->sendMessage($this->user->member_srl, $target_member_srl, $message_title, $message_content, false); } } // Call a trigger (after) $trigger_obj->declared_count = $declared_count + 1; ModuleHandler::triggerCall('document.declaredDocument', 'after', $trigger_obj); // commit $oDB->commit(); // Leave in the session information $_SESSION['declared_document'][$document_srl] = true; $this->setMessage('success_declared'); } /** * 신고 취소 * @param $document_srl * @return BaseObject|object|void */ function declaredDocumentCancel($document_srl) { $member_srl = $this->user->member_srl; if(!$_SESSION['declared_document'][$document_srl] && $member_srl) { return new BaseObject(-1, 'failed_declared_cancel'); } // Get the original document $oDocument = DocumentModel::getDocument($document_srl, false, false); $oDB = DB::getInstance(); $oDB->begin(); $args = new stdClass; $args->document_srl = $document_srl; if($member_srl) { $args->member_srl = $member_srl; } else { $args->ipaddress = \RX_CLIENT_IP; } $output = executeQuery('document.getDocumentDeclaredLogInfo', $args); if($output->data->count <= 0 || !isset($output->data->count)) { $_SESSION['declared_document'][$document_srl] = false; return new BaseObject(-1, 'failed_declared_cancel'); } $args = new stdClass(); $args->document_srl = $document_srl; $output = executeQuery('document.getDeclaredDocument', $args); $declared_count = ($output->data->declared_count) ? $output->data->declared_count : 0; $trigger_obj = new stdClass(); $trigger_obj->document_srl = $document_srl; $trigger_obj->declared_count = $declared_count; // Call a trigger (before) $trigger_output = ModuleHandler::triggerCall('document.declaredDocumentCancel', 'before', $trigger_obj); if(!$trigger_output->toBool()) { return $trigger_output; } if($declared_count > 1) { $output = executeQuery('document.updateDeclaredDocumentCancel', $args); } else { $output = executeQuery('document.deleteDeclaredDocument', $args); } if(!$output->toBool()) { $oDB->rollback(); return $output; } $output = executeQuery('document.deleteDeclaredDocumentLog', $args); if(!$output->toBool()) { $oDB->rollback(); return $output; } $message_targets = array(); $module_srl = $oDocument->get('module_srl'); $document_config = ModuleModel::getModulePartConfig('document', $module_srl); if ($document_config->declared_message && in_array('admin', $document_config->declared_message)) { $output = executeQueryArray('member.getAdmins', new stdClass); foreach ($output->data as $admin) { $message_targets[$admin->member_srl] = true; } } if ($document_config->declared_message && in_array('manager', $document_config->declared_message)) { $output = executeQueryArray('module.getModuleAdmin', (object)['module_srl' => $module_srl]); foreach ($output->data as $manager) { $message_targets[$manager->member_srl] = true; } } if ($message_targets) { $oCommunicationController = getController('communication'); $message_title = lang('document.declared_cancel_message_title'); $message_content = sprintf('%s
', $oDocument->getPermanentUrl(), $oDocument->getTitleText()); foreach ($message_targets as $target_member_srl => $val) { $oCommunicationController->sendMessage($this->user->member_srl, $target_member_srl, $message_title, $message_content, false); } } $oDB->commit(); $trigger_obj->declared_count = $declared_count - 1; ModuleHandler::triggerCall('document.declaredDocumentCancel', 'after', $trigger_obj); $_SESSION['declared_document'][$document_srl] = false; $this->setMessage('success_declared_cancel'); } /** * Increase the number of comments in the document * Update modified date, modifier, and order with increasing comment count * @param int $document_srl * @param int $comment_count * @param string $last_updater * @param bool $update_order * @return object */ function updateCommentCount($document_srl, $comment_count, $last_updater, $update_order = false) { $args = new stdClass(); $args->document_srl = $document_srl; $args->comment_count = $comment_count; if($update_order) { $args->update_order = -1*getNextSequence(); $args->last_update = date('YmdHis'); $args->last_updater = $last_updater; } // remove document item from cache Rhymix\Framework\Cache::delete('document_item:' . getNumberingPath($document_srl) . $document_srl); return executeQuery('document.updateCommentCount', $args); } /** * Increase trackback count of the document * @param int $document_srl * @param int $trackback_count * @return object */ function updateTrackbackCount($document_srl, $trackback_count) { $args = new stdClass; $args->document_srl = $document_srl; $args->trackback_count = $trackback_count; // remove document item from cache Rhymix\Framework\Cache::delete('document_item:' . getNumberingPath($document_srl) . $document_srl); return executeQuery('document.updateTrackbackCount', $args); } /** * Add a category * @param object $obj * @return object */ function insertCategory($obj) { // Sort the order to display if a child category is added if($obj->parent_srl) { // Get its parent category $parent_category = DocumentModel::getCategory($obj->parent_srl); $obj->list_order = $parent_category->list_order; $this->updateCategoryListOrder($parent_category->module_srl, $parent_category->list_order+1); if(!$obj->category_srl) $obj->category_srl = getNextSequence(); } else { $obj->list_order = $obj->category_srl = getNextSequence(); } $output = executeQuery('document.insertCategory', $obj); if($output->toBool()) { $output->add('category_srl', $obj->category_srl); $this->makeCategoryFile($obj->module_srl); } return $output; } /** * Increase list_count from a specific category * @param int $module_srl * @param int $list_order * @return object */ function updateCategoryListOrder($module_srl, $list_order) { $args = new stdClass; $args->module_srl = $module_srl; $args->list_order = $list_order; return executeQuery('document.updateCategoryOrder', $args); } /** * Update document_count in the category. * @param int $module_srl * @param int $category_srl * @param int $document_count * @return object */ function updateCategoryCount($module_srl, $category_srl, $document_count = 0) { // Create a document model object if(!$document_count) { $document_count = DocumentModel::getCategoryDocumentCount($module_srl,$category_srl); } $args = new stdClass; $args->category_srl = $category_srl; $args->document_count = $document_count; $output = executeQuery('document.updateCategoryCount', $args); if($output->toBool()) $this->makeCategoryFile($module_srl); return $output; } /** * Update category information * @param object $obj * @return object */ function updateCategory($obj) { $output = executeQuery('document.updateCategory', $obj); if($output->toBool()) $this->makeCategoryFile($obj->module_srl); return $output; } /** * Delete a category * @param int $category_srl * @return object */ function deleteCategory($category_srl) { $args = new stdClass(); $args->category_srl = $category_srl; $category_info = DocumentModel::getCategory($category_srl); // Display an error that the category cannot be deleted if it has a child $output = executeQuery('document.getChildCategoryCount', $args); if(!$output->toBool()) return $output; if($output->data->count>0) return new BaseObject(-1, 'msg_cannot_delete_for_child'); // Delete a category information $output = executeQuery('document.deleteCategory', $args); if(!$output->toBool()) return $output; $this->makeCategoryFile($category_info->module_srl); // remove cache $page = 0; while(true) { $args = new stdClass(); $args->category_srl = $category_srl; $args->list_count = 100; $args->page = ++$page; $output = executeQuery('document.getDocumentList', $args, array('document_srl')); if($output->data == array()) { break; } foreach($output->data as $val) { self::clearDocumentCache($val->document_srl); } } // Update category_srl of the documents in the same category to 0 $args = new stdClass(); $args->target_category_srl = 0; $args->source_category_srl = $category_srl; $output = executeQuery('document.updateDocumentCategory', $args); return $output; } /** * Delete all categories in a module * @param int $module_srl * @return object */ function deleteModuleCategory($module_srl) { $args = new stdClass(); $args->module_srl = $module_srl; $output = executeQuery('document.deleteModuleCategory', $args); return $output; } /** * Move the category level to higher * @param int $category_srl * @return Object */ function moveCategoryUp($category_srl) { // Get information of the selected category $args = new stdClass; $args->category_srl = $category_srl; $output = executeQuery('document.getCategory', $args); $category = $output->data; $list_order = $category->list_order; $module_srl = $category->module_srl; // Seek a full list of categories $category_list = DocumentModel::getCategoryList($module_srl); $category_srl_list = array_keys($category_list); if(count($category_srl_list)<2) return new BaseObject(); $prev_category = NULL; foreach($category_list as $key => $val) { if($key==$category_srl) break; $prev_category = $val; } // Return if the previous category doesn't exist if(!$prev_category) return new BaseObject(-1, 'msg_category_not_moved'); // Return if the selected category is the top level if($category_srl_list[0]==$category_srl) return new BaseObject(-1, 'msg_category_not_moved'); // Information of the selected category $cur_args = new stdClass; $cur_args->category_srl = $category_srl; $cur_args->list_order = $prev_category->list_order; $cur_args->title = $category->title; $this->updateCategory($cur_args); // Category information $prev_args = new stdClass; $prev_args->category_srl = $prev_category->category_srl; $prev_args->list_order = $list_order; $prev_args->title = $prev_category->title; $this->updateCategory($prev_args); return new BaseObject(); } /** * Move the category down * @param int $category_srl * @return Object */ function moveCategoryDown($category_srl) { // Get information of the selected category $args = new stdClass; $args->category_srl = $category_srl; $output = executeQuery('document.getCategory', $args); $category = $output->data; $list_order = $category->list_order; $module_srl = $category->module_srl; // Seek a full list of categories $category_list = DocumentModel::getCategoryList($module_srl); $category_srl_list = array_keys($category_list); if(count($category_srl_list)<2) return new BaseObject(); for($i=0;$i{$obj->manager_message}