Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
f46165e
Delete build.xml
DBinaghi Feb 16, 2026
8bb0d16
Refactor BrowseController methods and formatting
DBinaghi Feb 16, 2026
5dc23f3
Refactor summary view for improved readability
DBinaghi Feb 16, 2026
eab0033
Refactor PHP code for better readability
DBinaghi Feb 16, 2026
66d0dc7
Refactor stats configuration form layout and options
DBinaghi Feb 17, 2026
5ed15a4
Fix typo in template.pot regarding hits display
DBinaghi Feb 17, 2026
1da2dc4
Fix typo in French translation for stats display
DBinaghi Feb 17, 2026
c0508ea
Add files via upload
DBinaghi Feb 17, 2026
2accdba
Fix HTML fieldset tags and legend formatting
DBinaghi Feb 17, 2026
c8deb4e
Refactor PHP code for stats configuration form
DBinaghi Feb 17, 2026
b2946c0
Refactor stats-config-form.php table structure
DBinaghi Feb 17, 2026
9998a41
Refactor stats-config-form.php for clarity and structure
DBinaghi Feb 17, 2026
1d38188
Moved link from upper to side bar
DBinaghi Feb 20, 2026
e9e2dac
Refactor stats summary page layout and structure
DBinaghi Feb 20, 2026
c04da52
Enhance stats-config-form with explanations and cleanup
DBinaghi Feb 20, 2026
c2b0437
Refactor form and table structure in by-collection.php
DBinaghi Feb 20, 2026
df455ed
Refactor PHP code for better readability
DBinaghi Feb 20, 2026
5c20eea
Refactor PHP code for better readability
DBinaghi Feb 20, 2026
77ff010
Added function for end hit, added check for sorting ex-aequo
DBinaghi Feb 23, 2026
900369c
Added options
DBinaghi Feb 23, 2026
a468599
Added charts code
DBinaghi Feb 23, 2026
f862563
Create charts.php
DBinaghi Feb 23, 2026
a21e106
Update stats-nav.php
DBinaghi Feb 23, 2026
dab3d10
Delete views/admin/summary/charts.php
DBinaghi Feb 23, 2026
b4bc759
Create graphs.php
DBinaghi Feb 23, 2026
fbfb323
Update README.md
DBinaghi Feb 24, 2026
05e8298
Changed graphs for charts
DBinaghi Feb 24, 2026
ee686a6
Replaces spaces with tabs
DBinaghi Feb 24, 2026
011ea54
Swapped graphs for charts
DBinaghi Feb 24, 2026
bf1387e
Fixed null parameter issue
DBinaghi Feb 24, 2026
a1206a8
Fixed null parameter issue
DBinaghi Feb 24, 2026
a444332
Update by-collection.php
DBinaghi Feb 24, 2026
996d997
Added option check for pagination and quick filter
DBinaghi Feb 24, 2026
8a1b289
Added option check for pagination and quick filter
DBinaghi Feb 24, 2026
678b46c
Added css style for checkboxes
DBinaghi Feb 24, 2026
fce672a
Delete views/admin/summary/graphs.php
DBinaghi Feb 24, 2026
3e8e536
Create charts.php
DBinaghi Feb 24, 2026
f0968c5
Update index.php
DBinaghi Feb 24, 2026
2e798e1
Update Stats.php
DBinaghi Feb 24, 2026
784bd64
Update stats.css
DBinaghi Feb 24, 2026
a1e5e8c
Create chart.umd.js
DBinaghi Feb 24, 2026
fb44787
Add files via upload
DBinaghi Feb 24, 2026
3a3046c
Add files via upload
DBinaghi Feb 24, 2026
e712b08
Sorted languages by value DESC
DBinaghi Feb 25, 2026
eda4597
Removes from chart every language after the first 24
DBinaghi Feb 25, 2026
04a185f
Added parsing, cleaned up some functions
DBinaghi Mar 18, 2026
d978004
Update README.md
DBinaghi Mar 18, 2026
056918c
Fixed byCollection code
DBinaghi Mar 18, 2026
34336b0
Added browser and language parsing functions
DBinaghi Mar 18, 2026
6748484
Add files via upload
DBinaghi Mar 18, 2026
d45b90e
Add files via upload
DBinaghi Mar 18, 2026
b0e03c6
Create stats-ua-tracker.js
DBinaghi Mar 18, 2026
5fb458f
Add files via upload
DBinaghi Mar 18, 2026
06dba5f
Add files via upload
DBinaghi Mar 18, 2026
81c613f
Added parser options
DBinaghi Mar 18, 2026
0ab351c
Modified charts loading logic
DBinaghi Mar 18, 2026
70ac5b7
Refactored code, added extra checks
DBinaghi Mar 18, 2026
b231cc5
Refactored code, added extra checks
DBinaghi Mar 18, 2026
582b57c
Added browser and language parsing functions
DBinaghi Mar 18, 2026
2c2b665
Changed for lists to select box (standard for quick-filter)
DBinaghi Mar 18, 2026
1ba19ab
Add files via upload
DBinaghi Mar 18, 2026
cc3c93e
Update plugin.ini
DBinaghi Mar 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 114 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ plugins to get stats for a specific record type);
- informative (query, referrer, user agent and language are saved; all stats can
be browsed by public);
- count of direct download of files;
- full control of pruducted data;
- respect of privacy (if wanted!).
- full control of produced data;
- respect of privacy (if wanted!);
- user agent parsing (browser, OS, device type) via [ua-parser-js], with a
server-side cache so each unique user agent string is parsed only once;
- aggregated language statistics from `Accept-Language` headers, with ISO 639-1
language names;
- charts tab with hit trends and pie charts for browsers and accepted languages.

