<?phpif (($phad_block??null)===\Phad\Blocks::SITEMAP_META){
returnarray (
);
}
?><?phpif ($phad_block===\Phad\Blocks::ROUTE_META){
returnarray (
0 =>
array (
'pattern' => '/analytics/',
),
);
}
?>
<h1>Analytics across our site</h1>
<p>Analytics are helpful to learn what web pages are being visited. This analytics library attempts to be as privacy-respecting as possible, though the technical implementation is pretty lazy.</p>
<h2>For all time</h2>
<p>Well, since this analytics lib was installed anyway.</p>
<table border="1" style="border-collapse:collapse;">
<thead>
<th>Url</th>
<th>Hits</th>
</thead>
<tbody>
<?php/** template originally developed on jan 20, 2022
* @param \Phad $phad an object that handles the callback methods in the template. Can be any type, if you wish to change it from `\Phad`
*/## becomes $BlogInfo$tlf_analyticsInfo = (object)[
'name'=> 'tlf_analytics', //becomes Blog'mode'=>$phad_block,
'apis'=> array (
0 => 'view',
1 => 'data',
), //rawdata generally json. could be sql or csv though'type'=>'view', //just view or form at this point'args'=>$args,
'data_index'=>false,
'data_nodes' => array (
0 =>
array (
'sql' => 'SELECT url, COUNT(*) as hits FROM tlf_analytics GROUP BY url ORDER BY hits DESC LIMIT 300',
'type' => 'node',
),
1 =>
array (
'type' => 'default',
),
), // each contains access="role:admin" & sql="Select * ...", etc'response_code' => false, // could start as 500?'rows'=>[], // could start null/false?'errors'=>[], // just gets appended to by whatever when there's a problem'submit_errors'=>[],
];
$phad->item_initialized($tlf_analyticsInfo);
if ($phad_block==\Phad\Blocks::ITEM_META){
return$tlf_analyticsInfo;
}
foreach ($tlf_analyticsInfo->data_nodes as$_index=>&$_node){
$_node['index'] = $_index;
if (isset($_node['if'])){
//@todo templatize p-data 'if' attribute instead of using `eval()`$eval_code = 'return ('.$_node['if'].');';
$result = eval($eval_code);
if (!$result){
$_node['response_code'] = 403;
$tlf_analyticsInfo->response_code = 403;
continue;
}
}
if (!$phad->can_read_data($_node, $tlf_analyticsInfo)){
$tlf_analyticsInfo->response_code = 403;
$_node['response_code'] = 403;
continue;
}
// may include getting $args['Blog'] or $args['BlogList'] instead of using a query$tlf_analyticsInfo->rows = $phad->read_data($_node, $tlf_analyticsInfo);
if (count($tlf_analyticsInfo->rows)==0){
$tlf_analyticsInfo->response_code = 404;
$_node['response_code'] = 404;
continue;
}
$tlf_analyticsInfo->response_code = 200;
$_node['response_code'] = 200;
$tlf_analyticsInfo->data_index = $_index;
break;
}
if ($phad_block == \Phad\Blocks::ITEM_DATA){
// does not handle nested items. I'm okay with that, for now ... i can always make separate item viewsreturn$phad->get_rows($tlf_analyticsInfo);
}
foreach ($tlf_analyticsInfo->rows as$RowIndex_tlf_analytics => $tlf_analyticsRow ):
$tlf_analytics = $phad->object_from_row($tlf_analyticsRow, $tlf_analyticsInfo);
?><tr>
<td><?=$tlf_analytics->url?></td>
<td><?=$tlf_analytics->hits?></td>
</tr><?phpendforeach;
?>
</tbody>
</table>
<h2>This Month</h2>
<?php$datetime = new \DateTime();
$year_month = $datetime->format("Y-m")."-01";
$args['year_month'] = $year_month;
?>
<p>Showing analytics for<?=$year_month?> (we store all visits as being on the first day of the month)</p>
<table border="1" style="border-collapse:collapse;">
<thead>
<th>Url</th>
<th>Hits</th>
</thead>
<tbody>
<?php/** template originally developed on jan 20, 2022
* @param \Phad $phad an object that handles the callback methods in the template. Can be any type, if you wish to change it from `\Phad`
*/## becomes $BlogInfo$tlf_analyticsInfo = (object)[
'name'=> 'tlf_analytics', //becomes Blog'mode'=>$phad_block,
'apis'=> array (
0 => 'view',
1 => 'data',
), //rawdata generally json. could be sql or csv though'type'=>'view', //just view or form at this point'args'=>$args,
'data_index'=>false,
'data_nodes' => array (
0 =>
array (
'sql' => 'SELECT url, COUNT(*) as hits FROM tlf_analytics WHERE `year_month` LIKE :year_month GROUP BY url ORDER BY hits DESC LIMIT 300',
'type' => 'node',
),
1 =>
array (
'type' => 'default',
),
), // each contains access="role:admin" & sql="Select * ...", etc'response_code' => false, // could start as 500?'rows'=>[], // could start null/false?'errors'=>[], // just gets appended to by whatever when there's a problem'submit_errors'=>[],
];
$phad->item_initialized($tlf_analyticsInfo);
if ($phad_block==\Phad\Blocks::ITEM_META){
return$tlf_analyticsInfo;
}
foreach ($tlf_analyticsInfo->data_nodes as$_index=>&$_node){
$_node['index'] = $_index;
if (isset($_node['if'])){
//@todo templatize p-data 'if' attribute instead of using `eval()`$eval_code = 'return ('.$_node['if'].');';
$result = eval($eval_code);
if (!$result){
$_node['response_code'] = 403;
$tlf_analyticsInfo->response_code = 403;
continue;
}
}
if (!$phad->can_read_data($_node, $tlf_analyticsInfo)){
$tlf_analyticsInfo->response_code = 403;
$_node['response_code'] = 403;
continue;
}
// may include getting $args['Blog'] or $args['BlogList'] instead of using a query$tlf_analyticsInfo->rows = $phad->read_data($_node, $tlf_analyticsInfo);
if (count($tlf_analyticsInfo->rows)==0){
$tlf_analyticsInfo->response_code = 404;
$_node['response_code'] = 404;
continue;
}
$tlf_analyticsInfo->response_code = 200;
$_node['response_code'] = 200;
$tlf_analyticsInfo->data_index = $_index;
break;
}
if ($phad_block == \Phad\Blocks::ITEM_DATA){
// does not handle nested items. I'm okay with that, for now ... i can always make separate item viewsreturn$phad->get_rows($tlf_analyticsInfo);
}
foreach ($tlf_analyticsInfo->rows as$RowIndex_tlf_analytics => $tlf_analyticsRow ):
$tlf_analytics = $phad->object_from_row($tlf_analyticsRow, $tlf_analyticsInfo);
?><tr>
<td><?=$tlf_analytics->url?></td>
<td><?=$tlf_analytics->hits?></td>
</tr><?phpendforeach;
?>
</tbody>
</table>
<h2>Privacy</h2>
<p>As of Apr 7, 2022, we no longer store any IP address or hash of IP address. We only record the page visited & the year+month it was visited. There is no personal info stored.</p>