* @since Version 3.0 */ class sysSiteMapController extends cCore { public $dir; public $name; public $module; public $PUB_SIDE = false; // Default languages for pub side and cms lang id; CONST DEFAULT_LANG = 7; CONST CMS_LANG = 1; // Pub/Cms site map type; CONST PUB_TYPE = 0; CONST CMS_TYPE = 1; // Index page for pub/cms site; CONST PUB_SITE_ID = 524; CONST CMS_SITE_ID = 1; // Login page site map id; CONST PUB_LOGIN_MAP_ID = 675; CONST SYS_LOGIN_MAP_ID = 2; // Pub and CMS permission tables CONST DB_TABLE_SYS_PERMISSIONS = "site_permissions"; CONST DB_TABLE_PUB_PERMISSIONS = "mod_permissions"; // MENU TYPE CONST MENU_LINKED = 0; CONST MENU_LOADED = 1; // Modules CONST JS_MOD = 10; CONST CSS_MOD = 11; CONST APP_PUB_MOD = 3; CONST APP_CMS_MOD = 4; CONST REF_ID_DIFF = 0; CONST REF_ID_THE_SAME = 1; /** * Class constructor */ public function __construct($uriData, $dir, $name) { $this->dir = $dir; $this->name = $name; parent :: __construct($uriData); $this->module = new sysSiteMapModule(); $this->oView->setTemplateDir($this->dir . "/tmpl/"); if(!$this->oView->cacheUsed()){ $this->oView->setJs(getCurrentFolder($this->dir) . '/js/' . $this->name . '.js'); $this->oView->setCss(getCurrentFolder($this->dir) . '/css/' . $this->name . '.css'); } // Set JS module init title $this->oView->setAsJSON(cCore::JS_MOD, ucfirst($name)); } /** * Function to show main form in the module * * @category sysSiteMap Controller * @author Mareks Keišs */ public function run($initEditMode = false){ $this->oView->TABLE = true; $this->oView->setAsJSON('initEdit', $initEditMode); $this->oView->setAsJSON('baseUrl', $this->gL()); $this->oView->setAsJSON('gM', $this->getTranslations()); $this->oView->setAsJSON('vcfg', $this->getValCfg()); $this->oView->setAsJSON('sModName', $this->PUB_SIDE ? 'sysSiteMapPUB' : 'sysSiteMapCMS'); $this->oView->A_FOLDER = ADMINISTRATION_FOLDER; $this->oView->display('dialogBox/adminFolderChange', 'CMS_CUSTOM_TPL_DATA'); } /** * Function to create cms table & return for direct & ajax input * * @author Mareks Keišs * @category sysSiteMap Controller * @param int $page - page to display * @param string $filter_json - (optional) filter json string * @param bool $headers - flag whether to send header data or not * @return array of data * @version 1.1 */ public function createCmsTable($page = 1, $filter_json = '', $headers = false) { $this->oView->MODULE_TITLE = $this->gM(($this->PUB_SIDE? 'APP New Site Map' : 'SYS New Site Map')); $pages = 0; $filter = array(); if($filter_json) $filter = cJSON::decode($filter_json, true); if(!!$filter && is_array($filter)) $this->oView->DEFAULT_SEARCH_VALUES = prepForDisplayHtml($filter); $this->oView->LIST_HEADER = reOrderTableFields($this->getTableFields(), $this->oUser->oCfg->getTableProperty($this->PUB_SIDE ? 'sysSiteMapPUB' : 'sysSiteMapCMS')); $this->oView->LIST_DATA = $this->getModuleData($page, $filter, $pages); $this->oView->LIST_ACTIONS = $this->getTableActions(); $data = array( 'data' => $this->oView->genHelperView('cmsc/table/data-table'), 'pcount' => $pages, 'rlimit' => $this->cmsTableRecordsPerPage ); // Send data to client if($headers) $data['header'] = $this->oView->genHelperView('cmsc/table/data-table-search'); return $data; } /** * Function to get module data * * @author Mareks Keišs * @category sysSiteMap Controller * @param int $page * @param array $filter * @param int $pages * @return array of data * @version 1.1 */ public function getModuleData($page = 1, $filter = array(), &$pages) { $where = 'AND 1'; $sort = "sm.id DESC"; // Set default language and use it for query to select data; if(!!!$filter){ $oLang = new sysLanguagesModule(); $defaultLangId = $oLang->getDefaultAppLang($this->PUB_SIDE ? self::PUB_TYPE : self::CMS_TYPE); $where .= "".( !!$defaultLangId['id'] ? " AND sm.p_lang_id = {$defaultLangId['id']}" : "" ).""; } $offset = (($page?$page:1)-1) * $this->cmsTableRecordsPerPage; $tFields = $this->getTableFields(); // Create sort by if(getP('sortBy')) $sort = $this->module->db->genOrderByQuery(getP('sortBy'), getP('sortWay'), $tFields); // Create where clause if(count($filter)) $where = $this->module->db->genSearchFieldQuery($filter, $tFields); $subWhere = ""; $data = $this->module->getModuleRecords($where . $subWhere, $sort, $offset, $this->cmsTableRecordsPerPage, ($this->PUB_SIDE ? self::PUB_TYPE : self::CMS_TYPE)); if(!!$data){ foreach($data as &$val){ if($val['p_modified']) $val['p_modified'] = date($this->CMSDateFormat, $val['p_modified']); if($val['p_created']) $val['p_created'] = date($this->CMSDateFormat, $val['p_created']); if($val['p_default']) $val['p_default'] = '✓'; } unset($val); } $this->oView->ROWS = $rows = $this->module->db->getSelectedRecordsCount(); $pages = floor($rows / $this->cmsTableRecordsPerPage) + ($rows%$this->cmsTableRecordsPerPage?1:0); return $data; } /** * Function to disable / enable enum records marked in table * * @author Mareks Keišs * @category sysSiteMap Controller * @param array $baseField - base field to handle * @param string $rows - passed user ids in JSON string * @return bool|array */ public function changeEnumFields($baseField, $rows) { if($baseField && $rows = cJSON::decode($rows, true)){ $baseField = substr($baseField, 2); $fields = $this->getTableFields(); if(isset($fields[$baseField]['db_field'])){ if($this->module->changeRecordsStatus($this->module->db->prepData($rows), $fields[$baseField]['db_field'])) return true; } } cJSON::sendError(); return false; } /** * Function to delete records marked in table * * @author Mareks Keišs * @category sysSiteMap Controller * @param string $rows - passed user ids in JSON string * @return bool */ public function delete($rows) { // Decode json string if($rows = cJSON::decode($rows, true)){ $rows = $this->module->db->prepData($rows); // Chk if id = ref id if it is then update ref id for the remaining pages; $d = $this->chkIdForRefId($rows); if(!!$d['idsToDelete'] && is_array($d['idsToDelete'])){ // Load all menus linked to deleted modules $mnu = $this->module->getMenusByMapId($d['idsToDelete']); if($this->module->deleteRecords($d['idsToDelete'])){ // Drop apc $this->dropAPC($d['idsToDelete'], $mnu); // Update ref ids if(!!$d['sqlUpdateRefIds'] && strlen($d['sqlUpdateRefIds']) > 0) $this->module->updateRefIds($d['sqlUpdateRefIds']); return true; } }else{ return false; } } cJSON::sendError(); return false; } /** * Function to delete records marked in table * * @author Aivars Žukovskis * @category sysSiteMap Controller * @param array $ids - array with map nodes id's * @return bool|array of data */ public function chkIdForRefId($ids){ if(!!$ids && is_array($ids)){ $sSqlUpdate = ""; // Chk the ref id for each id $d = $this->module->chkIdsForRefIds($ids); // If we get any ids whose ref id is the same as its id if($d[self::REF_ID_THE_SAME]){ // Get all ids with the same ref id $dd = $this->module->getIdsByLangRefIds($d[self::REF_ID_THE_SAME]); if(!!$dd && is_array($dd)){ foreach($dd as $refId => $v){ $newRefId = 0; $nn = array(); // If we got more then 1 ( the 1 we get is the same as the ref id ) if(count($v) > 1){ foreach($v as $id){ // If its the same we add it to delete ( as requested ) if($refId == $id){ $d[self::REF_ID_DIFF][] = $id; // If its not in delete list we add it to array that will update the refs ids; }else if(!in_array($id, $d[self::REF_ID_DIFF])){ $newRefId = $id; $nn[] = $id; } } // Create sqlUpdate string; if(!!$nn && count($nn) > 0 && $newRefId > 0) $sSqlUpdate .= " UPDATE site_map SET p_lang_ref_id = {$newRefId} WHERE id IN (". implode(",", $nn) .");"; unset($nn, $newRefId); // Else we just add this one to delete }else{ if(empty($d[self::REF_ID_DIFF])) $d[self::REF_ID_DIFF] = array(); $d[self::REF_ID_DIFF] = array_merge($d[self::REF_ID_DIFF], $v); } } } unset($d[self::REF_ID_THE_SAME], $dd); } return array('idsToDelete' => $d[self::REF_ID_DIFF], 'sqlUpdateRefIds' => $sSqlUpdate); } return false; } /** * Function to get table record data for edit mode * * @author Mareks Keišs * @category sysSiteMap Controller * @param int $id - record id * @return array of data */ public function editCmsTableRecord($id) { $data = array(); if($id){ $ids = array(); $dataToView = array('isRoot' => false); // Get language reference id; $refId = $this->module->getRefIdById($id); $mnu = array(); // Get base data by reference id; if($d = $this->module->getModuleRecordsForEdit($refId)){ foreach($d as $k => &$v){ $v['p_title'] = prepForDisplayHtml($v['p_title']); $v['p_keywords'] = prepForDisplayHtml($v['p_keywords']); $v['p_description'] = prepForDisplayHtml($v['p_description']); // Set normal date format from unix time stamp; $v['p_created'] = date($this->CMSDateFormat, $v['p_created']); // Set normal date format from unix time stamp; $v['p_modified'] = date($this->CMSDateFormat, $v['p_modified']); // Check root edited if(!!$v['p_url'] && $v['p_url'] == ADMINISTRATION_FOLDER) $dataToView['isRoot'] = true; // Set parent url; if(!!$v['p_url'] && !!$v['p_parent']) $v['parent_url'] = $v['p_parent'] == self::PUB_SITE_ID ? '/' : "{$v['parent_url']}"; // Set full url $v['full_url'] = !!$v['p_full_url'] ? $v['p_full_url'] : ""; if(!!$v['p_permission'] && !!$k) $v['p_permission_name'] = $this->module->getAddedPermissionById(($v['p_type'] ? self::DB_TABLE_SYS_PERMISSIONS : self::DB_TABLE_PUB_PERMISSIONS), $v['p_permission']); // Get page menus; if($v["p_menus"] == '1'){ $v["p_menus"] = array( "load_menus" => $this->module->getPageMenus($v['id'], self::MENU_LOADED, $this->PUB_SIDE ? 1 : 0), "link_menus" => $this->module->getPageMenus($v['id'], self::MENU_LINKED, $this->PUB_SIDE ? 1 : 0), ); $mnu = array_merge($mnu, $v["p_menus"]["load_menus"],$v["p_menus"]["link_menus"]); } // Check the redirect url if(!!$v['p_redirect_url'] && strlen($v['p_redirect_url']) > 1){ if(substr($v['p_redirect_url'], 0, 1) === "/"){ $v['p_redirect_url'] = substr($v['p_redirect_url'], 1); $v['red_url'] = "/"; } else if(substr($v['p_redirect_url'], 0, 7) === "http://"){ $v['p_redirect_url'] = substr($v['p_redirect_url'], 7); $v['red_url'] = "http://"; } }else{ $v['red_url'] = "/"; } // Get each page language id; $ids[$k] = $v['id']; $dataToView[$k]['id'] = $v['id']; if($v['id'] == $id) $dataToView[$k]['sel'] = 1; $data[$k]['b'] = $v; } $data['m'] = $mnu; unset($v, $d, $mnu); // Get all used modules if(!!$ids && is_array($ids)){ $modules = $this->module->getUsedModulesForEdit($ids); foreach($ids as $langId => $id){ if(!empty($modules[$id][self::JS_MOD]) && is_array($modules[$id][self::JS_MOD])){ foreach($modules[$id][self::JS_MOD] as $vv){ if(file_exists(__JS__ . $vv['mod_code'] . '.js')){ $data[$langId]['mod']['js'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $data[$langId]['mod']['js'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__JS__ . $vv['mod_code'] . '.js'); } } } if(!empty($modules[$id][self::CSS_MOD]) && is_array($modules[$id][self::CSS_MOD])){ foreach($modules[$id][self::CSS_MOD] as $vv){ if(file_exists(__CSS__ . $vv['mod_code'] . '.css')) { $data[$langId]['mod']['css'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $data[$langId]['mod']['css'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__CSS__ . $vv['mod_code'] . '.css'); } } } if(!empty($modules[$id][self::APP_CMS_MOD]) && is_array($modules[$id][self::APP_CMS_MOD])){ foreach($modules[$id][self::APP_CMS_MOD] as $vv){ $data[$langId]['mod']['app']['mod_code'] = $vv['mod_code']; $data[$langId]['mod']['app']['mod_action'] = ($vv['mod_call_method'] == "" ? "run" : $vv['mod_call_method'] ); } } if(!empty($modules[$id][self::APP_PUB_MOD]) && is_array($modules[$id][self::APP_PUB_MOD])){ foreach($modules[$id][self::APP_PUB_MOD] as $vv){ $data[$langId]['mod']['app']['mod_code'] = $vv['mod_code']; $data[$langId]['mod']['app']['mod_action'] = ($vv['mod_call_method'] == "" ? "run" : $vv['mod_call_method'] ); } } } } // set read only data to view; $this->oView->ReadOnly = $dataToView; } } // Set login data $loginMapId = $this->PUB_SIDE ? self::PUB_LOGIN_MAP_ID : self::SYS_LOGIN_MAP_ID; $this->oView->LOGINDATA = array( 'login_url' => $this->module->getFullUrlById($loginMapId), 'id' => $loginMapId ); // Get site languages $lng = new sysLanguagesModule(); $vLanguages = $lng->getLanguages($this->PUB_SIDE); if(!$this->PUB_SIDE){ foreach($vLanguages as $k=>$v) if(!$v['default']) unset($vLanguages[$k]); } $this->oView->lang = $vLanguages; // get site templates $this->oView->templates = $this->oView->getTemplates(); // Get page actions $this->oView->PAGE_ACTIONS = $this->getPageActions(); // Set on view whether its cms or app; $this->oView->ISCMS = $this->PUB_SIDE ? false : true; return array( 'show' => array('buttons_top' => false, 'buttons_bottom' => true), 'btn' => $this->getFormButtons(), 'html' => $this->oView->genTemplate('editNode'), 'data' => $data, ); } /** * Function to clone a table record * * @author Aivars Žukovskis * @category sysSiteMap Controller * @param int $id - record id * @return array of data */ public function cloneBlank($id) { $data = array(); if($id){ $ids = array(); $mnu = array(); // Base data if($d = $this->module->getModuleRecordsForEdit($id, true)){ foreach($d as $k => &$v){ if(!!$v['p_permission'] && !!$k) $v['p_permission_name'] = $this->module->getAddedPermissionById(($k == 1 ? self::DB_TABLE_SYS_PERMISSIONS : self::DB_TABLE_PUB_PERMISSIONS), $v['p_permission']); // Get page menus; if($v["p_menus"] == '1'){ $v["p_menus"] = array( "load_menus" => $this->module->getPageMenus($id, self::MENU_LOADED, $this->PUB_SIDE ? 1 : 0), "link_menus" => $this->module->getPageMenus($id, self::MENU_LINKED, $this->PUB_SIDE ? 1 : 0), ); $mnu = array_merge($mnu, $v["p_menus"]["load_menus"],$v["p_menus"]["link_menus"]); } $ids[$k] = $id; $data[$k]['b'] = $v; } $data['m'] = $mnu; unset($v, $d, $mnu); // Get all used modules $modules = $this->module->getUsedModulesForEdit($ids); foreach($ids as $langId => $id){ if(!empty($modules[$id][self::JS_MOD]) && is_array($modules[$id][self::JS_MOD])){ foreach($modules[$id][self::JS_MOD] as $vv){ $data[$langId]['mod']['js'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $data[$langId]['mod']['js'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__JS__ . $vv['mod_code'] . '.js'); } } if(!empty($modules[$id][self::CSS_MOD]) && is_array($modules[$id][self::CSS_MOD])){ foreach($modules[$id][self::CSS_MOD] as $vv){ $data[$langId]['mod']['css'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $data[$langId]['mod']['css'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__CSS__ . $vv['mod_code'] . '.css'); } } if(!empty($modules[$id][self::APP_CMS_MOD]) && is_array($modules[$id][self::APP_CMS_MOD])){ foreach($modules[$id][self::APP_CMS_MOD] as $vv){ $data[$langId]['mod']['app']['mod_code'] = $vv['mod_code']; $data[$langId]['mod']['app']['mod_action'] = ($vv['mod_call_method'] == "" ? "run" : $vv['mod_call_method'] ); } } if(!empty($modules[$id][self::APP_PUB_MOD]) && is_array($modules[$id][self::APP_PUB_MOD])){ foreach($modules[$id][self::APP_PUB_MOD] as $vv){ $data[$langId]['mod']['app']['mod_code'] = $vv['mod_code']; $data[$langId]['mod']['app']['mod_action'] = ($vv['mod_call_method'] == "" ? "run" : $vv['mod_call_method'] ); } } } } } // Set login data $loginMapId = $this->PUB_SIDE ? self::PUB_LOGIN_MAP_ID : self::SYS_LOGIN_MAP_ID; $this->oView->LOGINDATA = array( 'login_url' => $this->module->getFullUrlById($loginMapId), 'id' => $loginMapId ); // get site languages $lng = new sysLanguagesModule(); $this->oView->lang = $lng->getLanguages($this->PUB_SIDE, true); // get site templates $this->oView->templates = $this->oView->getTemplates(); // Get page actions $this->oView->PAGE_ACTIONS = $this->getPageActions(); // Set on view whether its cms or app; $this->oView->ISCMS = $this->PUB_SIDE ? false : true; return array( 'show' => array('buttons_top' => false, 'buttons_bottom' => true), 'btn' => $this->getFormButtons(), 'html' => $this->oView->genTemplate('editNode'), 'data' => $data, ); } /** * Function to save Record data * * @author Mareks Keišs * @category sysSiteMap Controller * @param string $fields - param JSON string * @return bool|json of data */ public function saveRecordData($fields) { if($fields) $fields = $this->getSubmittedDataAsArray($fields); // Start save process if($fields){ // Validate fields $valid = new cValidator($this); $errors = $valid->checkArrayAdvance($fields, $this->getValCfg()); if(!!$errors) cJSON::sendError(array('data' => $errors)); // Create base data array $update = array(); $updateSql = ""; $modUpdate = array(); $menusUpdate = array(); // Create array for menu apc drop $mnu = array(); // Array for ids; $ids = array(); $deletedPages = ""; if($this->PUB_SIDE){ $mod_type = self::APP_PUB_MOD; $type = self::PUB_TYPE; $logInMapId = self::PUB_LOGIN_MAP_ID; $basePageId = self::PUB_SITE_ID; }else{ $mod_type = self::APP_CMS_MOD; $type = self::CMS_TYPE; $logInMapId = self::SYS_LOGIN_MAP_ID; $basePageId = self::CMS_SITE_ID; } // Check if any page has been deleted; if($fields["deletedPages"]) $deletedPages = $fields["deletedPages"]; unset($fields["deletedPages"]); $time = time(); $bIsRoot = false; // Base data foreach($fields as $lang_id => $d){ if(!empty($d["b"]) && is_array($d["b"])){ $ids[$lang_id] = 0; $update[$lang_id] = array( // Link settings "p_title" => $d["b"]["p_title"], "p_parent" => (!empty($d["b"]["p_parent"]) ? $d["b"]["p_parent"] : 0), // parent url id "p_url" => $d["b"]["p_url"], // page url "p_order" => (!empty($d["b"]["p_order"]) ? $d["b"]["p_order"] : 0), "p_redirect_url" => (!empty($d["b"]["p_redirect_url"]) ? (!empty($d['b']['red_url']) ? $d['b']['red_url'] : '') . $d["b"]["p_redirect_url"] : ''), "p_login_redirect" => "", // Link settings / CheckBoxes "p_enabled" => (!empty($d["b"]['p_enabled']) ? 1: 0), "p_visible" => (!empty($d["b"]['p_visible']) ? 1 : 0), "p_autocache" => (!empty($d["b"]['p_autocache']) ? 1 : 0), "p_st_cnt" => (!empty($d["b"]['p_st_cnt']) ? 1 : 0), "p_default" => (!empty($d["b"]['p_default']) ? 1 : 0), "p_login" => (!empty($d["b"]['p_login']) ? 1 : 0), "p_2fa" => (!empty($d["b"]['p_2fa']) ? 1 : 0), "p_404" => (!empty($d["b"]['p_404']) ? 1 : 0), "p_sitemap" => (!empty($d["b"]['p_sitemap']) ? 1 : 0), // Simple settings "p_description" => (!empty($d["b"]["p_description"]) ? $d["b"]["p_description"] : ''), "p_keywords" => (!empty($d["b"]["p_keywords"]) ? $d["b"]["p_keywords"] : ''), "p_fulltitle" => (!empty($d["b"]["p_fulltitle"]) ? $d["b"]["p_fulltitle"] : ''), "p_template_id" => (!empty($d["b"]["p_template_id"]) ? $d["b"]["p_template_id"] : 0), // Rest "p_lang_id" => $lang_id, "p_permission" => (!empty($d["b"]["p_permission"]) ? $d["b"]["p_permission"] : 0), "p_menus" => (!empty($d["b"]["p_menus"]) ? 1 : 0), "p_modified_user_id" => $this->oUser->getUser(), "p_modified" => $time, "p_type" => $type, "p_lang_ref_id" => $time, ); // Set Login url & id if($update[$lang_id]['p_login']){ $update[$lang_id]['p_req_login'] = $logInMapId; $update[$lang_id]['p_login_redirect'] = $this->module->getFullUrlWithLangCodeById($logInMapId, $lang_id, !$this->oUrl->_showDefault, $this->oUrl->_endSlash); } // Check root edited if(!$bIsRoot && $update[$lang_id]['p_url'] == ADMINISTRATION_FOLDER) $bIsRoot = true; // Set parent to base page if no parents given; if($update[$lang_id]['p_parent'] == 0){ if(!$bIsRoot){ $basePageUrl = $this->module->getFullUrlById($basePageId); $update[$lang_id]['p_parent'] = $basePageId; $update[$lang_id]['p_full_url'] = "/{$update[$lang_id]['p_url']}/"; // If cms side update full url too if(!$this->PUB_SIDE) $update[$lang_id]['p_full_url'] = (!!$basePageUrl && strlen($basePageUrl) > 0 ? $basePageUrl : "/") . $update[$lang_id]['p_url'] . "/"; } }else{ // Get parent full url and create full url for page $vParentPage = $this->module->getFullUrlByIdSpecial($update[$lang_id]['p_parent'], $lang_id); if(empty($vParentPage['p_full_url'])){ $vParentPage = array( 'p_full_url' => "/" ); $update[$lang_id]['p_parent'] = ($this->PUB_SIDE ? self::PUB_SITE_ID : self::CMS_SITE_ID); }else{ $update[$lang_id]['p_parent'] = $vParentPage['id']; } $update[$lang_id]['p_full_url'] = "{$vParentPage['p_full_url']}{$update[$lang_id]['p_url']}/"; } if(!empty($d["b"]["id"]) && $d["b"]["id"] != 0){ $ids[$lang_id] = $d["b"]["id"]; // If id then generate sql string instead of array of data with id and unset that key from update; $updateSql .= $this->createSqlQuery($update[$lang_id], $d["b"]["id"]); unset($update[$lang_id]); }else{ // Set created time if no id; $update[$lang_id]['p_created'] = time(); } // Insert loadable menus if(!empty($d["b"]["p_menus"]["load_menus"]) && is_array($d["b"]["p_menus"]["load_menus"])){ foreach($d["b"]["p_menus"]["load_menus"] as $v){ if($v){ $menusUpdate[] = array( 'map_id' => &$ids[$lang_id], 'menu_id' => $v['id'], 'menu_type' => self::MENU_LOADED ); $mnu[$v['id']] = 1; } } } // Insert linked menus if(!empty($d["b"]["p_menus"]['link_menus']) && is_array($d["b"]["p_menus"]["link_menus"])){ foreach($d["b"]["p_menus"]['link_menus'] as $v){ if($v){ $menusUpdate[] = array( 'map_id' => &$ids[$lang_id], 'menu_id' => $v['id'], 'menu_type' => self::MENU_LINKED ); $mnu[$v['id']] = 1; } } } } // Modules if(!empty($d["mod"]) && is_array($d["mod"])){ if(!empty($d["mod"]["app"]) && is_array($d["mod"]["app"])){ $modUpdate[] = array( 'mod_map_id' => &$ids[$lang_id], 'mod_type' => $mod_type, 'mod_code' => $d["mod"]["app"]["mod_code"], 'mod_primary' => '1', 'mod_call_method' => $d["mod"]["app"]["mod_action"], 'mod_use_tmpl' => $d["b"]["mod_use_tmpl"], 'mod_load_order' => 1 ); } if(!empty($d["mod"]['js']) && is_array($d["mod"]["js"])){ foreach($d["mod"]['js'] as $k => $v){ $modUpdate[] = array( 'mod_map_id' => &$ids[$lang_id], 'mod_type' => self::JS_MOD, 'mod_code' => $v['v'], 'mod_primary' => '0', 'mod_call_method' => '', 'mod_use_tmpl' => '', 'mod_load_order' => $k ); } } if(!empty($d["mod"]['css']) && is_array($d["mod"]["css"])){ foreach($d["mod"]['css'] as $k => $v){ $modUpdate[] = array( 'mod_map_id' => &$ids[$lang_id], 'mod_type' => self::CSS_MOD, 'mod_code' => $v['v'], 'mod_primary' => '0', 'mod_call_method' => '', 'mod_use_tmpl' => '', 'mod_load_order' => $k ); } } } } // Loop through the menus we got from edit; if(!empty($fields["m"]) && is_array($fields["m"])){ foreach($fields["m"] as $v){ // Add menus to apc drop if(!empty($mnu[$v['id']])) $mnu[$v['id']] = 1; } } // Update / Insert record data if ($this->module->saveRecordDataById($update, $updateSql)) { // Delete pages if we got any deletePage if ($deletedPages) $this->module->deleteRecords(explode(",", $deletedPages)); // Get ids for each inserted language; if ($i = $this->module->getIdToLangId($time)) { // Set ids to ids array; foreach ($i as $lng => $id) { $ids[$lng] = $id; // Update path if needed if (!$bIsRoot) $this->updateAllsubNodeUrls($id, false, $lng); } // Update menus if (!$this->module->updateMenuData($ids, $menusUpdate)) cJSON::sendError("Error on insert/updating menus!"); // Update site map modules if (!($this->module->saveRecordDataModuleById($ids, $modUpdate))) cJSON::sendError("something went wrong while saving modules data"); // Update ref ids if (!($this->module->updateRefId($ids, firstE($ids)))) cJSON::sendError("something went wrong while updating reference id"); } else { cJSON::sendError("Something went wrong on getting ids for each inserted language!"); } } else { cJSON::sendError("Something went wrong while inserting base data!"); } $this->dropAPC($ids, array_keys($mnu)); cJSON::sendOk(array('ids' => $ids)); } return false; } /** * Function to create table headers + search * * @author Mareks Keišs * @category sysSiteMap Controller * @return bool|array of data * @version 1.1 */ public function getTableFieldsPub(){ $this->PUB_SIDE = true; return $this->getTableFields(); } public function getTableFields(){ if(!$this->chkP(($this->PUB_SIDE? 'CMS_APP_' : 'SYS_') . 'SITE_MAP_SHOW_MANAGEMENT')) return false; if($this->PUB_SIDE){ $type = self::PUB_TYPE; $lang = self::DEFAULT_LANG; }else{ $type = self::CMS_TYPE; $lang = self::CMS_LANG; } $parents = array(''=> array('title' => $this->gM("-- Select --")), 524 => array('title' => $this->gM("Site"))) + $this->module->getAllPagesUrls($type , $lang, true); // Set languages for translatable data $langs = new sysLanguagesModule(); $l = $langs->getLanguages($this->PUB_SIDE ? 1 : 0); $languages = array(''=> array('title' => $this->gM("-- Select --"))); $defaultLangId = 0; foreach($l as $v){ $languages[$v['id']] = array( 'title' => $v['lang_title'] ); if($v['default']) $defaultLangId = $v['id']; } $vDefaultDropBoxVal = array( '' => array('title' => $this->gM("Select")), 0 => array('title' => $this->gM("Disabled")), 1 => array('title' => $this->gM("Enabled")) ); $tFields = array( "checkbox" => array( 'sort' => false, 'title' => '', 'class' => 'w4 center rchk' ), "id" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("ID"), 'class' => 'w8 center sortDesc sort', 'db_field' => 'sm.id', 'type' => 'input', ), "p_order" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("Order"), 'class' => 'w8 center sort', 'db_field' => 'sm.p_order', 'type' => 'input', ), "p_title" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("Title"), 'class' => 'w18 sort', 'db_field' => 'sm.p_title', 'type' => 'input', ), "p_full_url" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("Full url"), 'class' => 'w25 left', 'db_field' => 'sm.p_full_url', 'default' => '', 'type' => 'input', ), "lang_title" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("Language"), 'class' => 'w10 center', 'db_field' => 'sm.p_lang_id', 'type' => 'dropBox', 'data' => $languages, 'default' => $defaultLangId, ), "lang_code" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("/code"), 'class' => 'w7 center', 'db_field' => 'll.lang_code', 'type' => 'input', ), "parent_title" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("Parent"), 'class' => 'w12 left', 'db_field' => 'sm.p_parent', 'type' => 'dropBox', 'data' => $parents, 'default' => '', ), "p_lang_ref_id" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("Ref Id"), 'class' => 'w8 center', 'db_field' => 'sm.p_lang_ref_id', 'type' => 'input', ), "user_name" => array( 'sort' => true, 'search' => true, 'title' => $this->gM("Modified by"), 'class' => 'w12', 'db_field' => 'us.user_name', 'type' => 'input', ), "p_created" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("Created"), 'class' => 'w10 center', 'db_field' => 'sm.p_created', 'type' => 'input', ), "p_modified" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("Modified"), 'class' => 'w10 center', 'db_field' => 'sm.p_modified', 'type' => 'input', ), "enabled" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("Enable"), 'class' => 'w7 center', 'field' => 'p_enabled', 'db_field' => 'sm.p_enabled', 'type' => 'dropBox', 'checkbox' => 1, 'data' => $vDefaultDropBoxVal, 'default' => '', ), "visible" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("Visible"), 'class' => 'w7 center', 'field' => 'p_visible', 'db_field' => 'sm.p_visible', 'type' => 'dropBox', 'checkbox' => 1, 'data' => array( '' => array('title' => $this->gM("Select")), 0 => array('title' => $this->gM("Invisible")), 1 => array('title' => $this->gM("Visible")) ), 'default' => '', ), "sitemap" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("SiteMap"), 'class' => 'w7 center', 'field' => 'p_sitemap', 'db_field' => 'sm.p_sitemap', 'type' => 'dropBox', 'checkbox' => 1, 'data' => array( '' => array('title' => $this->gM("Select")), 0 => array('title' => $this->gM("Invisible")), 1 => array('title' => $this->gM("Visible")) ), 'default' => '', ), "autocache" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("Autocache"), 'class' => 'w7 center', 'field' => 'p_autocache', 'db_field' => 'sm.p_autocache', 'type' => 'dropBox', 'checkbox' => 1, 'data' => $vDefaultDropBoxVal, 'default' => '', ), "2fa" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("2FA"), 'class' => 'w7 center', 'field' => 'p_2fa', 'db_field' => 'sm.p_2fa', 'type' => 'dropBox', 'checkbox' => 1, 'data' => $vDefaultDropBoxVal, 'default' => '', ), "p_default" => array( 'sort' => true, 'search' => false, 'title' => $this->gM("Default"), 'class' => 'w7 center', 'field' => 'p_default', 'db_field' => 'sm.p_default', ), /*"login" => array( 'sort' => false, 'search' => false, 'title' => $this->gM("Login"), 'class' => 'w7 center', 'field' => 'p_login', 'db_field' => 'sm.p_login', 'type' => 'dropBox', 'checkbox' => 1, 'data' => $vDefaultDropBoxVal, 'default' => '', ),*/ "buttons" => array( 'sort' => false, 'class' => 'w20', 'title' => $this->gM("Actions"), 'btnset' => array( 'ledit' => array( 'edit' => true, 'title' => $this->gM("Edit"), ), 'ldelete' => array( 'title' => $this->gM("Delete"), ) ) ) ); if(!$this->chkP('SYS_SHOW_TABLE_IDS')) unset($tFields['id']); return $tFields; } /** * Function to get js translations for view * * @author Mareks Keišs * @category sysSiteMap Controller * @return array of data */ public function getTranslations(){ return array( 'yes' => $this->gM('Yes'), 'no' => $this->gM('No'), 'delTitle' => $this->gM('Delete Entry?'), 'delMessage' => $this->gM('Selected entries will be permanently deleted and cannot be recovered. Confirm delete?'), 'buttonYes' => $this->gM('Delete selected entries'), 'buttonCancel' => $this->gM('Cancel operation'), 'generateSiteMapXml' => $this->gM('Generate site map xml'), 'generateSiteMapXmlDone' => $this->gM('Site map xml generation done!'), ); } /** * Function to get table actions * * @author Mareks Keišs * @category sysSiteMap Controller * @return array of data */ public function getTableActions(){ $data = array( 'inew' => array( 'lbl' => $this->gM("Add new"), 'icon' => 'nico-add' ), 'icloneBlank' => array( 'lbl' => $this->gM("Clone selected row as new"), 'icon' => 'nico-clone', ), 'sepline', 'igensql' => array( 'lbl' => $this->gM("Gen. insert sql"), 'icon' => 'nico-gensql', ), 'igenxml' => array( 'lbl' => $this->gM("Gen. XML's - sitemap | Kurpirkt | Salidzini"), 'icon' => 'nico-genxml', ), 'sepline', 'idelete' => array( 'lbl' => $this->gM("Delete selected"), 'sepline' => true, 'icon' => 'nico-delete' ), 'sepline', 'minify_css' => array( 'lbl' => $this->gM("Minify css"), 'icon' => 'cache-css' ), 'minify_js' => array( 'lbl' => $this->gM("Minify js"), 'icon' => 'cache-js' ), 'clear_cache' => array( 'lbl' => $this->gM("Clear cache"), 'icon' => 'nico-clear' ), 'sepline', 'iGetUnusedModules' => array( 'lbl' => $this->gM("Show unused modules"), 'sepline' => false, 'icon' => 'unused-mods' ), 'iChangeFolder' => array( 'lbl' => $this->gM("Change Administration folder"), 'sepline' => false, 'icon' => 'admin-folder' ), 'sepline', 'iDeleteTempTables' => array( 'lbl' => $this->gM("Delete temporary table records from DB"), 'sepline' => false, 'icon' => 'nico-delete-all' ), ); if(!$this->chkP("SYS_SITE_MAP_ADMIN_FOLDER_CHANGE") || $this->PUB_SIDE) unset($data['iChangeFolder']); // Reform drop down reformatDropDown($data); return $data; } /** * Function to get page actions * * @author Aivars Žukovskis * @category sysSiteMap * @return array of data */ public function getPageActions(){ return array( 'p_created' => array( 'msg' => $this->gM('Created:'), ), 'p_modified' => array( 'msg' => $this->gM('Modified:'), ), 'user_name' => array( 'msg' => $this->gM('Modified by:'), ), 'copy_to_all' => array( 'lbl' => $this->gM("Copy To All Languages (*Everything*)"), ), ); } /** * Function to get js validator cfg * * @author Aivars Žukovskis * @category sysSiteMap Controller * @param bool $admin_folder = admin folder * @return array of data */ public function getValCfg($admin_folder = false){ // get site languages $lng = new sysLanguagesModule(); $sysLang = $lng->getLanguages($this->PUB_SIDE); $data = array(); if ($admin_folder){ $data["a_folder"] = array( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_ADDS => array( 'min' => 5, 'max' => 32, ), 'test' => array( cValidator::CHK_URL_SEGM, cValidator::CHK_LEN ), ); }else{ $data = array( "p_title" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => array(cValidator::CHK_STR), ), "p_order" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 0, cValidator::P_TEST => array(cValidator::CHK_NUM), ), "p_url" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => array(cValidator::CHK_URL_SEGM), ), "p_redirect_url" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 0, cValidator::P_TEST => array(cValidator::CHK_STR), ), "p_description" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 0, cValidator::P_TEST => array(cValidator::CHK_STR), ), "p_keywords" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 0, cValidator::P_TEST => array(cValidator::CHK_STR), ), "mod_use_tmpl" => array ( cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 0, cValidator::P_TEST => array(cValidator::CHK_STR), 'on' => 'change', ) ); } return $data; } /** * Function to get form buttons * * @author Mareks Keišs * @category sysSiteMap Controller * @return array of data */ public function getFormButtons(){ return array( 1 => array( 'id' => 'fsave', 'lbl' => $this->gM('Save') ), 2 => array( 'id' => 'fcancel', 'lbl' => $this->gM('Cancel') ) ); } /** * Function to get parents by language id * * @author Aivars Žukovskis * @category cms sysSiteMap Controller * @param array $id - language id * @return array with data */ public function getParentsByLanguageId($id) { $pages = $this->module->getAllPagesUrls(($this->PUB_SIDE ? self::PUB_TYPE : self::CMS_TYPE), $id['lang_id']); if($pages){ if($id['id']) $pages = $this->unsetUnusableElements($id['id'], $pages); foreach($pages as &$v) foreach($v as $vv) $vv['parent_url'] = "{$vv['parent_url']}"; } $this->oView->PP = $pages; return array( 'html' => $this->oView->genTemplate('dialogBox/parentReqChz') ); } /** * Function to get all site permissions * * @author Aivars Žukovskis * @category cms sysSiteMap Controller * @return array - html data */ public function getPermissions() { $this->oView->PP = $this->module->getSitePermissions($this->PUB_SIDE ? "mod_permissions" : "site_permissions"); return array( 'html' => $this->oView->genTemplate('dialogBox/permissionReqChz') ); } /** * Function to get all site menus * * @author Aivars Žukovskis * @category cms Sys Site Map Controller * @return array - html data */ public function getMenus() { // Get site menus $this->oView->PP = $this->module->getSiteMenus($this->PUB_SIDE ? 1 : 0); return array( 'html' => $this->oView->genTemplate('dialogBox/menusReqChz.twig') ); } /** * Function to unset unusable elements * * @author Aivars Žukovskis * @category cms sysSiteMap Controller * @param int $exclude - exclude id * @param array $data - data to check * @return array of data */ public function unsetUnusableElements($exclude, &$data) { foreach($data as &$v){ if(!empty($v[$exclude])){ foreach($v as $vv){ if($vv['p_parent'] == $v[$exclude]['parent_id']){ $this->unsetUnusableElements($v['parent_id'], $data); unset($vv); } } unset ($v[$exclude]); } } return $data; } /** * Function to get modules * * @category Sys new site map * @author Aivars Žukovskis * @param string $key - if its app module/js module or css; * @param int $language - which language to use ? * @param bool $reload - if its on reload or not; * @return array */ public function getModules($key, $language, $reload = false) { $data = []; $returnArray = []; $this->oView->LIST_HEADER = $this->getModulesFields(); if ($key == "app_modules") { if ($this->PUB_SIDE) { $data = $this->getAllFilesRec(__APP__, "_app", true, false, $reload); } else { $data = array_merge( $this->getAllFilesRec(__CMS__, "_cms", true, false, $reload), $this->getAllFilesRec(__CMSSYS__, "_sys", true, false, $reload) ); } $this->oView->LIST_DATA = $data; $returnArray['app_modules_html'] = $this->oView->genTemplate("dialogBox/load-table-module"); } else { // Get all pages ids and names and set it to view; $this->oView->PAGE_LIST_DATA = $this->module->getUsedModulesForAllPages($language); // Set JS $this->oView->LIST_DATA = $this->getAllFilesRec(__JS__, "_js", false, false, $reload); $returnArray['js_modules_html'] = $this->oView->genTemplate("dialogBox/load-table-css-js"); // Set CSS $this->oView->LIST_DATA = $this->getAllFilesRec(__CSS__, "_css", false, false, $reload); $returnArray['css_modules_html'] = $this->oView->genTemplate("dialogBox/load-table-css-js"); } return $returnArray; } /** * Function to get modules * * @category Sys new site map * @author Aivars Žukovskis * @returns bool|array */ public function getPageUsedModules($id, $d){ if(!!$id){ $type = array(); if($d['css']) $type[] = self::CSS_MOD; if($d['js']) $type[] = self::JS_MOD; $modules = $this->module->getUsedModulesForPageById($id, $type); $m = array(); if(!empty($modules[self::JS_MOD]) && is_array($modules[self::JS_MOD])){ foreach($modules[self::JS_MOD] as $vv){ $m['js'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $m['js'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__JS__ . $vv['mod_code'] . '.js'); } } if(!empty($modules[self::CSS_MOD]) && is_array($modules[self::CSS_MOD])){ foreach($modules[self::CSS_MOD] as $vv){ $m['css'][$vv['mod_load_order']]['v'] = $vv['mod_code']; $m['css'][$vv['mod_load_order']]['id'] = 'm_' . sha1_file(__CSS__ . $vv['mod_code'] . '.css'); } } return $m; } return false; } /** * Function to get modules view table fields * * @category APP pubPostmen Edit * @author Aivars Žukovskis * @return array */ public function getModulesFields(){ return array( "checkbox" => array( 'sort' => false, 'title' => '', 'class' => 'w4 center rchk' ), "n" => array( 'sort' => false, 'search' => true, 'title' => $this->gM("Module"), 'class' => 'w58', 'type' => 'input', ), ); } public function getAllFilesRec($folder, $k, $module = false, $show_cms = false, $reload = false) { if (!($data = $this->oApc->check('cms' . $k)) || $reload == "true") { $c = 0; $perline = 3; $counter = -1; $accActions = ['run']; // Default hidden modules $hidden_files = array(".", "..", ".svn", "module", "smarty", "sample", "url", "pubupdate", "pubcomingsoon"); if(!$show_cms){ // CMS MODULES TO HIDE if ( !( $this->oUser->chkPermission('CMS_LIB_MODULES', false, false) || $this->oUser->chkPermission('EDIT_CMS_TREE', false, false) ) ) { $cms_hidden_modules = [ 'content', 'login', 'settings', 'app messages', 'cms messages', 'startpage', 'user groups', 'site settings', 'main settings', 'languages', 'modules', 'menus', 'user permissions', 'site users', ]; $hidden_files = array_merge($hidden_files, $cms_hidden_modules); } // JS FILES TO HIDE if ( !( $this->oUser->chkPermission('CMS_JS_MODULES', false, false) || $this->oUser->chkPermission('EDIT_CMS_TREE', false, false) ) ) { $cms_hidden_modules = [ 'cms.js', 'cms.json.js', '_cms.jquery-1.6.1.min.js', 'cms.jquery.dynatree.js', 'cms.jquery.cookie.js', 'cms.jquery.dynatree.min.js', 'cms.jquery.contextmenu.js', 'cms.jquery.ui.position.js', 'cms.jquery-ui-1.8.14.custom.min.js', 'cms.chosen.jquery.js', 'cms.chosen.jquery.min.js' ]; $hidden_files = array_merge($hidden_files, $cms_hidden_modules); } } if ($k == '_js') { $mm = $this->getLevelBasedFolderContent($folder, 2, 'js'); foreach ($mm as $v) { $file = $folder . $v; if (file_exists($file)) { $t = array( 'n' => strtolower(substr($v, 0, strrpos($v, '.'))), 'h' => $t['h'] = sha1_file($file), 'c' => false ); $data[] = $t; } } } else if ($k == '_css') { $mm = $this->getLevelBasedFolderContent($folder, 2, 'css'); foreach ($mm as $v) { $file = $folder . $v; if (file_exists($file)) { $t = array( 'n' => strtolower(substr($v, 0, strrpos($v, '.'))), 'h' => $t['h'] = sha1_file($folder . $v), 'c' => false ); $data[] = $t; } } } else { foreach (scandir($folder) as $v) { if (!in_array(strtolower($v), $hidden_files)) { if (!$folder && !is_dir($folder . $v) || $module && is_dir($folder . $v)) { $actions = []; if (!(++$counter % $perline)) { $c++; } // Load next module if ($module) { // Mixed case available - win & unix $v = $this->getFolderFiles($folder . $v . '/', array('php')); $modTitle = $v; $v = getModuleNamespacePath(str_replace(' ', '_', $v)); // Get all functions $ac = get_class_methods(str_replace(' ', '_', $v)); if (count($ac)) { foreach ($ac as $a) { if ( in_array($a, $accActions) || strtoupper(substr($a, strlen($a) - 6)) == 'ACTION' ) { $actions['action'][] = strtolower($a); } } } } $t = array( 'n' => $modTitle, 'h' => $t['h'] = sha1_file($folder . $v), 'c' => false, 'action' => $actions['action'] ); $data[] = $t; } } } } // clear module cache data $this->oApc->setExpired('cms' . $k); $this->oApc->store('cms' . $k, $data); return $data; } else { return $data; } } /** * Function to get folder content based on the level * * @category SYS SITE MAP * @author Mareks Keišs * @param string $dir - directory * @param int/bool $level - how many levels * @param string $mod - css/js * @param array $hidden_files - files to hide * @return array of all available modules */ private function getLevelBasedFolderContent($dir, $level = 2, $mod, $hidden_files = array('.', '..', '.svn', '.ds_store')){ $data = array(); getFolderTree($data, $dir, $hidden_files, array($mod), $level, '', false); return $this->createLevelBasedFolder($data); } private function createLevelBasedFolder($data, $addin = ''){ foreach($data as $k => $v){ if(is_array($v)){ $data = array_merge($data, $this->createLevelBasedFolder($v, $k)); unset($data[$k]); }else{ if($addin){ $data[$addin .':'. $k] = $addin . '/' . $v; unset($k); } } } return $data; } /** * Function to get folder content * * @category CMS * @author Mareks Keišs * @param string $dir * @param array $ext * @param array $exc * @param bool $sext * @return bool|array of all available modules */ private function getFolderFiles($dir, $ext = array(), $exc = array('.', '..', '.svn', '.ds_store'), $sext = true){ foreach(scandir($dir) as $v){ if(!is_dir($dir . $v) && !in_array(strtolower($v), $exc) && in_array(getExtension($v), $ext)){ if($sext){ return substr($v, 0, strrpos($v, '.')); }else{ return $v; } } } return false; } /** * Function to update all subNode urls * * @category CMS * @author Mareks Keišs * @param int $parent_id - parent id * @param bool/string $preUrl - ... * @param int $lang_id - language id */ public function updateAllSubNodeUrls($parent_id, $preUrl = false, $lang_id){ // If parent url is empty - get preurl if(!$preUrl) $preUrl = $this->getPreUrl($parent_id); // Validate url if(substr($preUrl, 0, 1) != '/') $preUrl = '/' . $preUrl; if(substr($preUrl, strlen($preUrl)-1, 1) != '/') $preUrl .= '/'; // Generate suburls & update $children = $this->module->childUrls($parent_id, $lang_id); if(!!$children && is_array($children)){ foreach($children as $k => $v){ if($v['p_skipurl']){ $deep_url = $preUrl; }else{ $deep_url = $preUrl . $v['p_url'] . '/'; } $this->updateAllsubNodeUrls($v['id'], $deep_url, $lang_id); // Update each full url if(!$v['p_skipurl']) $this->module->updateFullUrl($deep_url, $v['id']); } } } /** * Function to get pre url of node url * * @category CMS * @author Mareks Keišs * @param int $start_node_id - node id to start creating pre node * @return bool|string - response on addin */ private function getPreUrl($start_node_id){ // Generate suburls & update $parent = $this->module->genSubUrl($start_node_id); if(!!!$parent){ return ''; }else{ if($parent['p_enabled']){ if($uri = $this->getPreUrl($parent['p_parent'])){ if(!$parent['p_skipurl']){ return $uri . $parent['p_url'] . '/'; }else{ return $uri; } }else{ if($uri === false){ return false; }else{ if(!$parent['p_skipurl']){ return '/' . $parent['p_url'] . '/'; }else{ return ''; } } } }else{ return false; } } } /** * Function to create sql query * * @category CMS * @author Aivars Žukovskis * @param array $update - array with data * @param int $id - node id * @return string */ private function createSqlQuery($update, $id){ $sSql = ""; if(!!$update && is_array($update) && !!$id){ $update = $this->module->db->prepData($update); $id = $this->module->db->prepData($id); foreach($update as $k => $v) $sSql .= ",`" . $k . "` = '" . $v . "'"; $sSql = substr($sSql, 1); $sSql = " UPDATE site_map SET {$sSql} WHERE id = {$id}; "; } return $sSql; } /** * Function to drop apc * * @author Aivars Žukovskis * @category CMS * @param int|array $ids - map id * @param bool|array $menu - array of menus * @return bool */ public function dropAPC($ids, $menu = false){ $keys = array(); $lng = new sysLanguagesModule(); $langs = $lng->getLanguages($this->PUB_SIDE); if(!!$ids && is_array($ids)){ foreach($ids as $val) $keys[] = "map_{$val}_menus"; } if(!!$menu && is_array($menu)){ $menu = $this->module->db->prepData($menu); foreach($menu as $val) foreach($langs as $v) $keys[] = "menu_{$val}_l" . $v['id']; } // Delete APC for selected modules $this->oApc->setExpired($keys); return true; } /** * Function to minify modules * * @author Mareks Keišs * @category sysSiteMap Controller * @return bool */ public $foldersToSkip = array('.', '..'); public function minify($bJs = false){ $cMin = new cMinify(); $FILE_TYPE = $cMin::FILE_TYPE_CSS; $const = '__CSS__'; $sDir = __CSS__; $ext = 'css'; if($bJs){ $FILE_TYPE = $cMin::FILE_TYPE_JS; $const = '__JS__'; $sDir = __JS__; $ext = 'js'; } if(defined($const) && defined('__CACHE__')){ foreach(scandir($sDir) as $v){ $fileName = $sDir . $v; if(file_exists($fileName)){ if(is_dir($fileName)){ $baseName = basename($fileName); if(!in_array($baseName, $this->foldersToSkip)){ $mm = $this->getLevelBasedFolderContent($fileName, 2, $ext, array('.', '..', '.svn', '.ds_store','tinymce','tinymcenew','fileupload')); if(!empty($mm) && is_array($mm)){ // Create folder if(!file_exists(__CACHE__ . $baseName)) mkdir(__CACHE__ . $baseName); // Create files foreach($mm as $file) $cMin->minifyCssOrJsFileV2("{$fileName}/{$file}" , $FILE_TYPE, false, $baseName, true); } } }else{ $cMin->minifyCssOrJsFileV2($fileName, $FILE_TYPE, false, false, true); } } } return true; } return false; } /** * Function to manage tree cache actions * * @author Mareks Keišs * @category sysSiteMap Controller * @param string $data - json, string of data to work with * @return array */ public function treeCacheActions($data){ $bError = true; $vReturn = array('err_msg' => $this->gM('Error!'), 'ok_msg' => $this->gM('Successful!')); if(strlen($data)){ $vData = cJSON::decode($data, true); if(!empty($vData) && is_array($vData)){ if(!empty($vData['action']) && strlen($vData['action'])){ switch ($vData['action']){ case 'minify_css': if($this->minify()) $bError = false; break; case 'minify_js': if($this->minify(true)) $bError = false; break; case 'clear_only': if(defined('__CACHE__') && deleteDir(__CACHE__, true)) $bError = false; break; default: break; } } } } // Return msg as json error or simple return for json ok if($bError) cJSON::sendError(array('msg' => $vReturn['err_msg'])); return array('msg' => $vReturn['ok_msg']); } /** * Function to change administration folder name * * @author Aivars Žukovskis * @category cms Sys Site Map Controller * @param string $val - new administration folder name * @return array - new url */ public function changeAdministrationFolder($val) { // Check if field is valid $valid = new cValidator($this); $data = ['a_folder' => $val]; $errors = $valid->checkArray($data, $this->getValCfg(true)); if ($errors !== true) { cJSON::sendError(['data' => $errors]); } // Replace links with new folder name $this->module->replaceLinks(ADMINISTRATION_FOLDER, $val); // Load links $this->links = $this->module->loadLinks($this->uri_data['id']); $this->urlLinks = $this->module->loadUrlLinks($this->uri_data['id']); $oCfg = new cINI(__CFG__ . 'init.cfg.ini', false); $oCfg->setV('ADMINISTRATION_FOLDER', $val, 'system'); $oCfg->writeDataToFile(); return array( 'url' => $this->gL() ); } /** * Function to get all unused site map js and css modules * * @author Aivars Žukovskis * @category cms Sys Site Map Controller * @return array|String - data / smarty tpl */ public function getAllSiteMapUnusedModules() { $unusedModules = array(); // Get all used modules $d = $this->module->getAllUsedSiteMapModules(array(self::CSS_MOD, self::JS_MOD)); $cssUsedMods = $d[self::CSS_MOD]; $jsUsedMods = $d[self::JS_MOD]; // Get all modules $css = $this->getAllFilesRec(__CSS__, "_css", false, false, true); $js = $this->getAllFilesRec(__JS__, "_js", false, false, true); // Loop and get all unused foreach($css as $v){ if(!$cssUsedMods[$v['n']]) { $unusedModules['css'][$v['h']]['n'] = $v['n']; $unusedModules['css'][$v['h']]['h'] = $v['h']; } } foreach($js as $v){ if(!$jsUsedMods[$v['n']]){ $unusedModules['js'][$v['h']]['n'] = $v['n']; $unusedModules['js'][$v['h']]['h'] = $v['h']; } } $this->oView->CSS = $unusedModules['css']; $this->oView->JS = $unusedModules['js']; unset($d, $cssUsedMods, $jsUsedMods, $css, $js, $unusedModules); return $this->oView->genTemplate("dialogBox/load-unused-modules"); } public function deleteUnusedModules($data){ if(!empty($data)){ $d = array('deleted' => array(), 'unable' => array()); if(!empty($data['js']) && count($data['js']) > 0){ foreach($data['js'] as $v){ if(file_exists(__JS__ . $v)){ unlink(__JS__ . $v); $d['deleted']['js'][] = $v; }else{ $d['unable']['js'][] = $v; } } } if(!empty($data['css']) && count($data['css']) > 0){ foreach($data['css'] as $v){ if(file_exists(__CSS__ . $v)){ unlink(__CSS__ . $v); $d['deleted']['css'][] = $v; }else{ $d['unable']['css'][] = $v; } } } $this->oView->JS = $d['deleted']['js']; $this->oView->JSx = $d['unable']['js']; $this->oView->CSS = $d['deleted']['css']; $this->oView->CSSx = $d['unable']['css']; return $this->oView->genTemplate("dialogBox/show-deleted-modules"); } return false; } /** * Function to delete from db temporary table content * * @author Aivars Žukovskis * @category system site map Controller * @return array|String - data / smarty tpl */ public function deleteTemporaryDbTableData(){ $cr = new cCron(); $cr->execBDEndCronScripts(); return array('msg' => $this->gM('Successfully cleared DB temporary tables!')); } /** * Function to generate site map insert sql * * @author Aivars Žukovskis * @category system site map Controller * @param string $ids json string * @return array of data * @version 1.1 */ public function generateInsertSql($ids) { if(!!$ids) $ids = json_decode($ids, true); // Get lang ref. id $vLangRefIds = $this->module->getLangRefIdById($ids); // Get all ids by lang ref id $vIds = $this->module->getIdsByLangRefIds($vLangRefIds, true); // Get all data for pages $vBaseData = $this->module->getDataForExportSql('site_map', 'id', $vIds); $vMenusData = $this->module->getDataForExportSql('site_map_menus', 'map_id', $vIds, array('map_id', 'menu_id', 'menu_type')); $vModulesData = $this->module->getDataForExportSql('site_map_modules', 'mod_map_id', $vIds, array('mod_type', 'mod_code', 'mod_map_id', 'mod_primary', 'mod_set_byname', 'mod_call_method', 'mod_use_tmpl', 'mod_load_order') ); if(!empty($vBaseData) && is_array($vBaseData)){ // --------------------------------------------------------------------------------------------------------- // Delete queries // --------------------------------------------------------------------------------------------------------- $sIds = implode(", ", $vIds); $sSqlDeleteSiteMap = "DELETE FROM site_map WHERE id IN ({$sIds});"; $sSqlDeleteMenus = "DELETE FROM site_map_menus WHERE map_id IN ({$sIds});"; $sSqlDeleteModules = "DELETE FROM site_map_modules WHERE mod_map_id IN ({$sIds});"; // --------------------------------------------------------------------------------------------------------- // Site map insert query // --------------------------------------------------------------------------------------------------------- $sSqlInsertSiteMap = ""; $sSqlPt1 = ""; foreach($vBaseData as $v) $sSqlPt1 .= ",\n ('". implode("', '", $v) ."')"; if(strlen($sSqlPt1)) $sSqlInsertSiteMap = "INSERT INTO site_map VALUES " . substr($sSqlPt1, 1) . ";"; // --------------------------------------------------------------------------------------------------------- // Site map menus insert query // --------------------------------------------------------------------------------------------------------- $sSqlInsertMenus = ""; if(!empty($vMenusData) && is_array($vMenusData)){ $sSqlPt1 = ""; foreach($vMenusData as $v) $sSqlPt1 .= ",\n ('". implode("', '", $v) ."')"; if(strlen($sSqlPt1)){ $sSqlInsertMenus = " INSERT INTO site_map_menus (map_id, menu_id, menu_type) VALUES " . substr($sSqlPt1, 1) . "; "; } } // --------------------------------------------------------------------------------------------------------- // Site map modules insert query // --------------------------------------------------------------------------------------------------------- $sSqlInsertModules = ""; if(!empty($vModulesData) && is_array($vModulesData)){ $sSqlPt1 = ""; foreach($vModulesData as $v) $sSqlPt1 .= ",\n ('". implode("', '", $v) ."')"; if(strlen($sSqlPt1)){ $sSqlInsertModules = " INSERT INTO site_map_modules (mod_type, mod_code, mod_map_id, mod_primary, mod_set_byname, mod_call_method, mod_use_tmpl, mod_load_order) VALUES " . substr($sSqlPt1, 1) . "; "; } } return array( 'sql' => array( 'sDeleteSiteMap' => $sSqlDeleteSiteMap, 'sDeleteMenus' => $sSqlDeleteMenus, 'sDeleteModules' => $sSqlDeleteModules, 'sInsertSiteMap' => $sSqlInsertSiteMap, 'sInsertMenus' => $sSqlInsertMenus, 'sInsertModules' => $sSqlInsertModules, 'sDeleteApc' => "DELETE FROM `temp_cache_exp` WHERE `key` <> '%" . cApc::APC_KEY . "';" ) ); } return false; } /** * Function to generate site map xml * * @author Aivars Žukovskis * @category system site map Controller * @return array of data * @version 1.1 */ public function generateSiteMapXML() { $sMsg = 'Unsuccessfully generated site map xml!'; //------------------------------------------------------------ // Check if site map generator present //------------------------------------------------------------ if(class_exists('pubExport')){ $oPubExport = new pubExport(getFirstMatchByMapId(840)); if(method_exists($oPubExport->controller, 'genExportXML')){ $oPubExport->controller->genExportXML(); return array('msg' => 'Successfully generated Xml\'s using pubExport module!'); } } //------------------------------------------------------------ // Continue with default xml generation //------------------------------------------------------------ $bPubSide = true; // $this->controller->PUB_SIDE // For pub side xml $fileName = 'site_map_' . ( $bPubSide ? 'PUB' : 'CMS' ); // Get all languages $modLanguages = new sysLanguagesModule(); $langs = $modLanguages->getLanguages(); if(!!$langs && is_array($langs)){ $files = array(); $this->oView->HOST = $_SERVER['HTTP_HOST']; $this->oView->TODAY = date('Y-m-d\TH:i:s+02:00'); foreach($langs as $l){ $files[] = $fName = "{$fileName}_{$l['lang_code']}.xml"; // Create XML export for active pages if($file = fopen(__MDIR__ . "{$fName}","w+")){ fwrite($file, "\n"); fwrite($file, ""); // Generate site map table $this->oView->DATA = $this->module->getSiteMapTableData($l['id']); fwrite($file, $this->oView->genTemplate('xml/sitemap_index_lang.twig')); $limit = 100; $offset = 0; //-------------------------------------------------------------- // Generate site_map_urls for categories //-------------------------------------------------------------- $data = $this->module->getSiteMapCategoryData($l['id'], $offset, $limit); while(!!$data){ foreach($data as &$v){ $v['loc'] = $this->oUrl->rmSlashesIndex($v['loc']); } unset($v); $offset += $limit; $this->oView->DATA = $data; fwrite($file, $this->oView->genTemplate('xml/sitemap_index_lang.twig')); // Load next data $data = $this->module->getSiteMapCategoryData($l['id'], $offset, $limit); } $limit = 100; $offset = 0; //-------------------------------------------------------------- // Generate site_map_urls for products //-------------------------------------------------------------- $data = $this->module->getSiteMapProductData($l['id'], $offset, $limit); while(!!$data){ foreach($data as &$v){ $v['loc'] = $this->oUrl->rmSlashesIndex($v['loc']); } unset($v); $offset += $limit; $this->oView->DATA = $data; fwrite($file, $this->oView->genTemplate('xml/sitemap_index_lang.twig')); // Load next data $data = $this->module->getSiteMapProductData($l['id'], $offset, $limit); } fwrite($file, ''); fclose($file); } } //pr($files); $this->oView->DATA = $files; // Create XML export for site map index file if($file = fopen(__MDIR__ . "{$fileName}.xml","w+")){ fwrite($file, $this->oView->genTemplate('xml/sitemap_index.twig')); fclose($file); $sMsg = 'Successfully generated site map xml!'; } } return array('msg' => $sMsg); } /** * Function to gather all site map ids * * @author Aivars Žukovskis * @category system site map Controller * @return array of data * @version 1.1 */ public function gatherIds() { return array('data' => cJSON::encode(array_keys($this->module->gatherIds()))); } }