On the other hand, some advanced features are not implemented, especially
a detailled board with advanced filters. Nevertheless, logs and data can be
a detailed board with advanced filters. Nevertheless, logs and data can be
exported via mysql to a spreadsheet like [LibreOffice] or another specialized
statistic tool, where any stats can be calculated.

Expand All @@ -32,7 +37,7 @@ Uncompress files and rename plugin folder "Stats".

Then install it like any other Omeka plugin and follow the config instructions.

To count direct download of files, you need to add a line in the beginning off
To count direct download of files, you need to add a line in the beginning of
`.htaccess`:

```
Expand All @@ -49,18 +54,57 @@ automatically added.
You can count fullsize files too, but this is not recommended, because in the
majority of themes, hits may increase even when a simple page is opened.

### User Agent Parser

The plugin can optionally parse raw user-agent strings into structured data
(browser name and version, rendering engine, operating system, device type and
vendor) using the [ua-parser-js] library.

Parsing is performed **client-side** by the visitor's own browser, so it adds
no server-side CPU overhead. Results are sent to the server and cached in a
dedicated database table (`omeka_stats_user_agents`); each unique user-agent
string is therefore parsed only once regardless of how many times it appears in
the hit log.

The plugin ships with a bundled copy of `ua-parser.min.js` inside
`libraries/ua-parser/`. Because the library is updated frequently, you can
point the plugin to a more recent copy hosted on a CDN (e.g. [jsDelivr]) or on
your own server via the configuration page — without having to update the
plugin itself.

To download or update the bundled fallback manually, grab `ua-parser.min.js`
from the [ua-parser-js releases] page and place it in
`plugins/Stats/libraries/ua-parser/`.


Browse Stats
------------

A summary of stats is displayed at `/stats/summary`.
A summary of stats is displayed at `/stats/summary`. It has two tabs:

**Summary** — shows total and period hit counts, plus top-10 lists for most
viewed pages, records, downloads, referrers, queries, browsers and languages.

- The **browsers** panel resolves each raw user-agent string against the cache
table and displays browser name, OS and a `(bot)` flag where applicable.
User-agents not yet in cache are shown as raw strings and parsed on-the-fly
in the browser via ua-parser-js; the result is stored for future visits.
- The **accepted languages** panel aggregates `Accept-Language` headers by
first preferred language, resolving ISO 639-1 codes to their English name
with the code in parentheses (e.g. `Italian (it)`).

**Charts** — displays bar charts of hit trends (last 30 days, last 12 months,
per year) and pie charts for the top 20 browsers and top 24 accepted languages.
The browser chart reserves black for the "not identified" slice (user-agents
not yet resolved) and uses Chart.js default colours for all others.

Lists of stats by page, by record or by field are available too. They can be
ordered and filtered by anonymous / identified users, record types, etc.

These pages can be made available to authorized users only or to all public.

For plugins makers, panels can be added via the hook `stats_summary`.
For plugins makers, panels can be added via the hooks `stats_summary` and
`stats_summary_charts`.


Displaying some stats in the theme
Expand Down Expand Up @@ -140,6 +184,59 @@ The hook and the helper return the partial from the theme.
`stats_vieweds` returns an html string that can be themed.


User Agent Parser
-----------------

When enabled, the plugin resolves each raw user-agent string stored in the hit
log to its structured components and caches the result in the
`omeka_stats_user_agents` table. The parsed fields are:

| Field | Example value |
|------------------|------------------------|
| `browser` | Chrome |
| `browser_version`| 120.0.0 |
| `engine` | Blink |
| `engine_version` | 120.0.0 |
| `os` | Windows |
| `os_version` | 10 |
| `device_type` | desktop / mobile / ... |
| `device_vendor` | Apple |
| `device_model` | iPhone |
| `is_bot` | 0 / 1 |

### Configuration options

Two options are available on the plugin configuration page under
**User Agent Parser**:

- **Parse on visit** — when checked, the visitor's browser automatically parses
its own user-agent on every public page view and sends the result to the
server. The server stores it only if that user-agent has not been seen before.
- **ua-parser-js URL** — URL of the `ua-parser.min.js` script to load on public
pages. Leave empty to use the bundled copy shipped with the plugin. Pointing
this to a CDN (e.g. `https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js`)
allows the library to be updated independently of the plugin.

### Batch parsing of existing hits

The configuration page also shows how many distinct user-agent strings in the
hit log have not yet been parsed, and provides a **Parse now** button. Clicking
it starts a fully client-side batch process: the browser downloads the list of
unparsed strings, parses them in chunks of 20 with ua-parser-js, and sends each
chunk to the server. A progress bar tracks the operation.

### Using parsed data in custom views or controllers

```php
$db = get_db();
$uaTable = $db->prefix . 'stats_user_agents';

