@Frenzie, simplified version of detection algorithm I've done for punBB (should be fairly easy to port to any script):
function user_agent_detect($string, $rules)
{
foreach ($rules as $key => $value)
{
$version = 0;
if (isset($value['rules']))
{
if (strstr($key, '.'))
{
$version = explode('.', $key);
$key = $version[0];
}
for ($i = 0, $c = count($value['rules']); $i < $c; ++$i)
{
if (($version && preg_match('#'.$value['rules'][$i].'#i', $string)) || preg_match('#'.$value['rules'][$i].'#i', $string, $version))
{
return array($key.(isset($version[1]) ? ' '.$version[1] : ''), (isset($value['icon']) ? $value['icon'] : $key));
}
}
}
else if (stristr($string, $key))
{
return array($key, (isset($value['icon']) ? $value['icon'] : $key));
}
}
return NULL;
}
if (!empty($cur_post['user_agent']))
{
$browser = user_agent_detect($cur_post['user_agent'], parse_ini_file($ext_info['path'].'/rules/browsers.ini', TRUE));
$operating_system = user_agent_detect($cur_post['user_agent'], parse_ini_file($ext_info['path'].'/rules/operating-systems.ini', TRUE));
if ($browser || $operating_system)
{
$browser_img = ($browser ? '<img src="'.$base_url.'/extensions/user_agent/icons/browsers/'.strtolower($browser[1]).'.png'.'" alt="" title="'.htmlspecialchars($browser[0]).'" />' : '');
$operating_system_img = ($operating_system ? '<img src="'.$base_url.'/extensions/user_agent/icons/operatingsystems/'.strtolower($operating_system[1]).'.png'.'" alt="" title="'.htmlspecialchars($operating_system[0]).'" />' : '');
$forum_page['post_actions']['user_agent'] = '<span class="edit-post user-agent-post" title="'.htmlspecialchars($cur_post['user_agent']).'" onclick="alert(\''.htmlspecialchars($cur_post['user_agent']).'\n'.($browser ? '\n'.htmlspecialchars($browser[0]) : '').($operating_system ? htmlspecialchars('\n'.$operating_system[0]) : '').'\')">'.$browser_img.$operating_system_img.'</span>';
}
}
It requires these definitions:
https://github.com/Emdek/eStats/blob/master/src/share/data/browsers.ini
https://github.com/Emdek/eStats/blob/master/src/share/data/operating-systems.ini
And uses these icons:
https://github.com/Emdek/eStats/tree/master/src/share/icons
Personally I would suggest to store results in additional columns (or single one, as serialized array), no need to run it each time.
It could be also modified to check if they are not empty, so when rules are updated then these columns could be emptied and script would refill them when needed.