<?php /** * SeekQuarry/Yioop -- * Open Source Pure PHP Search Engine, Crawler, and Indexer * * Copyright (C) 2009 - 2012 Chris Pollett chris@pollett.org * * LICENSE: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * END LICENSE * * @author Chris Pollett chris@pollett.org * @package seek_quarry * @subpackage controller * @license http://www.gnu.org/licenses/ GPL3 * @link http://www.seekquarry.com/ * @copyright 2009 - 2012 * @filesource */ if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();} /** Load base controller class if needed */ require_once BASE_DIR."/controllers/controller.php"; /** Loads common constants for web crawling */ require_once BASE_DIR."/lib/crawl_constants.php"; /** Need get host for search filter admin */ require_once BASE_DIR."/lib/url_parser.php"; /** * Controller used to handle admin functionalities such as * modify login and password, CREATE, UPDATE,DELETE operations * for users, roles, locale, and crawls * * @author Chris Pollett * @package seek_quarry * @subpackage controller */ class AdminController extends Controller implements CrawlConstants { /** * Says which views to load for this controller * admin is the main one, signin has the login screen crawlstatus * is used to see how many pages crawled by the current crawl * @var array */ var $views = array("admin", "signin", "crawlstatus", "machinestatus"); /** * Says which models to load for this controller. * @var array */ var $models = array( "signin", "user", "activity", "crawl", "role", "locale", "profile", "searchfilters", "source", "machine"); /** * Says which activities (roughly methods invoke from the web) this * controller will respond to * @var array */ var $activities = array("signin", "manageAccount", "manageUsers", "manageRoles", "manageCrawls", "pageOptions", "resultsEditor", "manageMachines", "manageLocales", "crawlStatus", "mixCrawls", "machineStatus", "searchSources", "configure"); /** * An array of activities which are periodically updated within other * activities that they live. For example, within manage crawl, * the current crawl status is updated every 20 or so seconds. * @var array */ var $status_activities = array("crawlStatus", "machineStatus"); /** * This is the main entry point for handling requests to administer the * Yioop/SeekQuarry site * * ProcessRequest determines the type of request (signin , manageAccount, * etc) is being made. It then calls the appropriate method to handle the * given activity. Finally, it draws the relevant admin screen */ function processRequest() { $data = array(); if(!PROFILE) { return $this->configureRequest(); } $view = "signin"; if(isset($_SESSION['USER_ID'])) { $user = $_SESSION['USER_ID']; } else { $user = $_SERVER['REMOTE_ADDR']; } $data['YIOOP_TOKEN'] = $this->generateCSRFToken($user); $token_okay = $this->checkCSRFToken('YIOOP_TOKEN', $user); if($token_okay) { if(isset($_SESSION['USER_ID']) && !isset($_REQUEST['u'])) { $data = array_merge($data, $this->processSession()); if(!isset($data['REFRESH'])) { $view = "admin"; } else { $view = $data['REFRESH']; } } else if ($this->checkSignin()){ $user_id = $this->signinModel->getUserId( $this->clean($_REQUEST['u'], "string")); $session = $this->userModel->getUserSession($user_id); if(is_array($session)) { $_SESSION = $session; } $_SESSION['USER_ID'] = $user_id; $data['YIOOP_TOKEN'] = $this->generateCSRFToken( $_SESSION['USER_ID']); // now don't want to use remote address anymore $data['SCRIPT'] = "doMessage('<h1 class=\"red\" >". tl('admin_controller_login_successful')."</h1>')"; $data = array_merge($data, $this->processSession()); $view = "admin"; } else { $data['SCRIPT'] = "doMessage('<h1 class=\"red\" >". tl('admin_controller_login_failed')."</h1>')"; unset($_SESSION['USER_ID']); } } else if($this->checkCSRFToken('YIOOP_TOKEN', "config")) { $data['SCRIPT'] = "doMessage('<h1 class=\"red\" >". tl('admin_controller_login_to_config')."</h1>')"; } else if(isset($_REQUEST['a']) && in_array($_REQUEST['a'], $this->status_activities)) { e("<p class='red'>". tl('admin_controller_status_updates_stopped')."</p>"); exit(); } $this->displayView($view, $data); } /** * If there is no profile/work directory set up then this method * get called to by pass any login and go to the configure screen. * The configure screen is only displayed if the user is connected * from localhost in this case */ function configureRequest() { $data = $this->processSession(); $data['YIOOP_TOKEN'] = $this->generateCSRFToken("config"); $this->displayView("admin", $data); } /** * Checks whether the user name and password sent presumably by the signin * form match a user in the database * * @return bool whether they do or not */ function checkSignin() { $result = $this->signinModel->checkValidSignin( $this->clean($_REQUEST['u'], "string"), $this->clean($_REQUEST['p'], "string") ); return $result; } /** * Determines the user's current allowed activities and current activity, * then calls the method for the latter. * * This is called from {@link processRequest()} once a user is logged in. * * @return array $data the results of doing the activity for display in the * view */ function processSession() { if(!PROFILE) { $activity = "configure"; } else if(isset($_REQUEST['a']) && in_array($_REQUEST['a'], $this->activities)) { $activity = $_REQUEST['a']; } else { $activity = "manageAccount"; } $allowed = false; if(!PROFILE) { $allowed_activities = array( array( "ACTIVITY_NAME" => $this->activityModel->getActivityNameFromMethodName($activity), 'METHOD_NAME' => $activity)); $allowed = true; } else { $allowed_activities = $this->userModel->getUserActivities($_SESSION['USER_ID']); } foreach($allowed_activities as $allowed_activity) { if($activity == $allowed_activity['METHOD_NAME']) { $allowed = true; } if($allowed_activity['METHOD_NAME'] == "manageCrawls" && $activity == "crawlStatus") { $allowed = true; } if($allowed_activity['METHOD_NAME'] == "manageMachines" && $activity == "machineStatus") { $allowed = true; } } //for now we allow anyone to get crawlStatus if($allowed) { $data = $this->$activity(); $data['ACTIVITIES'] = $allowed_activities; } if(!in_array($activity, $this->status_activities)) { $data['CURRENT_ACTIVITY'] = $this->activityModel->getActivityNameFromMethodName($activity); } return $data; } /** * This method is data to signin a user and initialize the data to be * display in a view * * @return array empty array of data to show so far in view */ function signin() { $data = array(); $_SESSION['USER_ID'] = $this->signinModel->getUserId($_REQUEST['username']); return $data; } /** * Used to handle crawlStatus REST activities requesting the status of the * current web crawl * * @return array $data contains crawl status of current crawl as well as * info about prior crawls and which crawl is being used for default * search results */ function crawlStatus() { $data = array(); $data['REFRESH'] = "crawlstatus"; $crawl_time = $this->crawlModel->getCurrentIndexDatabaseName(); if(isset($crawl_time) ) { $data['CURRENT_INDEX'] = (int)$crawl_time; } else { $data['CURRENT_INDEX'] = -1; } $machine_urls = $this->machineModel->getQueueServerUrls(); list($stalled, $status, $data['RECENT_CRAWLS']) = $this->crawlModel->combinedCrawlInfo($machine_urls); if($stalled) { $this->crawlModel->sendStopCrawlMessage($machine_urls); } $data = array_merge($data, $status); $data["CRAWL_RUNNING"] = false; if(isset($data['CRAWL_TIME']) && $data["CRAWL_TIME"] != 0) { //erase from previous crawl list any active crawl $num_crawls = count($data['RECENT_CRAWLS']); for($i = 0; $i < $num_crawls; $i++) { if($data['RECENT_CRAWLS'][$i]['CRAWL_TIME'] == $data['CRAWL_TIME']) { $data['RECENT_CRAWLS'][$i] = false; } } $data["CRAWL_RUNNING"] = true; $data['RECENT_CRAWLS']= array_filter($data['RECENT_CRAWLS']); } if(isset($data['RECENT_CRAWLS'][0])) { rorderCallback($data['RECENT_CRAWLS'][0], $data['RECENT_CRAWLS'][0], 'CRAWL_TIME'); usort($data['RECENT_CRAWLS'], "rorderCallback"); } return $data; } /** * Gets data from the machineModel concerning the on/off states * of the machines managed by this Yioop instance and then passes * this data the the machinestatus view. * @return array $data MACHINES field has information about each * machine managed by this Yioop instance as well the on off * status of its queue_servers and fetchers. * The REFRESH field is used to tell the controller that the * view shouldn't have its own sidemenu. */ function machineStatus() { $data = array(); $data['REFRESH'] = "machinestatus"; $data['MACHINES'] = $this->machineModel->getMachineStatuses(); return $data; } /** * Used to handle the change current user password admin activity * * @return array $data SCRIPT field contains success or failure message */ function manageAccount() { $possible_arguments = array("changepassword"); $data["ELEMENT"] = "manageaccountElement"; $data['SCRIPT'] = ""; if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "changepassword": if($_REQUEST['retypepassword'] != $_REQUEST['newpassword']){ $data["MESSAGE"] = tl('admin_controller_passwords_dont_match'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>')"; return $data; } $username = $this->signinModel->getUserName($_SESSION['USER_ID']); $result = $this->signinModel->checkValidSignin($username, $this->clean($_REQUEST['oldpassword'], "string") ); if(!$result) { $data["MESSAGE"] = tl('admin_controller_invalid_old_password'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]."</h1>')"; return $data; } $this->signinModel->changePassword($username, $this->clean($_REQUEST['newpassword'], "string")); $data["MESSAGE"] = tl('admin_controller_change_password'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]."</h1>')"; break; } } return $data; } /** * Used to handle the manage user activity. * * This activity allows new users to be added, old users to be * deleted and allows roles to be added to/deleted from a user * * @return array $data infomation about users of the system, roles, etc. * as well as status messages on performing a given sub activity */ function manageUsers() { $possible_arguments = array("adduser", "deleteuser", "adduserrole", "deleteuserrole"); $data["ELEMENT"] = "manageusersElement"; $data['SCRIPT'] = "selectUser = elt('select-user'); ". "selectUser.onchange = submitViewUserRole;"; $usernames = $this->userModel->getUserList(); if(isset($_REQUEST['username'])) { $username = $this->clean($_REQUEST['username'], "string" ); } $base_option = tl('admin_controller_select_username'); $data['USER_NAMES'] = array(); $data['USER_NAMES'][""] = $base_option; foreach($usernames as $name) { $data['USER_NAMES'][$name]= $name; } if(isset($_REQUEST['selectuser'])) { $select_user = $this->clean($_REQUEST['selectuser'], "string" ); } else { $select_user = ""; } if($select_user != "" ) { $userid = $this->signinModel->getUserId($select_user); $data['SELECT_USER'] = $select_user; $data['SELECT_ROLES'] = $this->userModel->getUserRoles($userid); $all_roles = $this->roleModel->getRoleList(); $role_ids = array(); if(isset($_REQUEST['selectrole'])) { $select_role = $this->clean($_REQUEST['selectrole'], "string" ); } else { $select_role = ""; } foreach($all_roles as $role) { $role_ids[] = $role['ROLE_ID']; if($select_role == $role['ROLE_ID']) { $select_rolename = $role['ROLE_NAME']; } } $available_roles = array_diff_assoc( $all_roles, $data['SELECT_ROLES']); $data['AVAILABLE_ROLES'][-1] = tl('admin_controller_select_rolename'); foreach($available_roles as $role) { $data['AVAILABLE_ROLES'][$role['ROLE_ID']]= $role['ROLE_NAME']; } if($select_role != "") { $data['SELECT_ROLE'] = $select_role; } else { $data['SELECT_ROLE'] = -1; } } else { $data['SELECT_USER'] = -1; } if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "adduser": $data['SELECT_ROLE'] = -1; unset($data['AVAILABLE_ROLES']); unset($data['SELECT_ROLES']); if($_REQUEST['retypepassword'] != $_REQUEST['password']) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_passwords_dont_match'). "</h1>')"; return $data; } if($this->signinModel->getUserId($username) > 0) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_exists')."</h1>')"; return $data; } $this->userModel->addUser($username, $this->clean($_REQUEST['password'], "string")); $data['USER_NAMES'][$username] = $username; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_added')."</h1>')"; break; case "deleteuser": $data['SELECT_ROLE'] = -1; unset($data['AVAILABLE_ROLES']); unset($data['SELECT_ROLES']); if(!($this->signinModel->getUserId($username) > 0)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_doesnt_exists'). "</h1>')"; return $data; } $this->userModel->deleteUser($username); unset($data['USER_NAMES'][$username]); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_deleted')."</h1>')"; break; case "adduserrole": if( $userid <= 0 ) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_doesnt_exists'). "</h1>')"; return $data; } if(!in_array($select_role, $role_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_doesnt_exists'). "</h1>')"; return $data; } $this->userModel->addUserRole($userid, $select_role); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_added'). "</h1>')"; unset($data['AVAILABLE_ROLES'][$select_role]); $data['SELECT_ROLE'] = -1; $data['SELECT_ROLES'] = $this->userModel->getUserRoles($userid); break; case "deleteuserrole": if($userid <= 0) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_username_doesnt_exists'). "</h1>')"; return $data; } if(!in_array($select_role, $role_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_doesnt_exists'). "</h1>')"; return $data; } $this->userModel->deleteUserRole($userid, $select_role); $data['SELECT_ROLES'] = $this->userModel->getUserRoles($userid); $data['AVAILABLE_ROLES'][$select_role] = $select_rolename; $data['SELECT_ROLE'] = -1; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_deleted')."</h1>')"; break; } } return $data; } /** * Used to handle the manage role activity. * * This activity allows new roles to be added, old roles to be * deleted and allows activities to be added to/deleted from a role * * @return array $data infomation about roles in the system, activities,etc. * as well as status messages on performing a given sub activity * */ function manageRoles() { $possible_arguments = array("addrole", "deleterole", "addactivity", "deleteactivity"); $data["ELEMENT"] = "managerolesElement"; $data['SCRIPT'] = "selectRole = elt('select-role'); selectRole.onchange =". " submitViewRoleActivities;"; $roles = $this->roleModel->getRoleList(); $role_ids = array(); $base_option = tl('admin_controller_select_rolename'); $data['ROLE_NAMES'] = array(); $data['ROLE_NAMES'][-1] = $base_option; if(isset($_REQUEST['rolename'])) { $rolename = $this->clean($_REQUEST['rolename'], "string" ); } foreach($roles as $role) { $data['ROLE_NAMES'][$role['ROLE_ID']]= $role['ROLE_NAME']; $role_ids[] = $role['ROLE_ID']; } $data['SELECT_ROLE'] = -1; if(isset($_REQUEST['selectrole'])) { $select_role = $this->clean($_REQUEST['selectrole'], "string" ); } else { $select_role = ""; } if($select_role != "" ) { $data['SELECT_ROLE'] = $select_role; $data['ROLE_ACTIVITIES'] = $this->roleModel->getRoleActivities($select_role); $all_activities = $this->activityModel->getActivityList(); $activity_ids = array(); $activity_names = array(); foreach($all_activities as $activity) { $activity_ids[] = $activity['ACTIVITY_ID']; $activity_names[$activity['ACTIVITY_ID']] = $activity['ACTIVITY_NAME']; } $available_activities = array_diff_assoc($all_activities, $data['ROLE_ACTIVITIES']); $data['AVAILABLE_ACTIVITIES'][-1] = tl('admin_controller_select_activityname'); foreach($available_activities as $activity) { $data['AVAILABLE_ACTIVITIES'][$activity['ACTIVITY_ID']] = $activity['ACTIVITY_NAME']; } if(isset($_REQUEST['selectactivity'])) { $select_activity = $this->clean($_REQUEST['selectactivity'], "int" ); } else { $select_activity = ""; } if($select_activity != "") { $data['SELECT_ACTIVITY'] = $select_activity; } else { $data['SELECT_ACTIVITY'] = -1; } } if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "addrole": unset($data['ROLE_ACTIVITIES']); unset($data['AVAILABLE_ACTIVITIES']); $data['SELECT_ROLE'] = -1; if($this->roleModel->getRoleId($rolename) > 0) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_exists'). "</h1>')"; return $data; } $this->roleModel->addRole($rolename); $roleid = $this->roleModel->getRoleId($rolename); $data['ROLE_NAMES'][$roleid] = $rolename; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_added'). "</h1>')"; break; case "deleterole": $data['SELECT_ROLE'] = -1; unset($data['ROLE_ACTIVITIES']); unset($data['AVAILABLE_ACTIVITIES']); if(!in_array($select_role, $role_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_doesnt_exists'). "</h1>')"; return $data; } $this->roleModel->deleteRole($select_role); unset($data['ROLE_NAMES'][$select_role]); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_deleted')."</h1>')"; break; case "addactivity": if(!in_array($select_role, $role_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_doesnt_exists'). "</h1>')"; return $data; } if(!in_array($select_activity, $activity_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_activityname_doesnt_exists'). "</h1>')"; return $data; } $this->roleModel->addActivityRole( $select_role, $select_activity); unset($data['AVAILABLE_ACTIVITIES'][$select_activity]); $data['ROLE_ACTIVITIES'] = $this->roleModel->getRoleActivities($select_role); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_activity_added')."</h1>')"; break; case "deleteactivity": if(!in_array($select_role, $role_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_rolename_doesnt_exists'). "</h1>')"; return $data; } if(!in_array($select_activity, $activity_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_activityname_doesnt_exists'). "</h1>')"; return $data; } $this->roleModel->deleteActivityRole( $select_role, $select_activity); $data['ROLE_ACTIVITIES'] = $this->roleModel->getRoleActivities($select_role); $data['AVAILABLE_ACTIVITIES'][$select_activity] = $activity_names[$select_activity]; $data['SELECT_ACTIVITY'] = -1; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_activity_deleted')."</h1>')"; break; } } return $data; } /** * Used to handle the manage crawl activity. * * This activity allows new crawls to be started, statistics about old * crawls to be seen. It allows a user to stop the current crawl or * restart an old crawl. It also allows a user to configure the options * by which a crawl is conducted * * @return array $data information and statistics about crawls in the system * as well as status messages on performing a given sub activity */ function manageCrawls() { $possible_arguments = array("start", "resume", "delete", "stop", "index", "options"); $data["ELEMENT"] = "managecrawlsElement"; $data['SCRIPT'] = "doUpdate();"; if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { $machine_urls = $this->machineModel->getQueueServerUrls(); $num_machines = count($machine_urls); if($num_machines < 1 || ($num_machines == 1 && UrlParser::isLocalhostUrl($machine_urls[0]))) { $machine_urls = NULL; } switch($_REQUEST['arg']) { case "start": $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_starting_new_crawl')."</h1>')"; $crawl_params = array(); $crawl_params[self::STATUS] = "NEW_CRAWL"; $crawl_params[self::CRAWL_TIME] = time(); $seed_info = $this->crawlModel->getSeedInfo(); $crawl_params[self::CRAWL_TYPE] = $seed_info['general']['crawl_type']; $crawl_params[self::CRAWL_INDEX] = (isset($seed_info['general']['crawl_index'])) ? $seed_info['general']['crawl_index'] : ''; $crawl_params[self::ARC_DIR] = (isset($seed_info['general']['arc_dir'])) ? $seed_info['general']['arc_dir'] : ''; $crawl_params[self::ARC_TYPE] = (isset($seed_info['general']['arc_type'])) ? $seed_info['general']['arc_type'] : ''; $crawl_params[self::PAGE_RANGE_REQUEST] = (isset($seed_info['general']['page_range_request'])) ? intval($seed_info['general']['page_range_request']) : PAGE_RANGE_REQUEST; $crawl_params[self::PAGE_RECRAWL_FREQUENCY] = (isset($seed_info['general']['page_recrawl_frequency'])) ? intval($seed_info['general']['page_recrawl_frequency']): PAGE_RECRAWL_FREQUENCY; $crawl_params[self::TO_CRAWL] = $seed_info['seed_sites']['url']; $crawl_params[self::CRAWL_ORDER] = $seed_info['general']['crawl_order']; $crawl_params[self::RESTRICT_SITES_BY_URL] = $seed_info['general']['restrict_sites_by_url']; $crawl_params[self::ALLOWED_SITES] = isset($seed_info['allowed_sites']['url']) ? $seed_info['allowed_sites']['url'] : array(); $crawl_params[self::DISALLOWED_SITES] = isset($seed_info['disallowed_sites']['url']) ? $seed_info['disallowed_sites']['url'] : array(); $crawl_params[self::META_WORDS] = isset($seed_info['meta_words']) ? $seed_info['meta_words'] : array(); if(isset($seed_info['indexing_plugins']['plugins'])) { $crawl_params[self::INDEXING_PLUGINS] = $seed_info['indexing_plugins']['plugins']; } if(isset($seed_info['indexed_file_types']['extensions'])) { $crawl_params[self::INDEXED_FILE_TYPES] = $seed_info['indexed_file_types']['extensions']; } if(isset($_REQUEST['description'])) { $description = $this->clean($_REQUEST['description'], "string"); } else { $description = tl('admin_controller_no_description'); } $crawl_params['DESCRIPTION'] = $description; $crawl_params[self::VIDEO_SOURCES] = array(); $sources = $this->sourceModel->getMediaSources('video'); foreach($sources as $source) { $url = $source['SOURCE_URL']; $url_parts = explode("{}", $url); $crawl_params[self::VIDEO_SOURCES][] = $url_parts[0]; } // Write the new crawl parameters to the name server, so // that it can pass them along in the case of a new archive // crawl. $filename = CRAWL_DIR. "/schedules/name_server_messages.txt"; file_put_contents($filename, serialize($crawl_params)); chmod($filename, 0777); $this->crawlModel->sendStartCrawlMessage($crawl_params, $seed_info, $machine_urls); break; case "stop": $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_stop_crawl')."</h1>')"; @unlink(CRAWL_DIR."/schedules/crawl_params.txt"); $info = array(); $info[self::STATUS] = "STOP_CRAWL"; $filename = CRAWL_DIR. "/schedules/name_server_messages.txt"; file_put_contents($filename, serialize($info)); $this->crawlModel->sendStopCrawlMessage($machine_urls); break; case "resume": $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_resume_crawl')."</h1>')"; $crawl_params = array(); $crawl_params[self::STATUS] = "RESUME_CRAWL"; $crawl_params[self::CRAWL_TIME] = $this->clean($_REQUEST['timestamp'], "int"); /* we only set crawl time. Other data such as allowed sites should come from index. */ $this->crawlModel->sendStartCrawlMessage($crawl_params, NULL, $machine_urls); break; case "delete": if(isset($_REQUEST['timestamp'])) { $timestamp = $this->clean($_REQUEST['timestamp'], "int"); $this->crawlModel->deleteCrawl($timestamp, $machine_urls); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_delete_crawl_success'). "</h1>'); crawlStatusUpdate(); "; } else { $data['SCRIPT'] .= "crawlStatusUpdate(); ". "doMessage('<h1 class=\"red\" >". tl('admin_controller_delete_crawl_fail'). "</h1>')"; } break; case "index": $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_set_index')."</h1>')"; $timestamp = $this->clean($_REQUEST['timestamp'], "int"); $this->crawlModel->setCurrentIndexDatabaseName($timestamp); break; case "options": $data["leftorright"] = (getLocaleDirection() == 'ltr') ? "right": "left"; $data["ELEMENT"] = "crawloptionsElement"; $crawls = $this->crawlModel->getCrawlList(false, false, $machine_urls); $indexes = $this->crawlModel->getCrawlList(true, true, $machine_urls); $indexes_by_crawl_time = array(); $update_flag = false; $data['available_options'] = array( tl('admin_controller_use_below'), tl('admin_controller_use_defaults')); $data['available_crawl_indexes'] = array(); $data['options_default'] = tl('admin_controller_use_below'); foreach($crawls as $crawl) { $data['available_options'][$crawl['CRAWL_TIME']] = tl('admin_controller_previous_crawl')." ". $crawl['DESCRIPTION']; } foreach($indexes as $i => $crawl) { $data['available_crawl_indexes'][$crawl['CRAWL_TIME']] = $crawl['DESCRIPTION']; $indexes_by_crawl_time[$crawl['CRAWL_TIME']] =& $indexes[$i]; } $no_further_changes = false; if(isset($_REQUEST['load_option']) && $_REQUEST['load_option'] == 1) { $seed_current = $this->crawlModel->getSeedInfo(); $seed_info = $this->crawlModel->getSeedInfo(true); if(isset( $seed_current['general']['page_range_request'])) { $seed_info['general']['page_range_request'] = $seed_current['general']['page_range_request']; } if(isset( $seed_current['general']['page_recrawl_frequency']) ){ $seed_info['general']['page_recrawl_frequency'] = $seed_current['general']['page_recrawl_frequency']; } if(isset( $seed_current['indexed_file_types'])) { $seed_info['indexed_file_types'] = $seed_current['indexed_file_types']; } $update_flag = true; $no_further_changes = true; } else if (isset($_REQUEST['load_option']) && $_REQUEST['load_option'] > 1 ) { $timestamp = $this->clean($_REQUEST['load_option'], "int"); $seed_info = $this->crawlModel->getCrawlSeedInfo( $timestamp, $machine_urls); $update_flag = true; $no_further_changes = true; } else if(isset($_REQUEST['ts'])) { $timestamp = $this->clean($_REQUEST['ts'], "int"); $seed_info = $this->crawlModel->getCrawlSeedInfo( $timestamp, $machine_urls); $data['ts'] = $timestamp; } else { $seed_info = $this->crawlModel->getSeedInfo(); } if(!$no_further_changes && isset($_REQUEST['crawl_indexes']) && in_array($_REQUEST['crawl_indexes'], array_keys($data['available_crawl_indexes']))) { $seed_info['general']['crawl_index'] = $_REQUEST['crawl_indexes']; $index_data = $indexes_by_crawl_time[ $_REQUEST['crawl_indexes']]; if(isset($index_data['ARC_DIR'])) { $seed_info['general']['arc_dir'] = $index_data['ARC_DIR']; $seed_info['general']['arc_type'] = $index_data['ARC_TYPE']; } else { $seed_info['general']['arc_dir'] = ''; $seed_info['general']['arc_type'] = ''; } $update_flag = true; } $data['crawl_index'] = (isset($seed_info['general']['crawl_index'])) ? $seed_info['general']['crawl_index'] : ''; $data['available_crawl_types'] = array(self::WEB_CRAWL, self::ARCHIVE_CRAWL); if(!$no_further_changes && isset($_REQUEST['crawl_type']) && in_array($_REQUEST['crawl_type'], $data['available_crawl_types'])) { $seed_info['general']['crawl_type'] = $_REQUEST['crawl_type']; $update_flag = true; } $data['crawl_type'] = $seed_info['general']['crawl_type']; if($data['crawl_type'] == self::WEB_CRAWL) { $data['web_crawl_active'] = "active"; $data['archive_crawl_active'] = ""; } else { $data['archive_crawl_active'] = "active"; $data['web_crawl_active'] = ""; } $data['available_crawl_orders'] = array( self::BREADTH_FIRST => tl('admin_controller_breadth_first'), self::PAGE_IMPORTANCE => tl('admin_controller_page_importance')); if(!$no_further_changes && isset($_REQUEST['crawl_order']) && in_array($_REQUEST['crawl_order'], array_keys($data['available_crawl_orders']))) { $seed_info['general']['crawl_order'] = $_REQUEST['crawl_order']; $update_flag = true; } $data['crawl_order'] = $seed_info['general']['crawl_order']; if(!$no_further_changes && isset($_REQUEST['posted'])) { $seed_info['general']['restrict_sites_by_url'] = (isset($_REQUEST['restrict_sites_by_url'])) ? true : false; $update_flag = true; } $data['restrict_sites_by_url'] = $seed_info['general']['restrict_sites_by_url']; $site_types = array('allowed_sites','disallowed_sites', 'seed_sites'); foreach($site_types as $type) { if(!$no_further_changes && isset($_REQUEST[$type])) { $seed_info[$type]['url'] = $this->convertStringCleanUrlsArray( $_REQUEST[$type]); } if(isset($seed_info[$type]['url'])) { $data[$type] = $this->convertArrayCleanLines( $seed_info[$type]['url']); } else { $data[$type] = ""; } } $data['TOGGLE_STATE'] = ($data['restrict_sites_by_url']) ? "checked='checked'" : ""; $data['META_WORDS'] = array(); if(!$no_further_changes) { if(isset($_REQUEST["META_WORDS"])){ foreach($_REQUEST["META_WORDS"] as $pair) { list($word, $url_pattern)=array_values($pair); $word = $this->clean($word, "string"); $url_pattern = $this->clean($url_pattern, "string"); if(trim($word) != "" &&trim($url_pattern) !=""){ $data['META_WORDS'][$word] = $url_pattern; } } $seed_info['meta_words'] = $data['META_WORDS']; $update_flag = true; } else if(isset($seed_info['meta_words'])){ $data['META_WORDS'] = $seed_info['meta_words']; } } else if(isset($seed_info['meta_words'])){ $data['META_WORDS'] = $seed_info['meta_words']; } $data['INDEXING_PLUGINS'] = array(); $included_plugins = array(); if(!$no_further_changes && isset($_REQUEST["posted"])) { $seed_info['indexing_plugins']['plugins'] = (isset($_REQUEST["INDEXING_PLUGINS"])) ? $_REQUEST["INDEXING_PLUGINS"] : array(); $update_flag = true; } $included_plugins = (isset($seed_info['indexing_plugins']['plugins'])) ? $seed_info['indexing_plugins']['plugins'] : array(); foreach($this->indexing_plugins as $plugin) { $plugin_name = ucfirst($plugin); $data['INDEXING_PLUGINS'][$plugin_name] = (in_array($plugin_name, $included_plugins)) ? "checked='checked'" : ""; } $data['SCRIPT'] = "setDisplay('toggle', ". "'{$data['restrict_sites_by_url']}');"; if(!isset($_REQUEST['ts'])) { $data['SCRIPT'] .= " elt('load-options').onchange = ". "function() { if(elt('load-options').selectedIndex !=". " 0) { elt('crawloptionsForm').submit(); }};"; } if($data['crawl_type'] == CrawlConstants::WEB_CRAWL) { $data['SCRIPT'] .= "switchTab('webcrawltab', 'archivetab');"; } else { $data['SCRIPT'] .= "switchTab('archivetab', 'webcrawltab');"; } $add_message = ""; if(isset($_REQUEST['ts']) && isset($_REQUEST['inject_sites'])) { $timestamp = $this->clean($_REQUEST['ts'], "string"); $inject_urls = $this->convertStringCleanUrlsArray( $_REQUEST['inject_sites']); if($this->crawlModel->injectUrlsCurrentCrawl( $timestamp, $inject_urls, $machine_urls)) { $add_message = "<br />". tl('admin_controller_urls_injected'); } } if($update_flag) { if(isset($_REQUEST['ts'])) { $this->crawlModel->setCrawlSeedInfo($timestamp, $seed_info, $machine_urls); } else { $this->crawlModel->setSeedInfo($seed_info); } $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_update_seed_info'). "$add_message</h1>');"; } break; default: } } return $data; } /** * Cleans a potentially tainted set of user input which are presented as * an array of lines. This is used to handle data from the crawl options * textareas. It is also used * * @param array $arr the array of lines to be cleaned * @param string $endline_string what string should be used to indicate * the end of a line * @return string a concatenated string of cleaned lines */ function convertArrayCleanLines($arr, $endline_string="\n") { $output = ""; $eol = ""; foreach($arr as $line) { $output .= $eol; $output .= trim($this->clean($line, 'string')); $eol = $endline_string; } return $output; } /** * Cleans a string consisting of lines of urls into an array of urls. This * is used in handling data from the crawl options text areas. * * @param string $str contains the url data * @return $url an array of urls */ function convertStringCleanUrlsArray($str) { $pre_urls = preg_split("/(\s)+/", $str); $urls = array(); foreach($pre_urls as $url) { $pre_url = $this->clean($url, "string"); if(strlen($pre_url) > 0) { $start_url = substr($pre_url,0, 6); if(!in_array($start_url, array("file:/", "http:/", "domain", "https:"))) { $pre_url = "http://". $pre_url; } $urls[] =$pre_url; } } return $urls; } /** * Handles admin request related to the crawl mix activity * * The crawl mix activity allows a user to create/edit crawl mixes: * weighted combinations of search indexes * * @return array $data info about available crawl mixes and changes to them * as well as any messages about the success or failure of a * sub activity. */ function mixCrawls() { $possible_arguments = array( "createmix", "deletemix", "editmix", "index"); $data["ELEMENT"] = "mixcrawlsElement"; $data['mix_default'] = 0; $crawls = $this->crawlModel->getCrawlList(false, true); $data['available_crawls'][0] = tl('admin_controller_select_crawl'); $data['available_crawls'][1] = tl('admin_controller_default_crawl'); $data['SCRIPT'] = "c = [];c[0]='". tl('admin_controller_select_crawl')."';"; $data['SCRIPT'] .= "c[1]='". tl('admin_controller_default_crawl')."';"; foreach($crawls as $crawl) { $data['available_crawls'][$crawl['CRAWL_TIME']] = $crawl['DESCRIPTION']; $data['SCRIPT'] .= 'c['.$crawl['CRAWL_TIME'].']="'. $crawl['DESCRIPTION'].'";'; } $mixes = $this->crawlModel->getMixList(true); if(count($mixes) > 0 ) { $data['available_mixes']= $mixes; $mix_ids = array(); foreach($mixes as $mix) { $mix_ids[] = $mix['MIX_TIMESTAMP']; } } $mix = array(); if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "createmix": $mix['MIX_TIMESTAMP'] = time(); if(isset($_REQUEST['MIX_NAME'])) { $mix['MIX_NAME'] = $this->clean($_REQUEST['MIX_NAME'], 'string'); } else { $mix['MIX_NAME'] = tl('admin_controller_unnamed'); } $mix['GROUPS'] = array(); $this->crawlModel->setCrawlMix($mix); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_mix_created')."</h1>');"; case "editmix": //$data passed by reference $this->editMix($data, $mix_ids, $mix); break; case "index": $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_set_index')."</h1>')"; $timestamp = $this->clean($_REQUEST['timestamp'], "int"); $this->crawlModel->setCurrentIndexDatabaseName($timestamp); break; case "deletemix": if(!isset($_REQUEST['timestamp'])|| !isset($mix_ids) || !in_array($_REQUEST['timestamp'], $mix_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_mix_doesnt_exists'). "</h1>')"; return $data; } $this->crawlModel->deleteCrawlMix($_REQUEST['timestamp']); $data['available_mixes'] = $this->crawlModel->getMixList(true); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_mix_deleted')."</h1>')"; break; } } $crawl_time = $this->crawlModel->getCurrentIndexDatabaseName(); if(isset($crawl_time) ) { $data['CURRENT_INDEX'] = (int)$crawl_time; } else { $data['CURRENT_INDEX'] = -1; } return $data; } /** * Handles admin request related to the editing a crawl mix activity * * @return array $data info about the groups and their contents for a * particular crawl mix */ function editMix(&$data, &$mix_ids, $mix) { $data["leftorright"] = (getLocaleDirection() == 'ltr') ? "right": "left"; $data["ELEMENT"] = "editmixElement"; if(isset($_REQUEST['timestamp'])) { $mix = $this->crawlModel->getCrawlMix( $_REQUEST['timestamp']); } $data['MIX'] = $mix; $data['INCLUDE_SCRIPTS'] = array("mix"); //set up an array of translation for javascript-land $data['SCRIPT'] .= "tl = {". 'editmix_element_add_crawls:"'.tl('editmix_element_add_crawls').'",'. 'editmix_element_num_results:"'. tl('editmix_element_num_results').'",'. 'editmix_element_del_grp:"'.tl('editmix_element_del_grp').'",'. 'editmix_element_weight:"'.tl('editmix_element_weight').'",'. 'editmix_element_name:"'.tl('editmix_element_name').'",'. 'editmix_add_keywords:"'.tl('editmix_add_keywords').'",'. 'editmix_element_actions:"'.tl('editmix_element_actions').'",'. 'editmix_add_query:"'.tl('editmix_add_query').'",'. 'editmix_element_delete:"'.tl('editmix_element_delete').'"'. '};'; //clean and save the crawl mix sent from the browser if(isset($_REQUEST['update']) && $_REQUEST['update'] == "update") { $mix = $_REQUEST['mix']; $mix['MIX_TIMESTAMP'] = $this->clean($mix['MIX_TIMESTAMP'], "int"); $mix['MIX_NAME'] =$this->clean($mix['MIX_NAME'], "string"); $comp = array(); if(isset($mix['GROUPS'])) { if($mix['GROUPS'] != NULL) { foreach($mix['GROUPS'] as $group_id => $group_data) { if(isset($group_data['RESULT_BOUND'])) { $mix['GROUPS'][$group_id]['RESULT_BOUND'] = $this->clean($group_data['RESULT_BOUND'], "int"); } else { $mix['GROUPS']['RESULT_BOUND'] = 0; } if(isset($group_data['COMPONENTS'])) { $comp = array(); foreach($group_data['COMPONENTS'] as $component) { $row = array(); $row['CRAWL_TIMESTAMP'] = $this->clean($component['CRAWL_TIMESTAMP'], "int"); $row['WEIGHT'] = $this->clean( $component['WEIGHT'], "float"); $row['KEYWORDS'] = $this->clean( $component['KEYWORDS'], "string"); $comp[] =$row; } $mix['GROUPS'][$group_id]['COMPONENTS'] = $comp; } else { $mix['GROUPS'][$group_id]['COMPONENTS'] = array(); } } } else { $mix['COMPONENTS'] = array(); } } else { $mix['GROUPS'] = $data['MIX']['GROUPS']; } $data['MIX'] = $mix; $this->crawlModel->setCrawlMix($mix); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_mix_saved')."</h1>');"; } $data['SCRIPT'] .= 'groups = ['; $not_first = ""; foreach($mix['GROUPS'] as $group_id => $group_data) { $data['SCRIPT'] .= $not_first.'{'; $not_first= ","; if(isset($group_data['RESULT_BOUND'])) { $data['SCRIPT'] .= "num_results:".$group_data['RESULT_BOUND']; } else { $data['SCRIPT'] .= "num_results:1 "; } $data['SCRIPT'] .= ", components:["; if(isset($group_data['COMPONENTS'])) { $comma = ""; foreach($group_data['COMPONENTS'] as $component) { $crawl_ts = $component['CRAWL_TIMESTAMP']; $crawl_name = $data['available_crawls'][$crawl_ts]; $data['SCRIPT'] .= $comma." [$crawl_ts, '$crawl_name', ". $component['WEIGHT'].", "; $comma = ","; $keywords = (isset($component['KEYWORDS'])) ? $component['KEYWORDS'] : ""; $data['SCRIPT'] .= "'$keywords'] "; } } $data['SCRIPT'] .= "] }"; } $data['SCRIPT'] .= ']; drawGroups();'; } /** * Handles admin request related to controlling file options to be used * in a crawl * * This activity allows a user to specify the page range size to be * be used during a crawl as well as which file types can be downloaded * * @return array $data info about the groups and their contents for a * particular crawl mix */ function pageOptions() { global $INDEXED_FILE_TYPES; $seed_info = $this->crawlModel->getSeedInfo(); if(!isset($seed_info["indexed_file_types"]["extensions"])) { $seed_info["indexed_file_types"]["extensions"] = $INDEXED_FILE_TYPES; } $data["ELEMENT"] = "pageoptionsElement"; $data['SCRIPT'] = ""; $profile = $this->profileModel->getProfile(WORK_DIRECTORY); $weights = array('TITLE_WEIGHT' => 4, 'DESCRIPTION_WEIGHT' => 1, 'LINK_WEIGHT' => 2, 'MIN_RESULTS_TO_GROUP' => 200, 'SERVER_ALPHA' => 1.6); $change = false; foreach($weights as $weight => $value) { if(isset($_REQUEST[$weight])) { $data[$weight] = $this->clean($_REQUEST[$weight], 'float', 1 ); $profile[$weight] = $data[$weight]; $change = true; } else if(isset($profile[$weight]) && $profile[$weight] != ""){ $data[$weight] = $profile[$weight]; } else { $data[$weight] = $value; $profile[$weight] = $data[$weight]; $change = true; } } $data['RECRAWL_FREQS'] = array(-1=>tl('admin_controller_recrawl_never'), 1=>tl('admin_controller_recrawl_1day'), 2=>tl('admin_controller_recrawl_2day'), 3=>tl('admin_controller_recrawl_3day'), 7=>tl('admin_controller_recrawl_7day'), 14=>tl('admin_controller_recrawl_14day')); if(isset($_REQUEST["page_recrawl_frequency"]) && in_array($_REQUEST["page_recrawl_frequency"], array_keys($data['RECRAWL_FREQS']))) { $seed_info["general"]["page_recrawl_frequency"] = $_REQUEST["page_recrawl_frequency"]; } if(!isset($seed_info["general"]["page_recrawl_frequency"])) { $seed_info["general"]["page_recrawl_frequency"] = PAGE_RECRAWL_FREQUENCY; } $data['PAGE_RECRAWL_FREQUENCY'] = $seed_info["general"]["page_recrawl_frequency"]; if($change == true) { $this->profileModel->updateProfile(WORK_DIRECTORY, array(), $profile); } $data['SIZE_VALUES'] = array(10000=>10000, 50000=>50000, 100000=>100000, 500000=>500000, 1000000=>1000000, 5000000=>5000000, 10000000=>10000000); $data['INDEXED_FILE_TYPES'] = array(); if(isset($_REQUEST["page_range_request"]) && in_array($_REQUEST["page_range_request"], $data['SIZE_VALUES'])) { $seed_info["general"]["page_range_request"] = $_REQUEST["page_range_request"]; } if(!isset($seed_info["general"]["page_range_request"])) { $seed_info["general"]["page_range_request"] = PAGE_RANGE_REQUEST; } $data['PAGE_SIZE'] = $seed_info["general"]["page_range_request"]; $filetypes = array(); foreach($INDEXED_FILE_TYPES as $filetype) { $ison =false; if(isset($_REQUEST["filetype"])) { if(isset($_REQUEST["filetype"][$filetype])) { $filetypes[] = $filetype; $ison = true; $change = true; } } else { if(in_array($filetype, $seed_info["indexed_file_types"]["extensions"])) { $filetypes[] = $filetype; $ison = true; } } $data['INDEXED_FILE_TYPES'][$filetype] = ($ison) ? "checked='checked'" :''; } $seed_info["indexed_file_types"]["extensions"] = $filetypes; $this->crawlModel->setSeedInfo($seed_info); if($change == true) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_page_options_updated')."</h1>')"; } return $data; } /** * Handles admin request related to the search filter activity * * This activity allows a user to specify hosts whose web pages are to be * filtered out the search results * * @return array $data info about the groups and their contents for a * particular crawl mix */ function resultsEditor() { $data["ELEMENT"] = "resultseditorElement"; $data['SCRIPT'] = ""; if(isset($_REQUEST['disallowed_sites'])) { $sites = $this->convertStringCleanUrlsArray( $_REQUEST['disallowed_sites']); $disallowed_sites = array(); foreach($sites as $site) { $site = UrlParser::getHost($site); if(strlen($site) > 0) { $disallowed_sites[] = $site."/"; } } $data['disallowed_sites'] = implode("\n", $disallowed_sites); $this->searchfiltersModel->set($disallowed_sites); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_results_editor_update')."</h1>')"; } if(!isset($data['disallowed_sites'])) { $data['disallowed_sites'] = implode("\n", $this->searchfiltersModel->getUrls()); } foreach (array("URL", "TITLE", "DESCRIPTION") as $field) { $data[$field] = (isset($_REQUEST[$field])) ? $this->clean($_REQUEST[$field], "string") : ((isset($data[$field]) ) ? $data[$field] : ""); } if($data["URL"] != "") { $data["URL"] = UrlParser::canonicalLink($data["URL"],""); } $tmp = tl('admin_controller_edited_pages'); $data["URL_LIST"] = array ($tmp => $tmp); $summaries = $this->searchfiltersModel->getEditedPageSummaries(); foreach($summaries as $hash => $summary) { $data["URL_LIST"][$summary[self::URL]] = $summary[self::URL]; } if(isset($_REQUEST['arg']) ) { switch($_REQUEST['arg']) { case "save_page": $missing_page_field = ($data["URL"] == "") ? true: false; if($missing_page_field) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_results_editor_need_url'). "</h1>')"; } else { $this->searchfiltersModel->updateResultPage( $data["URL"], $data["TITLE"], $data["DESCRIPTION"]); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_results_editor_page_updated'). "</h1>')"; } break; case "load_url": $hash_url = crawlHash($_REQUEST['LOAD_URL'], true); if(isset($summaries[$hash_url])) { $data["URL"] = $this->clean($_REQUEST['LOAD_URL'], "string"); $data["TITLE"] = $summaries[$hash_url][self::TITLE]; $data["DESCRIPTION"] = $summaries[$hash_url][ self::DESCRIPTION]; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_results_editor_page_loaded'). "</h1>')"; } break; } } return $data; } /** * Handles admin request related to the managing the machines which perform * crawls * * With this activity an admin can add/delete machines to manage. For each * managed machine, the admin can stop and start fetchers/queue_servers * as well as look at their log files * * @return array $data MACHINES, their MACHINE_NAMES, data for * FETCHER_NUMBERS drop-down */ function manageMachines() { $data["ELEMENT"] = "managemachinesElement"; $possible_arguments = array("addmachine", "deletemachine", "log", "update"); $data['SCRIPT'] = "doUpdate();"; $data["leftorright"]=(getLocaleDirection() == 'ltr') ? "right": "left"; $data['MACHINES'] = array(); $data['MACHINE_NAMES'] = array(); $urls = array(); $data['FETCHER_NUMBERS'] = array( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 16 => 16 ); $machines = $this->machineModel->getMachineList(); $tmp = tl('admin_controller_select_machine'); $data['DELETABLE_MACHINES'] = array( $tmp => $tmp ); $data['REPLICATABLE_MACHINES'] = array( $tmp => $tmp ); foreach($machines as $machine) { $data['MACHINE_NAMES'][] = $machine["NAME"]; $urls[] = $machine["URL"]; $data['DELETABLE_MACHINES'][$machine["NAME"]] = $machine["NAME"]; if(!isset($machine["PARENT"]) || $machine["PARENT"] == "") { $data['REPLICATABLE_MACHINES'][$machine["NAME"]] = $machine["NAME"]; } } if(!isset($_REQUEST["has_queue_server"]) || isset($_REQUEST['is_replica'])) { $_REQUEST["has_queue_server"] = false; } if(isset($_REQUEST['is_replica'])) { $_REQUEST['num_fetchers'] = 0; } else { $_REQUEST['parent'] = ""; } $request_fields = array( "name" => "string", "url" => "string", "has_queue_server" => "bool", "num_fetchers" => "int", "parent" => "string" ); $r = array(); $allset = true; foreach($request_fields as $field => $type) { if(isset($_REQUEST[$field])) { $r[$field] = $this->clean($_REQUEST[$field], $type); if($field == "url" && $r[$field][strlen($r[$field])-1] != "/") { $r[$field] .= "/"; } } else { $allset = false; } } if(isset($r["num_fetchers"]) && in_array($r["num_fetchers"], $data['FETCHER_NUMBERS'])) { $data['FETCHER_NUMBER'] = $r["num_fetchers"]; } else { $data['FETCHER_NUMBER'] = 0; if(isset($r["num_fetchers"])) { $r["num_fetchers"] = 0; } } $machine_exists = (isset($r["name"]) && in_array($r["name"], $data['MACHINE_NAMES']) ) || (isset($r["url"]) && in_array($r["url"], $urls)); if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "addmachine": if($allset == true && !$machine_exists) { $this->machineModel->addMachine( $r["name"], $r["url"], $r["has_queue_server"], $r["num_fetchers"], $r["parent"]); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_added'). "</h1>');"; $data['MACHINE_NAMES'][] = $r["name"]; $data['DELETABLE_MACHINES'][$r["name"]] = $r["name"]; sort($data['MACHINE_NAMES']); } else if ($allset && $machine_exists ) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_exists'). "</h1>');"; } else { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_incomplete'). "</h1>');"; } break; case "deletemachine": if(!isset($r["name"]) || !in_array($r["name"], $data['MACHINE_NAMES'])) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_doesnt_exists'). "</h1>');"; } else { $machines = $this->machineModel->getMachineStatuses(); $service_in_use = false; foreach($machines as $machine) { if($machine['NAME'] == $r["name"]) { if($machine['STATUSES'] != array()) { $service_in_use = true; break; } else { break; } } } if($service_in_use) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_stop_service_first')."</h1>');"; break; } $this->machineModel->deleteMachine($r["name"]); $tmp_array = array($r["name"]); $diff = array_diff($data['MACHINE_NAMES'], $tmp_array); $data['MACHINE_NAMES'] = array_merge($diff); $tmp_array = array($r["name"] => $r["name"]); $diff = array_diff($data['DELETABLE_MACHINES'], $tmp_array); $data['DELETABLE_MACHINES'] = array_merge($diff); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_deleted')."</h1>');"; } break; case "log": if(isset($_REQUEST["fetcher_num"])) { $r["fetcher_num"] = $this->clean($_REQUEST["fetcher_num"], "int"); } if(isset($_REQUEST["mirror_name"])) { $r["mirror_name"] = $this->clean($_REQUEST["mirror_name"], "string"); } if(isset($_REQUEST["time"])) { $data["time"] = $this->clean($_REQUEST["time"], "int") + 30; } else { $data["time"] = 30; } $data["ELEMENT"] = "machinelogElement"; $data["REFRESH_LOG"] = "&time=".$data["time"]; $data["LOG_TYPE"] = ""; if(isset($r['fetcher_num']) && isset($r['name'])) { $data["LOG_FILE_DATA"] = $this->machineModel->getLog( $r["name"], $r["fetcher_num"]); $data["LOG_TYPE"] = $r['name']. " fetcher ".$r["fetcher_num"]; $data["REFRESH_LOG"] .= "&arg=log&name=".$r['name']. "&fetcher_num=". $r['fetcher_num']; } else if(isset($r["mirror_name"])) { $data["LOG_TYPE"] = $r['mirror_name']." mirror"; $data["LOG_FILE_DATA"] = $this->machineModel->getLog( $r["mirror_name"], NULL, true); } else if(isset($r['name'])) { $data["LOG_TYPE"] = $r['name']." queue_server"; $data["LOG_FILE_DATA"] = $this->machineModel->getLog( $r["name"]); $data["REFRESH_LOG"] .= "&arg=log&name=".$r['name']; } if($data["time"] >= 1200) { $data["REFRESH_LOG"] = ""; } if(!isset($data["LOG_FILE_DATA"]) || $data["LOG_FILE_DATA"] == ""){ $data["LOG_FILE_DATA"] = tl('admin_controller_no_machine_log'); } $lines =array_reverse(explode("\n",$data["LOG_FILE_DATA"])); $data["LOG_FILE_DATA"] = implode("\n", $lines); break; case "update": if(isset($_REQUEST["fetcher_num"])) { $r["fetcher_num"] = $this->clean($_REQUEST["fetcher_num"], "int"); } else { $r["fetcher_num"] = NULL; } $available_actions = array("start", "stop", "mirror_start", "mirror_stop"); if(isset($r["name"]) && isset($_REQUEST["action"]) && in_array($_REQUEST["action"], $available_actions)) { $action = $_REQUEST["action"]; $is_mirror = false; if($action == "mirror_start") { $action = "start"; $is_mirror = true; } else if ($action == "mirror_stop") { $action = "stop"; $is_mirror = true; } $this->machineModel->update($r["name"], $action, $r["fetcher_num"], $is_mirror); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_servers_updated'). "</h1>');"; } else { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_machine_no_action'). "</h1>');"; } break; } } $data['SCRIPT'] .= "toggleReplica(false);"; return $data; } /** * Handles admin request related to the manage locale activity * * The manage locale activity allows a user to add/delete locales, view * statistics about a locale as well as edit the string for that locale * * @return array $data info about current locales, statistics for each * locale as well as potentially the currently set string of a * locale and any messages about the success or failure of a * sub activity. */ function manageLocales() { $possible_arguments = array("addlocale", "deletelocale", "editlocale"); $data['SCRIPT'] = ""; $data["ELEMENT"] = "managelocalesElement"; $data["LOCALES"] = $this->localeModel->getLocaleList(); $data['LOCALE_NAMES'][-1] = tl('admin_controller_select_localename'); $locale_ids = array(); foreach ($data["LOCALES"] as $locale) { $data["LOCALE_NAMES"][$locale["LOCALE_TAG"]] = $locale["LOCALE_NAME"]; $locale_ids[] = $locale["LOCALE_TAG"]; } if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { if(isset($_REQUEST['localename'])) { $localename = $this->clean($_REQUEST['localename'], "string" ); } else { $localename = ""; } if(isset($_REQUEST['localetag'])) { $localetag = $this->clean($_REQUEST['localetag'], "string" ); } else { $localetag = ""; } if(isset($_REQUEST['writingmode'])) { $writingmode = $this->clean($_REQUEST['writingmode'], "string" ); } else { $writingmode = ""; } if(isset($_REQUEST['selectlocale'])) { $select_locale = $this->clean($_REQUEST['selectlocale'], "string" ); } else { $select_locale = ""; } switch($_REQUEST['arg']) { case "addlocale": $this->localeModel->addLocale( $localename, $localetag, $writingmode); $this->localeModel->extractMergeLocales(); $data["LOCALES"] = $this->localeModel->getLocaleList(); $data['LOCALE_NAMES'][$localetag] = $localename; $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_locale_added')."</h1>')"; break; case "deletelocale": if(!in_array($select_locale, $locale_ids)) { $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_localename_doesnt_exists'). "</h1>')"; return $data; } $this->localeModel->deleteLocale($select_locale); $data["LOCALES"] = $this->localeModel->getLocaleList(); unset($data['LOCALE_NAMES'][$select_locale]); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_localename_deleted')."</h1>')"; break; case "editlocale": if(!isset($select_locale)) break; $data["leftorright"] = (getLocaleDirection() == 'ltr') ? "right": "left"; $data["ELEMENT"] = "editlocalesElement"; $data['STATIC_PAGES'][-1]= tl('admin_controller_select_staticpages'); $data['STATIC_PAGES'] += $this->localeModel->getStaticPageList($select_locale); $data['CURRENT_LOCALE_NAME'] = $data['LOCALE_NAMES'][$select_locale]; $data['CURRENT_LOCALE_TAG'] = $select_locale; $tmp_pages = $data['STATIC_PAGES']; array_shift($tmp_pages); $page_keys = array_keys($tmp_pages); if(isset($_REQUEST['static_page']) && in_array($_REQUEST['static_page'], $page_keys)) { $data["ELEMENT"] = "editstaticElement"; $data['STATIC_PAGE'] = $_REQUEST['static_page']; if(isset($_REQUEST['PAGE_DATA'])) { $this->localeModel->setStaticPage( $_REQUEST['static_page'], $data['CURRENT_LOCALE_TAG'], $_REQUEST['PAGE_DATA']); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_staticpage_updated'). "</h1>')"; } $data['PAGE_NAME'] = $data['STATIC_PAGES'][$data['STATIC_PAGE']]; $data['PAGE_DATA'] = $this->localeModel->getStaticPage( $_REQUEST['static_page'], $data['CURRENT_LOCALE_TAG']); /*since page data can contain tags we clean it htmlentities it just before displaying*/ $data['PAGE_DATA'] = $this->clean($data['PAGE_DATA'], "string"); break; } $data['SCRIPT'] .= "selectPage = elt('static-pages');". "selectPage.onchange = submitStaticPageForm;"; if(isset($_REQUEST['STRINGS'])) { $safe_strings = array(); foreach($_REQUEST['STRINGS'] as $key => $value) { $clean_key = $this->clean($key, "string" ); $clean_value = $this->clean($value, "string" ); $safe_strings[$clean_key] = $clean_value; } $this->localeModel->updateStringData( $select_locale, $safe_strings); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_localestrings_updated'). "</h1>')"; } else { $this->localeModel->extractMergeLocales(); } $data['STRINGS'] = $this->localeModel->getStringData($select_locale); break; } } return $data; } /** * Checks to see if the current machine has php configured in a way * Yioop! can run. * * @return string a message indicatign which required and optional * components are missing; or "Passed" if nothing missing. */ function systemCheck() { $required_items = array( array("name" => "Multi-Curl", "check"=>"curl_multi_init", "type"=>"function"), array("name" => "GD Graphics Library", "check"=>"imagecreate", "type"=>"function"), array("name" => "SQLite3 Library", "check"=>"SQLite3|PDO", "type"=>"class"), array("name" => "Multibyte Character Library", "check"=>"mb_internal_encoding", "type"=>"function"), ); $optional_items = array( array("name" => "Memcache", "check" => "Memcache", "type"=> "class"), ); $missing_required = ""; $comma = ""; foreach($required_items as $item) { $check_function = $item["type"]."_exists"; $check_parts = explode("|", $item["check"]); $check_flag = true; foreach($check_parts as $check) { if($check_function($check)) { $check_flag = false; } } if($check_flag) { $missing_required .= $comma.$item["name"]; $comma = ", "; } } if(!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) { $missing_required .= $comma.tl("admin_controller_php_version"); $comma = ", "; } $out = ""; $br = ""; if(!is_writable(BASE_DIR."/configs/config.php")) { $out .= tl('admin_controller_no_write_config_php'); $br = "<br />"; } if(defined(WORK_DIRECTORY) && !is_writable(WORK_DIRECTORY)) { $out .= $br. tl('admin_controller_no_write_work_dir'); $br = "<br />"; } if(intval(ini_get("post_max_size")) < 32) { $out .= $br. tl('admin_controller_post_size_small'); $br = "<br />"; } if($missing_required != "") { $out .= $br. tl('admin_controller_missing_required', $missing_required); $br = "<br />"; } $missing_optional = ""; $comma = ""; foreach($optional_items as $item) { $check_function = $item["type"]."_exists"; $check_parts = explode("|", $item["check"]); $check_flag = true; foreach($check_parts as $check) { if($check_function($check)) { $check_flag = false; } } if($check_flag) { $missing_optional .= $comma.$item["name"]; $comma = ", "; } } if($missing_optional != "") { $out .= $br. tl('admin_controller_missing_optional', $missing_optional); $br = "<br />"; } if($out == "") { $out = tl('admin_controller_check_passed'); } else { $out = "<span class='red'>$out</span>"; } if(file_exists(BASE_DIR."/configs/local_config.php")) { $out .= "<br />".tl('admin_controller_using_local_config'); } return $out; } /** * Handles admin request related to the search sources activity * * The search sources activity allows a user to add/delete search sources * for video and news, it also allows a user to control which subsearches * appear on the SearchView page * * @return array $data info about current search sources, and current * sub-searches */ function searchSources() { $possible_arguments = array("addsource", "deletesource", "addsubsearch", "deletesubsearch"); $data = array(); $data["ELEMENT"] = "searchsourcesElement"; $data['SCRIPT'] = ""; $data['SOURCE_TYPES'] = array(-1 => tl('admin_controller_media_kind'), "video" => tl('admin_controller_video'), "rss" => tl('admin_controller_rss_feed')); $source_type_flag = false; if(isset($_REQUEST['sourcetype']) && in_array($_REQUEST['sourcetype'], array_keys($data['SOURCE_TYPES']))) { $data['SOURCE_TYPE'] = $_REQUEST['sourcetype']; $source_type_flag = true; } else { $data['SOURCE_TYPE'] = -1; } $machine_urls = $this->machineModel->getQueueServerUrls(); $search_lists = $this->crawlModel->getCrawlList(false, true, $machine_urls); $data["SEARCH_LISTS"] = array(-1 => tl('admin_controller_sources_indexes')); foreach($search_lists as $item) { $data["SEARCH_LISTS"]["i:".$item["CRAWL_TIME"]] = $item["DESCRIPTION"]; } $search_lists= $this->crawlModel->getMixList(); foreach($search_lists as $item) { $data["SEARCH_LISTS"]["m:".$item["MIX_TIMESTAMP"]] = $item["MIX_NAME"]; } $n = NUM_RESULTS_PER_PAGE; $data['PER_PAGE'] = array($n => $n, 2*$n => 2*$n, 5*$n=> 5*$n, 10*$n=>10*$n); if(isset($_REQUEST['perpage']) && in_array($_REQUEST['perpage'], array_keys($data['PER_PAGE']))) { $data['PER_PAGE_SELECTED'] = $_REQUEST['perpage']; } else { $data['PER_PAGE_SELECTED'] = NUM_RESULTS_PER_PAGE; } $locales = $this->localeModel->getLocaleList(); $data["LANGUAGES"] = array(); foreach($locales as $locale) { $data["LANGUAGES"][$locale['LOCALE_TAG']] = $locale['LOCALE_NAME']; } if(isset($_REQUEST['sourcelocaletag']) && in_array($_REQUEST['sourcelocaletag'], array_keys($data["LANGUAGES"]))) { $data['SOURCE_LOCALE_TAG'] = $_REQUEST['sourcelocaletag']; } else { $data['SOURCE_LOCALE_TAG'] = DEFAULT_LOCALE; } if(isset($_REQUEST['arg']) && in_array($_REQUEST['arg'], $possible_arguments)) { switch($_REQUEST['arg']) { case "addsource": if(!$source_type_flag) break; $must_have = array("sourcename", "sourcetype", 'sourceurl'); $to_clean = array_merge($must_have, array('sourcethumbnail','sourcelocaletag')); foreach ($to_clean as $clean_me) { $r[$clean_me] = (isset($_REQUEST[$clean_me])) ? $this->clean($_REQUEST[$clean_me], "string" ) : ""; if(in_array($clean_me, $must_have) && $r[$clean_me] == "" ) break 2; } $this->sourceModel->addMediaSource( $r['sourcename'], $r['sourcetype'], $r['sourceurl'], $r['sourcethumbnail'], $r['sourcelocaletag']); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_media_source_added'). "</h1>');"; break; case "deletesource": if(!isset($_REQUEST['ts'])) break; $timestamp = $this->clean($_REQUEST['ts'], "string"); $this->sourceModel->deleteMediaSource($timestamp); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_media_source_deleted'). "</h1>');"; break; case "addsubsearch": $to_clean = array("foldername", 'indexsource'); $must_have = $to_clean; foreach ($to_clean as $clean_me) { $r[$clean_me] = (isset($_REQUEST[$clean_me])) ? $this->clean($_REQUEST[$clean_me], "string" ) : ""; if(in_array($clean_me, $must_have) && $r[$clean_me] == "" ) break 2; } $this->sourceModel->addSubsearch( $r['foldername'], $r['indexsource'], $data['PER_PAGE_SELECTED']); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_subsearch_added'). "</h1>');"; break; case "deletesubsearch": if(!isset($_REQUEST['fn'])) break; $folder_name = $this->clean($_REQUEST['fn'], "string"); $this->sourceModel->deleteSubsearch($folder_name); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". tl('admin_controller_subsearch_deleted'). "</h1>');"; break; } } $data["MEDIA_SOURCES"] = $this->sourceModel->getMediaSources(); $subsearches = $this->sourceModel->getSubsearches(); $data["SUBSEARCHES"] = array(); foreach($subsearches as $search) { if(isset($data["SEARCH_LISTS"][$search['INDEX_IDENTIFIER']])) { $data["SUBSEARCHES"][] = $search; } else { // $this->sourceModel->deleteSubsearch($search["FOLDER_NAME"]); } } $data['SCRIPT'] .= "source_type = elt('source-type');". "source_type.onchange = switchSourceType;". "switchSourceType()"; return $data; } /** * Responsible for handling admin request related to the configure activity * * The configure activity allows a user to set the work directory for * storing data local to this SeekQuarry/Yioop instance. It also allows one * to set the default language of the installation, dbms info, robot info, * test info, as well as which machine acts as the queue server. * * @return array $data fields for available language, dbms, etc as well as * results of processing sub activity if any */ function configure() { $data = array(); $profile = array(); $data['SYSTEM_CHECK'] = $this->systemCheck(); $languages = $this->localeModel->getLocaleList(); foreach($languages as $language) { $data['LANGUAGES'][$language['LOCALE_TAG']] = $language['LOCALE_NAME']; } if(isset($_REQUEST['lang'])) { $data['lang'] = $this->clean($_REQUEST['lang'], "string"); $profile['DEFAULT_LOCALE'] = $data['lang']; setLocaleObject($data['lang']); } $data["ELEMENT"] = "configureElement"; $data['SCRIPT'] = ""; $data['PROFILE'] = false; $data['MESSAGE'] = ""; if(isset($_REQUEST['WORK_DIRECTORY'])) { $dir = $this->clean($_REQUEST['WORK_DIRECTORY'], "string"); $data['PROFILE'] = true; if(strstr(PHP_OS, "WIN")) { //convert to forward slashes so consistent with rest of code $dir = str_replace("\\", "/", $dir); if($dir[0] != "/" && $dir[1] != ":") { $data['PROFILE'] = false; } } else if($dir[0] != "/") { $data['PROFILE'] = false; } if($data['PROFILE'] == false) { $data["MESSAGE"] = tl('admin_controller_configure_use_absolute_path'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>');" . "setTimeout('window.location.href= ". "window.location.href', 3000);"; $data['WORK_DIRECTORY'] = $dir; return $data; } $data['WORK_DIRECTORY'] = $dir; } else if (defined("WORK_DIRECTORY") && strlen(WORK_DIRECTORY) > 0 && strcmp(realpath(WORK_DIRECTORY), realpath(BASE_DIR)) != 0 && (is_dir(WORK_DIRECTORY) || is_dir(WORK_DIRECTORY."../"))) { $data['WORK_DIRECTORY'] = WORK_DIRECTORY; $data['PROFILE'] = true; } $arg = ""; if(isset($_REQUEST['arg'])) { $arg = $_REQUEST['arg']; } switch($arg) { case "directory": if(!isset($data['WORK_DIRECTORY'])) {break;} if($data['PROFILE'] && file_exists($data['WORK_DIRECTORY']."/profile.php")) { $data = array_merge($data, $this->profileModel->getProfile( $data['WORK_DIRECTORY'])); $this->profileModel->setWorkDirectoryConfigFile( $data['WORK_DIRECTORY']); $data["MESSAGE"] = tl('admin_controller_configure_work_dir_set'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>');setTimeout(". "'window.location.href=window.location.href', 3000);"; } else if ($data['PROFILE'] && strlen($data['WORK_DIRECTORY']) > 0) { if($this->profileModel->makeWorkDirectory( $data['WORK_DIRECTORY'])) { $profile['DBMS'] = 'sqlite3'; $data['DBMS'] = 'sqlite3'; $profile['DB_NAME'] = 'default'; $data['DB_NAME'] = 'default'; $profile['USER_AGENT_SHORT'] = tl('admin_controller_name_your_bot'); $data['USER_AGENT_SHORT'] = $profile['USER_AGENT_SHORT']; if($this->profileModel->updateProfile( $data['WORK_DIRECTORY'], array(), $profile)) { if($this->profileModel->setWorkDirectoryConfigFile( $data['WORK_DIRECTORY'])) { $data["MESSAGE"] = tl('admin_controller_configure_work_profile_made'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>');" . "setTimeout('window.location.href= ". "window.location.href', 3000);"; } else { $data['PROFILE'] = false; $data["MESSAGE"] = tl('admin_controller_configure_no_set_config'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"] . "</h1>');" . "setTimeout('window.location.href= ". "window.location.href', 3000);"; } } else { $this->profileModel->setWorkDirectoryConfigFile( $data['WORK_DIRECTORY']); $data['PROFILE'] = false; $data["MESSAGE"] = tl('admin_controller_configure_no_create_profile'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>'); setTimeout('window.location.href=". "window.location.href', 3000);"; } } else { $this->profileModel->setWorkDirectoryConfigFile( $data['WORK_DIRECTORY']); $data["MESSAGE"] = tl('admin_controller_configure_work_dir_invalid'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>');". "setTimeout('window.location.href=". "window.location.href', 3000);"; $data['PROFILE'] = false; } } else { $this->profileModel->setWorkDirectoryConfigFile( $data['WORK_DIRECTORY']); $data["MESSAGE"] = tl('admin_controller_configure_work_dir_invalid'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"] . "</h1>');" . "setTimeout('window.location.href=". "window.location.href', 3000);"; $data['PROFILE'] = false; } break; case "profile": foreach($this->profileModel->profile_fields as $field) { if(isset($_REQUEST[$field])) { if($field != "ROBOT_DESCRIPTION" && $field != "MEMCACHE_SERVERS") { $clean_field = $this->clean($_REQUEST[$field], "string"); } else { $clean_field = $_REQUEST[$field]; } if($field == "NAME_SERVER" && $clean_field[strlen($clean_field) -1] != "/") { $clean_field .= "/"; } $data[$field] = $clean_field; $profile[$field] = $data[$field]; if($field == "MEMCACHE_SERVERS") { $mem_array = preg_split("/(\s)+/", $clean_field); $profile[$field] = $this->convertArrayCleanLines( $mem_array, "|Z|"); } } if(!isset($data[$field])) { $data[$field] = ""; if(in_array($field, array( 'USE_FILECACHE', 'USE_MEMCACHE', 'IP_LINK', 'CACHE_LINK', 'SIMILAR_LINK', 'IN_LINK', 'SIGNIN_LINK', 'SUBSEARCH_LINK','WORD_SUGGEST', "WEB_ACCESS", 'RSS_ACCESS', 'API_ACCESS'))) { $profile[$field] = false; } } } $data['DEBUG_LEVEL'] = 0; $data['DEBUG_LEVEL'] |= (isset($_REQUEST["ERROR_INFO"])) ? ERROR_INFO : 0; $data['DEBUG_LEVEL'] |= (isset($_REQUEST["QUERY_INFO"])) ? QUERY_INFO : 0; $data['DEBUG_LEVEL'] |= (isset($_REQUEST["TEST_INFO"])) ? TEST_INFO : 0; $profile['DEBUG_LEVEL'] = $data['DEBUG_LEVEL']; $old_profile = $this->profileModel->getProfile($data['WORK_DIRECTORY']); $db_problem = false; if((isset($profile['DBMS']) && $profile['DBMS'] != $old_profile['DBMS']) || (isset($profile['DB_NAME']) && $profile['DB_NAME'] != $old_profile['DB_NAME']) || (isset($profile['DB_HOST']) && $profile['DB_HOST'] != $old_profile['DB_HOST'])) { if(!$this->profileModel->migrateDatabaseIfNecessary( $profile)) { $db_problem = true; } } else if ((isset($profile['DB_USER']) && $profile['DB_USER'] != $old_profile['DB_USER']) || (isset($profile['DB_PASSWORD']) && $profile['DB_PASSWORD'] != $old_profile['DB_PASSWORD'])) { if($this->profileModel->testDatabaseManager( $profile) !== true) { $db_problem = true; } } if($db_problem) { $data['MESSAGE'] = tl('admin_controller_configure_no_change_db'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data['MESSAGE']. "</h1>');"; $data['DBMS'] = $old_profile['DBMS']; $data['DB_NAME'] = $old_profile['DB_NAME']; $data['DB_HOST'] = $old_profile['DB_HOST']; $data['DB_USER'] = $old_profile['DB_USER']; $data['DB_PASSWORD'] = $old_profile['DB_PASSWORD']; break; } if($this->profileModel->updateProfile( $data['WORK_DIRECTORY'], $profile, $old_profile)) { $data['MESSAGE'] = tl('admin_controller_configure_profile_change'); $data['SCRIPT'] = "doMessage('<h1 class=\"red\" >". $data['MESSAGE']. "</h1>');"; if($old_profile['DEBUG_LEVEL'] != $profile['DEBUG_LEVEL']) { $data['SCRIPT'] .= "setTimeout('window.location.href=\"". "?c=admin&a=configure&YIOOP_TOKEN=". $_REQUEST['YIOOP_TOKEN']."\"', 3*sec);"; } } else { $data['PROFILE'] = false; $data["MESSAGE"] = tl('admin_controller_configure_no_change_profile'); $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >". $data["MESSAGE"]. "</h1>');"; break; } break; default: if(isset($data['WORK_DIRECTORY']) && file_exists($data['WORK_DIRECTORY']."/profile.php")) { $data = array_merge($data, $this->profileModel->getProfile( $data['WORK_DIRECTORY'])); $data['MEMCACHE_SERVERS'] = str_replace( "|Z|","\n", $data['MEMCACHE_SERVERS']); } else { $data['WORK_DIRECTORY'] = ""; $data['PROFILE'] = false; } } if($data['PROFILE']) { $data['DBMSS'] = array(); $data['SCRIPT'] .= "logindbms = Array();\n"; foreach($this->profileModel->getDbmsList() as $dbms) { $data['DBMSS'][$dbms] = $dbms; if($this->profileModel->loginDbms($dbms)) { $data['SCRIPT'] .= "logindbms['$dbms'] = true;\n"; } else { $data['SCRIPT'] .= "logindbms['$dbms'] = false;\n"; } } if(!isset($data['ROBOT_DESCRIPTION']) || strlen($data['ROBOT_DESCRIPTION']) == 0) { $data['ROBOT_DESCRIPTION'] = tl('admin_controller_describe_robot'); } else { //since the description might contain tags we apply htmlentities $data['ROBOT_DESCRIPTION'] = $this->clean($data['ROBOT_DESCRIPTION'], "string"); } if(!isset($data['MEMCACHE_SERVERS']) || strlen($data['MEMCACHE_SERVERS']) == 0) { $data['MEMCACHE_SERVERS'] = "localhost"; } $data['SCRIPT'] .= "elt('database-system').onchange = function () {" . "setDisplay('login-dbms',". "self.logindbms[elt('database-system').value]);};" . "setDisplay('login-dbms', ". "logindbms[elt('database-system').value]);\n"; $data['SCRIPT'] .= "elt('use-memcache').onchange = function () {" . "setDisplay('filecache',". "(elt('use-memcache').checked) ? false: true);" . "setDisplay('memcache',". "(elt('use-memcache').checked) ? true : false);};" . "setDisplay('filecache', ". "(elt('use-memcache').checked) ? false : true);\n". "setDisplay('memcache', ". "(elt('use-memcache').checked) ? true : false);\n"; } $data['SCRIPT'] .= "elt('locale').onchange = ". "function () { elt('configureProfileForm').submit();};\n"; return $data; } } ?>