4
4
5
5
use App \Wiki ;
6
6
use App \WikiDailyMetrics ;
7
+ use Illuminate \Support \Arr ;
7
8
8
9
class WikiMetrics
9
10
{
11
+ const INTERVAL_DAILY = 'INTERVAL 1 DAY ' ;
12
+ const INTERVAL_WEEKLY = ' INTERVAL 1 WEEK ' ;
13
+ const INTERVAL_MONTHLY = 'INTERVAL 1 MONTH ' ;
14
+ const INTERVAL_QUARTERLY = 'INTERVAL 3 MONTH ' ;
15
+
16
+ protected $ wiki ;
17
+
10
18
public function saveMetrics (Wiki $ wiki ): void
11
19
{
20
+ $ this ->wiki = $ wiki ;
21
+
12
22
$ today = now ()->format ('Y-m-d ' );
13
23
$ oldRecord = WikiDailyMetrics::where ('wiki_id ' , $ wiki ->id )->latest ('date ' )->first ();
14
24
$ todayPageCount = $ wiki ->wikiSiteStats ()->first ()->pages ?? 0 ;
15
25
$ isDeleted = (bool )$ wiki ->deleted_at ;
16
26
27
+ $ dailyActions = $ this ->getNumberOfActions (self ::INTERVAL_DAILY );
28
+ $ weeklyActions = $ this ->getNumberOfActions (self ::INTERVAL_WEEKLY );
29
+ $ monthlyActions = $ this ->getNumberOfActions (self ::INTERVAL_MONTHLY );
30
+ $ quarterlyActions = $ this ->getNumberOfActions (self ::INTERVAL_QUARTERLY );
31
+
17
32
$ dailyMetrics = new WikiDailyMetrics ([
18
33
'id ' => $ wiki ->id . '_ ' . date ('Y-m-d ' ),
19
34
'pages ' => $ todayPageCount ,
20
35
'is_deleted ' => $ isDeleted ,
21
36
'date ' => $ today ,
22
- 'wiki_id ' => $ wiki ->id
37
+ 'wiki_id ' => $ wiki ->id ,
38
+ 'daily_actions ' => $ dailyActions ,
39
+ 'weekly_actions ' => $ weeklyActions ,
40
+ 'monthly_actions ' => $ monthlyActions ,
41
+ 'quarterly_actions ' => $ quarterlyActions ,
23
42
]);
24
-
43
+
44
+ // compare current record to old record and only save if there is a change
25
45
if ($ oldRecord ) {
26
46
if ($ oldRecord ->is_deleted ) {
27
47
\Log::info ("Wiki is deleted, no new record for WikiMetrics ID {$ wiki ->id }. " );
28
48
return ;
29
49
}
30
-
31
50
if (!$ isDeleted ) {
32
51
if ($ oldRecord ->areMetricsEqual ($ dailyMetrics )) {
33
52
\Log::info ("Record unchanged for WikiMetrics ID {$ wiki ->id }, no new record added. " );
@@ -38,6 +57,48 @@ public function saveMetrics(Wiki $wiki): void
38
57
39
58
$ dailyMetrics ->save ();
40
59
41
- \Log::info ("New metric recorded for WikiMetrics ID {$ wiki ->id }" );
60
+ \Log::info ("New metric recorded for Wiki ID {$ wiki ->id }" );
61
+ }
62
+
63
+ protected function getNumberOfActions (string $ interval ): null |int
64
+ {
65
+ $ actions = null ;
66
+
67
+ // safeguard
68
+ if (false === in_array ($ interval ,
69
+ [
70
+ self ::INTERVAL_DAILY ,
71
+ self ::INTERVAL_WEEKLY ,
72
+ self ::INTERVAL_MONTHLY ,
73
+ self ::INTERVAL_QUARTERLY
74
+ ]
75
+ )) { return null ; }
76
+
77
+ $ wikiDb = $ this ->wiki ->wikiDb ;
78
+ $ tableRecentChanges = $ wikiDb ->name . '. ' . $ wikiDb ->prefix . '_recentchanges ' ;
79
+ $ tableActor = $ wikiDb ->name . '. ' . $ wikiDb ->prefix . '_actor ' ;
80
+
81
+ $ query = "SELECT
82
+ SUM(rc_timestamp >= DATE_FORMAT(DATE_SUB(NOW(), $ interval), '%Y%m%d%H%i%S')) AS sum_actions
83
+ FROM
84
+ $ tableRecentChanges AS rc
85
+ INNER JOIN $ tableActor AS a ON rc.rc_actor = a.actor_id
86
+ WHERE
87
+ /*
88
+ Conditions below added for consistency with Wikidata: https://phabricator.wikimedia.org/diffusion/ADES/browse/master/src/wikidata/site_stats/sql/active_user_changes.sql
89
+ */
90
+ a.actor_user != 0
91
+ AND rc.rc_bot = 0
92
+ AND ( rc.rc_log_type != 'newusers' OR rc.rc_log_type IS NULL) " ;
93
+
94
+ $ manager = app ()->db ;
95
+ $ manager ->purge ('mw ' );
96
+ $ conn = $ manager ->connection ('mw ' );
97
+ $ pdo = $ conn ->getPdo ();
98
+ $ result = $ pdo ->query ($ query )->fetch ();
99
+
100
+ $ actions = Arr::get ($ result , 'sum_actions ' , null );
101
+
102
+ return $ actions ;
42
103
}
43
104
}
0 commit comments