// Aggregate statistics via SummaryController helpers (within the controller):
$browsers = $this->_getBrowserStats(); // top 20 browsers
$languages = $this->_aggregateLanguages($rows, 10); // top 10 languages
```


Notes
-----

Expand All @@ -148,14 +245,21 @@ Notes
- Reload of a page generates a new hit (no check).
- IP can be hashed or not saved for privacy purpose.
- Currently, screen size is not detected.
- User-agent parsing is performed client-side and cached server-side; the cache
is keyed on `MD5(user_agent)` so lookups are O(1) regardless of log size.
- The UA cache table is created automatically on first page load after the
plugin files are updated, even without a formal reinstall.
- Accept-Language headers are aggregated by first preferred language only;
the ISO 639-1 code is resolved to its English name with the code in
parentheses (e.g. `Italian (it)`); unknown codes are shown as-is.


Warning
-------

Use it at your own risk.

Its always recommended to backup your files and your databases and to check
It's always recommended to backup your files and your databases and to check
your archives regularly so you can roll back if needed.


Expand Down Expand Up @@ -216,3 +320,6 @@ Copyright
[FSF]: https://www.fsf.org
[OSI]: http://opensource.org
[Daniel-KM]: https://github.com/Daniel-KM "Daniel Berthereau"
[ua-parser-js]: https://github.com/faisalman/ua-parser-js
[ua-parser-js releases]: https://github.com/faisalman/ua-parser-js/releases
[jsDelivr]: https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js
Loading