Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ All notable changes to this project will be documented in this file.
- Log mailer errors plausible/analytics#3336
- Allow custom event timeseries in stats API plausible/analytics#3505
- Fixes for sites with UTF characters in domain plausible/analytics#3560
- Fix crash when using special characters in filter plausible/analytics#3634

## v2.0.0 - 2023-07-12

Expand Down
17 changes: 8 additions & 9 deletions lib/plausible/stats/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -542,16 +542,15 @@ defmodule Plausible.Stats.Base do
{first_datetime, last_datetime}
end

@replaces %{
~r/\*\*/ => ".*",
~r/(?<!\.)\*/ => "[^/]*",
"(" => "\\(",
")" => "\\)"
}
def page_regex(expr) do
Enum.reduce(@replaces, "^#{expr}$", fn {pattern, replacement}, regex ->
String.replace(regex, pattern, replacement)
end)
escaped =
expr
|> Regex.escape()
|> String.replace("\\|", "|")
|> String.replace("\\*\\*", ".*")
|> String.replace("\\*", ".*")

"^#{escaped}$"
end

defp split_goals(clauses, map_fn \\ &Function.identity/1) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,23 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
}
end

test "wildcard referrer filter with special regex characters", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview, referrer: "https://a.com"),
build(:pageview, referrer: "https://a.com"),
build(:pageview, referrer: "https://ab.com")
])

conn =
get(conn, "/api/v1/stats/aggregate", %{
"site_id" => site.domain,
"metrics" => "visitors",
"filters" => "visit:referrer==**a.com**"
})

assert json_response(conn, 200)["results"] == %{"visitors" => %{"value" => 2}}
end

test "can filter by utm_medium", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,13 +625,10 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
insert(:goal, %{site: site, page_path: "/register"})
insert(:goal, %{site: site, page_path: "/reg*"})
insert(:goal, %{site: site, page_path: "/*/register"})
insert(:goal, %{site: site, page_path: "/billing**/success"})
insert(:goal, %{site: site, page_path: "/billing*/success"})
insert(:goal, %{site: site, page_path: "/signup"})
insert(:goal, %{site: site, page_path: "/signup/*"})
insert(:goal, %{site: site, page_path: "/signup/**"})
insert(:goal, %{site: site, page_path: "/*"})
insert(:goal, %{site: site, page_path: "/**"})

populate_stats(site, [
build(:pageview,
Expand Down Expand Up @@ -678,25 +675,19 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
%{
"conversion_rate" => 100.0,
"visitors" => 8,
"name" => "Visit /**",
"name" => "Visit /*",
"events" => 8
},
%{
"conversion_rate" => 37.5,
"visitors" => 3,
"name" => "Visit /signup/**",
"events" => 3
},
%{
"conversion_rate" => 37.5,
"visitors" => 3,
"name" => "Visit /*",
"name" => "Visit /signup/*",
"events" => 3
},
%{
"conversion_rate" => 25.0,
"visitors" => 2,
"name" => "Visit /billing**/success",
"name" => "Visit /billing*/success",
"events" => 2
},
%{
Expand All @@ -705,18 +696,6 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
"name" => "Visit /reg*",
"events" => 2
},
%{
"conversion_rate" => 12.5,
"visitors" => 1,
"name" => "Visit /signup/*",
"events" => 1
},
%{
"conversion_rate" => 12.5,
"visitors" => 1,
"name" => "Visit /billing*/success",
"events" => 1
},
%{
"conversion_rate" => 12.5,
"visitors" => 1,
Expand Down