2011-05-02 09:17:45 +00:00
|
|
|
|
<?php
|
|
|
|
|
/*
|
2011-11-14 08:13:34 +00:00
|
|
|
|
Plugin Name: semmelstatzR
|
2011-08-23 14:08:57 +00:00
|
|
|
|
Plugin URI: http://sourceforge.net/projects/semmelstatz/
|
|
|
|
|
Description: Visitorstatistic for Wordpress, based upon the original wp-plugin semmelstatz by Andreas 'Redunzl' Mueller (http://www.kopfhoch-studio.de)
|
2011-11-14 08:13:34 +00:00
|
|
|
|
Version: 1.0.0 Beta
|
|
|
|
|
Author: SEM-Team
|
|
|
|
|
Author URI: http://semmelstatz.sf.net
|
|
|
|
|
License: GPLv3
|
|
|
|
|
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
2011-05-02 09:17:45 +00:00
|
|
|
|
*/
|
2011-05-02 10:30:11 +00:00
|
|
|
|
/**
|
|
|
|
|
* file semmelstatzR.php
|
|
|
|
|
*
|
2011-11-14 14:21:22 +00:00
|
|
|
|
* @package SemmelstatzR
|
|
|
|
|
* @version $Rev$
|
|
|
|
|
* @since 1.0.0 Beta
|
|
|
|
|
* @author SEM-Team
|
|
|
|
|
* @copyright (c)2011 SEM-Team
|
|
|
|
|
* @link http://sourceforge.net/projects/semmelstatz/
|
|
|
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html
|
2011-11-14 08:13:34 +00:00
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-05-02 10:30:11 +00:00
|
|
|
|
*
|
|
|
|
|
* $Id$
|
2011-11-14 08:13:34 +00:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
/**
|
|
|
|
|
* based upon semmelstatz
|
2011-05-02 10:30:11 +00:00
|
|
|
|
* Copyright (c) 2005-2009 Andreas 'Redunzl' Mueller (redunzl@gmx.de)
|
2011-11-14 08:13:34 +00:00
|
|
|
|
*
|
|
|
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.html
|
2011-05-02 10:30:11 +00:00
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License (version 2) as
|
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2011-05-02 09:17:45 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2011-11-14 08:13:34 +00:00
|
|
|
|
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'semmelstatzR_startup.php';
|
2011-08-23 14:08:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(is_admin() == true) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* add CSS
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
function semmelstatzR_css() {
|
|
|
|
|
print "<link rel='stylesheet' href='".get_option('siteurl')."/wp-content/plugins/semmelstatzR/semmelstatzR.css' type='text/css' media='screen' />\n";
|
|
|
|
|
}
|
|
|
|
|
add_action('admin_head', 'semmelstatzR_css');
|
|
|
|
|
### End add CSS
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* add toplevel menu into admin
|
|
|
|
|
*
|
|
|
|
|
* @todo localization
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
function semmelstatzR_menu() {
|
|
|
|
|
if (function_exists('add_menu_page')) {
|
|
|
|
|
add_menu_page('SemmelstatzR','SemmelstatzR', 'manage_statz', 'semmelstatzR/semmelstatzR-statz.php', '', plugins_url('semmelstatzR/img/statz_small.png'));
|
|
|
|
|
}
|
|
|
|
|
if (function_exists('add_submenu_page')) {
|
2011-08-24 09:20:32 +00:00
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('Current Statz'), semr_i18n('Current Statz'), 'manage_statz', 'semmelstatzR/semmelstatzR-statz.php');
|
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('History'), semr_i18n('History'), 'manage_statz', 'semmelstatzR/semmelstatzR-history.php');
|
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('Log'), semr_i18n('Log'), 'manage_statz', 'semmelstatzR/semmelstatzR-log.php');
|
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('Database'), semr_i18n('Database'), 'manage_statz', 'semmelstatzR/semmelstatzR-database.php');
|
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('Templates'), semr_i18n('Templates'), 'manage_statz', 'semmelstatzR/semmelstatzR-templates.php');
|
|
|
|
|
add_submenu_page('semmelstatzR/semmelstatzR-statz.php', semr_i18n('Options'), semr_i18n('Options'), 'manage_statz', 'semmelstatzR/semmelstatzR-options.php');
|
2011-08-23 14:08:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
add_action('admin_menu', 'semmelstatzR_menu');
|
|
|
|
|
### end add toplevel adminmenu
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* write defaults to options-array
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2011-05-02 09:17:45 +00:00
|
|
|
|
function sem_init_options() {
|
2011-08-23 14:08:57 +00:00
|
|
|
|
global $wpdb;
|
|
|
|
|
|
|
|
|
|
if(get_option('statz_options')) {
|
|
|
|
|
$wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE 'statz%';"); // L<>schen der alten Optionen
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-02 10:30:11 +00:00
|
|
|
|
if(!get_option('semmelstatzR_options')) {
|
2011-08-23 14:08:57 +00:00
|
|
|
|
$sem_options = array(
|
|
|
|
|
"statz_comment_limit" => 10,
|
|
|
|
|
"statz_datarecs_limit" => 100,
|
|
|
|
|
"statz_days_limit" => 7,
|
|
|
|
|
"statz_do_cron" => false,
|
|
|
|
|
"statz_encode_ip" => false,
|
|
|
|
|
"statz_keyword_limit" =>10,
|
|
|
|
|
"statz_referer_limit" => 10,
|
|
|
|
|
"statz_mask_referer" => false,
|
|
|
|
|
"statz_on_dashboard" => false,
|
|
|
|
|
"statz_online_time" => 180,
|
|
|
|
|
"statz_recdays_limit" => 20,
|
|
|
|
|
"statz_show_commenters" => true,
|
|
|
|
|
"statz_show_dailystatz" => true,
|
|
|
|
|
"statz_show_keywords" => true,
|
|
|
|
|
"statz_show_reads" => true,
|
|
|
|
|
"statz_show_referers" => true,
|
|
|
|
|
"statz_show_todayreads" => true,
|
|
|
|
|
"statz_show_todayusers" => true,
|
|
|
|
|
"statz_show_topcommposts" => true,
|
|
|
|
|
"statz_show_useronline" => true,
|
|
|
|
|
"statz_topreads_limit" => 10,
|
|
|
|
|
"statz_write_admins" => false,
|
|
|
|
|
"statz_write_users" => false,
|
|
|
|
|
"statz_use_img" => true
|
|
|
|
|
);
|
|
|
|
|
add_option( 'semmelstatzR_options', $sem_options );
|
|
|
|
|
}
|
2011-05-02 09:17:45 +00:00
|
|
|
|
}
|
2011-08-23 14:08:57 +00:00
|
|
|
|
add_action('init', 'sem_init_options');
|
|
|
|
|
### End write defaults to options-array
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-02 09:17:45 +00:00
|
|
|
|
|
|
|
|
|
### Anlegen der Tabellen, Optionen schreiben
|
2011-08-23 14:08:57 +00:00
|
|
|
|
add_action('activate_semmelstatzR/semmelstatzR.php', 'sem_statzsetup');
|
|
|
|
|
function sem_statzsetup() {
|
|
|
|
|
global $wpdb;
|
|
|
|
|
if(@is_file(ABSPATH.'/wp-admin/upgrade-functions.php')) {
|
|
|
|
|
include_once(ABSPATH.'/wp-admin/upgrade-functions.php');
|
|
|
|
|
} elseif(@is_file(ABSPATH.'/wp-admin/includes/upgrade.php')) {
|
|
|
|
|
include_once(ABSPATH.'/wp-admin/includes/upgrade.php');
|
|
|
|
|
} else {
|
|
|
|
|
die('Kann <i>wp-admin/upgrade-functions.php</i> und <i>wp-admin/includes/upgrade.php</i> nicht finden!');
|
2011-05-02 09:17:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-23 14:08:57 +00:00
|
|
|
|
$create_table = array();
|
|
|
|
|
$create_table['statz'] = "CREATE TABLE $wpdb->statz (
|
|
|
|
|
id int(11) unsigned NOT NULL auto_increment,
|
|
|
|
|
ip varchar(39) default NULL,
|
|
|
|
|
time datetime NOT NULL default '0000-00-00 00:00:00',
|
|
|
|
|
referer varchar(255) default NULL,
|
|
|
|
|
page int(11) unsigned NOT NULL default '0',
|
|
|
|
|
username varchar(255) default NULL,
|
|
|
|
|
PRIMARY KEY (`id`))";
|
|
|
|
|
$create_table['statzhist'] = "CREATE TABLE $wpdb->statzhist (
|
|
|
|
|
id int(10) unsigned NOT NULL auto_increment,
|
|
|
|
|
date datetime NOT NULL default '0000-00-00 00:00:00',
|
|
|
|
|
visitors int(10) unsigned NOT NULL default '0',
|
|
|
|
|
hits int(10) unsigned NOT NULL default '0',
|
|
|
|
|
referers int(10) unsigned NOT NULL default '0',
|
|
|
|
|
PRIMARY KEY (`id`))";
|
|
|
|
|
|
|
|
|
|
maybe_create_table($wpdb->statz, $create_table['statz']);
|
|
|
|
|
maybe_create_table($wpdb->statzhist, $create_table['statzhist']);
|
|
|
|
|
|
|
|
|
|
$sql = $wpdb->query("SELECT host FROM $wpdb->statz");
|
|
|
|
|
if($sql) { $wpdb->query("ALTER TABLE $wpdb->statz DROP host"); }
|
|
|
|
|
|
|
|
|
|
$sql = $wpdb->query("SELECT keyword FROM $wpdb->statz");
|
|
|
|
|
if($sql) { $wpdb->query("ALTER TABLE $wpdb->statz DROP keyword"); }
|
|
|
|
|
|
|
|
|
|
maybe_add_column($wpdb->posts, 'hits', "ALTER TABLE $wpdb->posts ADD hits bigint(20) NOT NULL DEFAULT '0';"); // ab 3.2
|
|
|
|
|
|
|
|
|
|
$wpdb->query("ALTER TABLE $wpdb->statz CHANGE ip ip VARCHAR(39) NULL DEFAULT NULL;");
|
|
|
|
|
|
|
|
|
|
sem_init_options();
|
|
|
|
|
sem_writeOldDaysToHist();
|
|
|
|
|
|
|
|
|
|
$role = get_role('administrator');
|
|
|
|
|
if(!$role->has_cap('manage_statz')) {
|
|
|
|
|
$role->add_cap('manage_statz');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-02 09:17:45 +00:00
|
|
|
|
### Zugriff analysieren und in statz-Tabelle schreiben
|
2011-08-23 14:08:57 +00:00
|
|
|
|
add_action('wp_footer', 'sem_writeStatz');
|
|
|
|
|
function sem_writeStatz() {
|
|
|
|
|
global $wpdb, $wp_query, $isBot, $isAdmin, $page;
|
|
|
|
|
$plugin_dir = basename(dirname(__FILE__));
|
|
|
|
|
$sem_options = get_option('semmelstatzR_options'); ### optionsarray auslesen
|
|
|
|
|
|
|
|
|
|
// true === $sem_options['statz_use_img'] &&
|
|
|
|
|
if(true == $sem_options['statz_use_img'] && !defined('SEMMELSTATZR_STATZIMG')) {
|
|
|
|
|
print '<img src="'.SEMMELSTATZR_HTML_RELPATH.'semr_image.php" alt="" />';
|
|
|
|
|
return; ### nothing todo if stat image is used
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sem_writeYesterdayToHist();
|
|
|
|
|
$useragent = $wpdb->escape($_SERVER['HTTP_USER_AGENT']);
|
|
|
|
|
$isBot = sem_AreYouBot($useragent);
|
|
|
|
|
$username = sem_getUsername();
|
|
|
|
|
|
|
|
|
|
if(($isBot == true)
|
|
|
|
|
|| ($isAdmin == 0 && $sem_options['statz_write_users'] == false)
|
|
|
|
|
|| ($isAdmin == 1 && $sem_options['statz_write_admins'] == false)
|
|
|
|
|
|| is_404()
|
|
|
|
|
) return;
|
|
|
|
|
|
|
|
|
|
$userip = $wpdb->escape($_SERVER['REMOTE_ADDR']);
|
|
|
|
|
if($sem_options['statz_encode_ip'] == true) $userip = sem_encodeIP($userip);
|
|
|
|
|
|
|
|
|
|
$referer = $wpdb->escape(urldecode($_SERVER['HTTP_REFERER']));
|
|
|
|
|
$blogtime = gmdate('Y-m-d H:i:s', current_time('timestamp'));
|
|
|
|
|
|
|
|
|
|
if (!empty($referer)) {
|
|
|
|
|
if(get_option('blog_charset') == 'iso-8859-1') $referer = utf8_decode($referer);
|
|
|
|
|
$referer = "'".$referer."'";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$referer = 'NULL';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$readingnow = wp_title('', false);
|
|
|
|
|
if(empty($readingnow)) {
|
|
|
|
|
$page = 0;
|
|
|
|
|
} else {
|
|
|
|
|
$page = $wp_query->post->ID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wpdb->query("INSERT INTO $wpdb->statz (ip, time, referer, page, username)
|
|
|
|
|
VALUES('$userip', '$blogtime', $referer, $page, '$username')");
|
|
|
|
|
|
|
|
|
|
if($wpdb->query("SELECT COUNT(hits) FROM $wpdb->posts")) {
|
|
|
|
|
$wpdb->query("UPDATE $wpdb->posts SET hits = hits + 1 WHERE ID = $page"); // neu ab 3.2
|
2011-05-02 09:17:45 +00:00
|
|
|
|
}
|
2011-08-23 14:08:57 +00:00
|
|
|
|
}
|
2011-05-02 09:17:45 +00:00
|
|
|
|
|
|
|
|
|
### Zeitgesteuertes Limitieren der statz-Tabelle
|
|
|
|
|
// Wenn semmelKron JA UND statz_next_cron <20>lter JETZT, dann...
|
2011-05-02 10:30:11 +00:00
|
|
|
|
$sem_options = get_option('semmelstatzR_options'); ### optionsarray auslesen
|
2011-05-02 09:17:45 +00:00
|
|
|
|
if($sem_options['statz_do_cron'] == true && $sem_options['statz_next_cron'] < time()) {
|
|
|
|
|
add_action('shutdown', 'sem_doCronStatzLimit'); // ...limitiere statz-Tabelle auf vorgegebenen Wert
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
### Rendert eine Mini-STATZ. Idee: Ren<65> Tauchnitz
|
2011-08-23 14:08:57 +00:00
|
|
|
|
function sem_dashboardStatz_show() {
|
|
|
|
|
|
|
|
|
|
$widgets = get_option( 'dashboard_widget_options' );
|
2011-05-02 16:38:26 +00:00
|
|
|
|
echo '<p>';
|
|
|
|
|
printf(_n("%d Visitor online", "%d Visitors online", sem_showNumUsersOnline(), "semmelstatzR"), sem_showNumUsersOnline());
|
|
|
|
|
echo ' - ';
|
|
|
|
|
printf(__("Today: %s", "semmelstatzR"),sem_showTodayStatz());
|
|
|
|
|
echo ' <a title="'.__("more...", "semmelstatzR").'" href="'.get_option('siteurl').'/wp-admin/admin.php?page=semmelstatzR/semmelstatzR-statz.php">»»</a>';
|
|
|
|
|
echo '</p>';
|
|
|
|
|
}
|
2011-08-23 14:08:57 +00:00
|
|
|
|
|
|
|
|
|
function sem_dashboardStatz_control() {
|
|
|
|
|
if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
|
|
|
|
|
$widget_options = array();
|
|
|
|
|
|
|
|
|
|
if ( !isset($widget_options['dashboard_sem_dashboardStatz']) )
|
|
|
|
|
$widget_options['dashboard_sem_dashboardStatz'] = array();
|
|
|
|
|
|
|
|
|
|
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['dashboard-sem-dashboardStatz']) ) {
|
|
|
|
|
$number = absint( $_POST['dashboard-sem-dashboardStatz']['items'] );
|
2011-08-24 09:20:32 +00:00
|
|
|
|
$number = ($number > 20)?20:$number;
|
2011-08-23 14:08:57 +00:00
|
|
|
|
$widget_options['dashboard_sem_dashboardStatz']['items'] = $number;
|
|
|
|
|
update_option( 'dashboard_widget_options', $widget_options );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$number = isset( $widget_options['dashboard_sem_dashboardStatz']['items'] ) ? (int) $widget_options['dashboard_sem_dashboardStatz']['items'] : '';
|
|
|
|
|
|
2011-08-24 09:20:32 +00:00
|
|
|
|
echo '<p><label for="sem-number">' . semr_i18n('Number of Items (max. 10):') . '</label>';
|
2011-08-23 14:08:57 +00:00
|
|
|
|
echo '<input id="sem-number" name="dashboard-sem-dashboardStatz[items]" type="text" value="' . $number . '" size="3" /></p>';
|
|
|
|
|
|
2011-08-24 09:20:32 +00:00
|
|
|
|
//print_r($widget_options['dashboard_sem_dashboardStatz']);
|
2011-08-23 14:08:57 +00:00
|
|
|
|
}
|
2011-05-02 09:17:45 +00:00
|
|
|
|
|
2011-08-24 09:20:32 +00:00
|
|
|
|
/**
|
|
|
|
|
* Callback generating a small dashboard widget
|
|
|
|
|
*
|
|
|
|
|
* @uses sem_showTodayStatz() to generate the content
|
|
|
|
|
* @uses wp_add_dashboard_widget() to generate widget
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2011-05-02 16:38:26 +00:00
|
|
|
|
function sem_dashboardStatz_setup() {
|
|
|
|
|
$sem_options = get_option('semmelstatzR_options'); ### optionsarray auslesen
|
|
|
|
|
if(!current_user_can('manage_statz')) return;
|
|
|
|
|
if($sem_options['statz_on_dashboard'] != true) return;
|
2011-08-23 14:08:57 +00:00
|
|
|
|
wp_add_dashboard_widget( 'sem_dashboardStatz', 'SemmelstatzR', 'sem_dashboardStatz_show', 'sem_dashboardStatz_control' );
|
2011-05-02 16:38:26 +00:00
|
|
|
|
}
|
2011-05-02 09:17:45 +00:00
|
|
|
|
|
2011-08-24 09:20:32 +00:00
|
|
|
|
add_action('wp_dashboard_setup', 'sem_dashboardStatz_setup');
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* generates and returns content for a small dashboard widget
|
|
|
|
|
*
|
|
|
|
|
* @global wpdb $wpdb
|
|
|
|
|
* @return string formated string/html for dashboard
|
|
|
|
|
*/
|
2011-05-02 09:17:45 +00:00
|
|
|
|
function sem_showTodayStatz() {
|
|
|
|
|
global $wpdb;
|
|
|
|
|
$thedays = $wpdb->get_results("SELECT COUNT(ip) AS hits, COUNT(DISTINCT ip) AS visitors, COUNT(DISTINCT referer)
|
|
|
|
|
AS referers, substring(time,1,10) AS date FROM ".$wpdb->statz." WHERE time >= CURDATE() GROUP BY date");
|
2011-08-23 14:08:57 +00:00
|
|
|
|
//$thedays = array(array('hits' => 33));
|
2011-05-02 09:17:45 +00:00
|
|
|
|
if (empty($thedays)) {
|
2011-08-24 09:20:32 +00:00
|
|
|
|
return "<small>".semr_i18n("... no entries")."</small>";
|
2011-05-02 09:17:45 +00:00
|
|
|
|
}
|
|
|
|
|
foreach($thedays as $key=>$theday) {
|
|
|
|
|
$date = mysql2date("l",$theday->date);
|
|
|
|
|
$hits = $theday->hits;
|
|
|
|
|
$visitors = $theday->visitors;
|
|
|
|
|
$referers = $theday->referers;
|
|
|
|
|
}
|
2011-08-24 09:20:32 +00:00
|
|
|
|
return sprintf(semr_i18np("%d Visitor","%d Visitors",$visitors),$visitors)." - "
|
|
|
|
|
.sprintf(semr_i18np("%d Hit","%d Hits",$hits),$hits)." - "
|
|
|
|
|
.sprintf(semr_i18np("%d Referer","%d Referers",$referers),$referers);
|
2011-05-02 09:17:45 +00:00
|
|
|
|
}
|
2011-11-14 08:13:34 +00:00
|
|
|
|
?>
|