1616
1717namespace tool_cloudmetrics \metric ;
1818
19+ use progress_bar ;
20+ use tool_cloudmetrics \lib ;
21+
1922/**
2023 * Metric class for 12 months yearly active users.
2124 *
2629 */
2730class yearly_active_users_metric extends builtin_user_base {
2831
32+
33+ /** @var int The interval config for which data is displayed in seconds (eg: 5 minutes = 300). */
34+ public $ interval ;
35+
36+ /** @var int The minimal timestamp representing earliest date retrieved in DB. */
37+ public $ mintimestamp ;
38+
39+ /** @var int The maximal timestamp representing latest date retrieved in DB. */
40+ public $ maxtimestamp ;
41+
42+ /** @var bool True if config used is same as one requested. */
43+ public $ sameconfig ;
44+
2945 /**
3046 * The metric's name.
3147 *
@@ -72,6 +88,15 @@ public function set_frequency(int $freq) {
7288 // Do nothing.
7389 }
7490
91+ /**
92+ * Metric's ability to be backfilled.
93+ *
94+ * @return bool
95+ */
96+ public function is_backfillable (): bool {
97+ return true ;
98+ }
99+
75100 /**
76101 * Generates the metric items from the source data.
77102 *
@@ -91,4 +116,91 @@ public function generate_metric_item(int $starttime, int $finishtime): metric_it
91116 );
92117 return new metric_item ($ this ->get_name (), $ finishtime , $ users , $ this );
93118 }
119+
120+ /**
121+ * Returns records for backfilled metric.
122+ *
123+ * @param int $backwardperiod Time from which sample is to be retrieved.
124+ * @param int|null $finishtime If data is being completed argument is passed here.
125+ * @param progress_bar|null $progress
126+ *
127+ * @return array
128+ */
129+ public function generate_metric_items (int $ backwardperiod , ?int $ finishtime = null , ?progress_bar $ progress = null ): array {
130+ global $ DB ;
131+ $ metricitems = [];
132+ $ finishtime = ($ finishtime === -1 ) ? null : $ finishtime ;
133+ $ finishtime = $ finishtime ?? time ();
134+ $ starttime = $ finishtime - $ backwardperiod ;
135+ // Back to last year from start time.
136+ $ lastyear = $ starttime - YEARSECS ;
137+ // Get aggregation interval.
138+ $ frequency = $ this ->get_frequency ();
139+ $ interval = lib::FREQ_TIMES [$ frequency ];
140+ if ($ finishtime < $ starttime ) {
141+ return [];
142+ }
143+ $ sql = 'SELECT floor(timecreated / :interval ) * :intervaldup AS timestamp,
144+ userid
145+ FROM {logstore_standard_log}
146+ WHERE timecreated >= :lastyear
147+ AND timecreated <= :finishtime
148+ GROUP BY timestamp, userid
149+ ORDER BY timestamp DESC ' ;
150+ $ results = $ DB ->get_recordset_sql (
151+ $ sql ,
152+ ['interval ' => $ interval , 'intervaldup ' => $ interval , 'lastyear ' => $ lastyear , 'finishtime ' => $ finishtime ]
153+ );
154+ $ buffer = [];
155+
156+ foreach ($ results as $ record ) {
157+ $ buffer [] = $ record ;
158+ }
159+ $ results ->close ();
160+
161+ // Variables for updating progress.
162+ $ count = 0 ;
163+ $ total = ($ finishtime - $ starttime ) / $ interval ;
164+ // Build a metric for each day from starttime to finishtime.
165+ while ($ starttime <= $ finishtime ) {
166+ $ distinctusers = [];
167+ $ lastyear = $ starttime - YEARSECS ;
168+ foreach ($ buffer as $ r ) {
169+ // Count active users in a 12 months period.
170+ if ($ r ->timestamp >= $ lastyear &&
171+ $ r ->timestamp <= $ starttime &&
172+ !array_key_exists ($ r ->userid , $ distinctusers )) {
173+ $ distinctusers [$ r ->userid ] = true ;
174+ }
175+ }
176+ $ metricitems [] = new metric_item ($ this ->get_name (), $ starttime , count ($ distinctusers ), $ this );
177+ $ starttime = $ starttime + $ interval ;
178+ $ count ++;
179+ if ($ progress ) {
180+ $ progress ->update (
181+ $ count ,
182+ $ total ,
183+ get_string ('backfillgenerating ' , 'tool_cloudmetrics ' , $ this ->get_label ())
184+ );
185+ }
186+ }
187+ $ this ->mintimestamp = !empty ($ metricitems ) ? $ metricitems [0 ]->time : null ;
188+ $ this ->maxtimestamp = !empty ($ metricitems ) ? end ($ metricitems )->time : null ;
189+ $ this ->interval = $ frequency ;
190+ return $ metricitems ;
191+ }
192+
193+ /**
194+ * Stores what data has been sent to collector.
195+ *
196+ */
197+ public function set_data_sent_config (): void {
198+ // Store what data has been sent min, max timestamp range and interval.
199+ $ currentconfig = [$ this ->mintimestamp , $ this ->maxtimestamp , $ this ->interval ];
200+ $ rangeretrieved = $ this ->get_range_retrieved ();
201+ $ this ->sameconfig = ($ rangeretrieved === $ currentconfig );
202+ if (!$ this ->sameconfig && isset ($ this ->mintimestamp ) && isset ($ this ->maxtimestamp ) && isset ($ this ->interval )) {
203+ $ this ->set_range_retrieved ($ currentconfig );
204+ }
205+ }
94206}
0 commit comments