MODх — records of site visitors and schedule visits

Like many programmers, I suffer some degree of suspicion towards other services and prefer to do everything myself.
To foreign services, in particular, liveinternet and other usages. I like that they don't trust, you know.

Now I'll tell (and show) it is easy to do for the visitors of the site with modx.


Step 1. Writing the log.


First we need to create a table to store visits. Doing sql query as you wish. For example, in phpmyadmin.
the
CREATE TABLE IF NOT EXISTS `modx_visitors_log` (
`index` int(10) NOT NULL AUTO_INCREMENT,
`ip` varchar(15) COLLATE utf8_unicode_ci is a NOT NULL,
`host` varchar(255) COLLATE utf8_unicode_ci is a DEFAULT NULL,
`url` text COLLATE utf8_unicode_ci is a NOT NULL,
`datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`referer` text COLLATE utf8_unicode_ci is a NOT NULL,
`browser` varchar(255) NOT NULL,
PRIMARY KEY (`index`),
KEY `ip` (`ip`,`host`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci is a AUTO_INCREMENT=1 ;

The table is ready, now we need a plugin to fix the visits.

Most of the users know about the snippets and chunks in modx, but about plug-ins is usually not aware of. Talk: plugin in modx, if simple is the snippet that works without a call to from the document itself, in response to system events, of which the engine provides quite a lot. We are interested in the event OnLogPageHit.

Go to
the Features->controls->Plugins->Create a plugin

A new plugin called dbLog and insert the following code to it:
the
/* Basic settings*/
// Table for the log of visitors by default, this is modx_visitors_log
$db = "modx_visitors_log`;
// Don't log these users and IP. If you logg all - should be empty arrays
$not_log_ip = array('192.168.100.1', '192.168.100.2');
$not_log_user = array('bezumkin');
/* End of settings */

// Exposed variables
$login = $_SESSION['webShortname']; // If you users are authenticated on the website. If there is an empty field.
$ip = $_SERVER['REMOTE_ADDR']; // requestor's IP address. Check for proxy no.
$host = "; // Here is the hostname belonging to the IP user. Not yet touched.
$url = $_SERVER['REQUEST_URI']; // the Requested page.
$referer = urlencode($_SERVER['HTTP_REFERER']); // Where did the user what the link.
$browser = mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']); // Browser user. I use the browscap class, what do you want. For example, you'll be fine.

// Write in log
if (!in_array($ip, $not_log_ip) and !in_array($login, $not_log_login)) {
$modx->db->query("INSERT INTO $db (`login`, `ip`, `host`, `url`, `referer`,`browser`)
VALUES ('$login','$ip','$host', '$url','$referer','$browser')");
}

Switch tab, System events and set OnLogPageHit, and then click save. Please note: when placing the plugin in the editor, the admin should not be <?php and ?> after. Should have snippets and plugins — no. Don't know why it was made, but when writing their first pagina I did a lot of swearing.
All, the plugin should fix all your visitors. Unless of course you are never wrong!

By the way, there is another option to frame the operation of the plug-in event OnWebPageComplete. Then you need to be in admin settings to enable the "Record visits" and will work the same tircik in the document properties. Also not a bad option, but I haven't tried. Read more about events you can look here.

If you want to know the names of the hosts which are registered on the ip of your visitors, you can make another snippet (Ip2Host) and run it on schedule.
Why? This will save power for the server, because if you know the host user at each page request — the load is serious. It is better to run once a day at night.
the
<?php
$db = "modx_visitors_log`;

// Select all records that have a blank host
$sql = $modx->db->query("SELECT `ip` FROM $db WHERE `host` =" GROUP BY `ip`");
$arr = $modx- > db- > makeArray($sql);

// Iterate through all of them
foreach ($arr as $v) {
$ip = $v['ip'];
// Do a normal nslookup. If a website is hosted on Windows, first, I pity you, and secondly, this line will have to change to something else.
$host = `nslookup "$ip" | grep 'name =' | awk '{print $4}";
// If the name we would write that the host is not known to re-not to choose next time.

//Save the result in database.
$modx->db->query("UPDATE $db SET `host` = '$host' WHERE `ip` = '$ip' AND `host` = ";");
}
?>

Need to make a call on some hidden from the page:
[!Ip2Host!]

and pull her cron Ohm:
10 2 * * * * user wget localhost/secret_page.html


the second Stage. Output log to the screen.


In principle, your visits are already in the database, and display them from there-how convenient. Personally, I am happy to see this in nice graphics and private plate numbers.

Let's do that.

Write the snippet for the abstraction of data from the database and display them in a clear table, graph will do later. Comments as usual, within the code.
the
<?php
/* Basic settings */
if (empty($db)) {$db = "modx_visitors_log`;} // Database log
if (empty($days)) {$days = 14;} // number of days to display the table
if (empty($daysText)) {$daysText = 'days';} // the Text after the number of days in the chunk, not necessarily
if (empty($tpl)) {$tpl = 'visitStat.tpl';} // Template for the table
if (empty($act)) {$act = 'graph';} // output Mode table, only two of them, graph & table
if (empty($dateFormat)) {$dateFormat = '%d.%m';} // output date format for strftime()
if (empty($int)) {$int = 2;} // Interval at which to display the date in the graph mode. the default is every second.
/* End of settings */

// Find out how much time to select data
$cur = time();
$end = date("Y-m-d");
$start = strftime("%Y-%m-%d", ($cur - ($days * 86400)));

// Choose
$sql = $modx->db->query("SELECT DATE(`datetime`) as `date`,
COUNT(distinct `ip`) as `host`, 
COUNT(`ip`) as `hit` 
FROM $db WHERE DATE(`datetime`) BETWEEN '$start' AND '$end' 
GROUP BY DATE(`datetime`) ORDER BY `datetime` ASC");
$result = $modx- > db- > makeArray($sql);

// Parse the result on 3 different array, date, hosts and hits 
foreach($result as $v) {
$date[] = $v['date'];
$host[] = $v['host'];
$hit[] = $v['hit'];
}

// Graph displayed each $int date, in Datasheet view - all the dates
$i = 1;
foreach ($date as $v) { 
if ($act == 'graph') {
if ($i == $int) {
$i = 0;
$date2 .= '<th></th>';
} 
else {
$date2 .= '<th>'.strftime($dateFormat, strtotime($v)).'</th>';
}
$i++;
}
else if ($act == 'table') {
$date2 .= '<th>'.strftime($dateFormat, strtotime($v)).'</th>';
}
}
foreach ($host as $v) {
$host2 .= '<td>'.$v.'</td>';
}
foreach ($hit as $v) {
$hit2 .= '<td>'.$v.'</td>';
}

$placeholders = array('[+stat.days+]','[+stat.days.text+]','[+stat.date+]','[+stat.host+]','[+stat.hit+]');
$values = array($days, $daysText, $date2, $host2, $hit2);

$html = $modx- > getChunk($tpl);

echo str_replace($placeholders, $values, $html);
?>

Create a snippet called it, for example, generateStatGraph, copy there code and save.

Now we need to display the result of our intense activity.
We will need two chunks of the template. first, just for the table, the second is more difficult to plot. They can be used independently from each other.

The first template to output the table (tpl.StatTable).
the
<div style='margin: auto;text-align: center;'>
<table id='chart_table'>
<caption>Statistics of visits to the site over the past [+stat.days+] [+stat.days.text+]</caption>
<thead>
<tr><td></td>[+stat.date+]</tr>
</thead>
<tbody>
<tr><th>Visitors</th>[+stat.host+]</tr>
<tr><th>Views</th>[+stat.hit+]</tr>
</tbody>
</table>
</div>


The second template, to plot (tpl.StatGraph).
the
<link type='text/css' rel='stylesheet' href='[(site_url)]inc/css/visualize.css' /> 
<script type='text/javascript' src='[(site_url)]inc/js/visualize.jquery.js'></script>
<script type='text/javascript'>
$(document).ready(function(){
$('#chart').visualize({
type: 'area',
width: '570',
height: '300'
}); 
});
</script>
<div style='margin: auto;'>
<table id='chart' style='display: none;'>
<caption>Statistics of visits to the site over the past [+stat.days+] [+stat.days.text+]</caption>
<thead>
<tr><td></td>[+stat.date+]</tr>
</thead>
<tbody>
<tr><th>Visitors</th>[+stat.host+]</tr>
<tr><th>Views</th>[+stat.hit+]</tr>
</tbody>
</table>
</div>


As you can see, these two templates differ by the presence of the second connecting great jquery plugin jQuery Visualize, which allows us to build charts from tables. As well as the design of this chart.
Rendering graphics is triggered with the following code (for details about the parameters of jquery.visualize, as well as examples of design — from the above link):
$('#chart').visualize({ type: 'area', width: '570', height: '300' }); });
Ufff... almost everything.

Step 3. Run!


Create a new document, modx and run it snippet (separate chart).
the
[!generateStatGraph?
&days=`20`
&tpl=`tpl.StatTable`
&act=`table`
&dateFormat=`%d <i>%b</i>`
!]

[!generateStatGraph?
&days=`20`
&daysText=`days`
&tpl=`tpl.StatGraph`
&act=`graph`
&dateFormat=`%d`
!]


I would Like to note that here we considered only screening of the anonymous statistics of visits, and in database we have stored information about the ip, time of visits, the browsers of users and so on. This information you can view or directly from the database, or write a simple snippet + chunk clearance for withdrawal of the site, in a protected section.

Application.


This is curious — is it possible view result, at the same time to personally check out gebrettert.
By the way, apparently non-acidic difference statistics, which, I gather, and which shows liveinternet counter on the bottom of each page.

Options generateStatGraph snippet:
&db
the default: `modx_visitors_log`
value: [string]
description: Name of an existing table, the database (`modx`.`modx_log`).

&dateFormat
the default: '%d %b %Y %H:%M'
value: variable strftime()
description: date Format.

&days
the default: 14
value: [int]
description: the Number of days of sampling visits from now.

&$daysText
the default: 'days'
value: [string]
description: the label Text for the number of days of sampling, not necessarily used only in templates.

&tpl
the default: 'tpl.StatGraph'
value: the Name of an existing template modx
description: Template to output the table.

&act
the default: 'graph',
value: a graph, table
description: processing Mode table in the output. graph ignores date.

&int
the default: 2
value: [int]
description: If &act=`graph`, &the int indicates what date each show. by default, every second.


Placeholder eventsCalendar snippet:
[+stat.days+]
the Number of days sample
[+stat.days.text+]
Caption of the day.
[+stat.date+]
date in a specified format.
[+stat.host+]
the Number of unique visits per day (hosts).
[+stat.hit+]
Number are not unique visits per day (hits).


Links to relevant sites.
the

Bug reports send to bezumkin@yandex.ru, or write in this thread.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Monitoring PostgreSQL + php-fpm + nginx + disk using Zabbix

Templates ESKD and GOST 7.32 for Lyx 1.6.x

Customize your Google