xref: /plugin/combo/action/analytics.php (revision d81822ad92f09f1615648cf7e974436cf32e2c2c)
1c25e802bSgerardnico<?php
2c25e802bSgerardnico
32c067407Sgerardnicouse ComboStrap\Analytics;
4db974367Sgerardnicouse Combostrap\AnalyticsMenuItem;
5db974367Sgerardnicouse ComboStrap\Auth;
655d4462bSgerardnicouse ComboStrap\LogUtility;
7c25e802bSgerardnicouse ComboStrap\Page;
855d4462bSgerardnicouse ComboStrap\Sqlite;
9c25e802bSgerardnico
10c25e802bSgerardnico/**
11c25e802bSgerardnico * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved.
12c25e802bSgerardnico *
13c25e802bSgerardnico * This source code is licensed under the GPL license found in the
14c25e802bSgerardnico * COPYING  file in the root directory of this source tree.
15c25e802bSgerardnico *
16c25e802bSgerardnico * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
17c25e802bSgerardnico * @author   ComboStrap <support@combostrap.com>
18c25e802bSgerardnico *
19c25e802bSgerardnico */
20c25e802bSgerardnico
212c067407Sgerardnicorequire_once(__DIR__ . '/../class/' . 'Analytics.php');
22db974367Sgerardnicorequire_once(__DIR__ . '/../class/' . 'Auth.php');
23db974367Sgerardnicorequire_once(__DIR__ . '/../class/' . 'AnalyticsMenuItem.php');
242c067407Sgerardnico
25c25e802bSgerardnico/**
26c25e802bSgerardnico * Class action_plugin_combo_analytics
27c25e802bSgerardnico * Update the analytics data
28c25e802bSgerardnico */
29c25e802bSgerardnicoclass action_plugin_combo_analytics extends DokuWiki_Action_Plugin
30c25e802bSgerardnico{
31c25e802bSgerardnico
32c25e802bSgerardnico
33c25e802bSgerardnico    public function register(Doku_Event_Handler $controller)
34c25e802bSgerardnico    {
352c067407Sgerardnico
36c25e802bSgerardnico        /**
37c42a1196Sgerardnico         * Analytics to refresh because they have lost or gain a backlinks
38c42a1196Sgerardnico         * are done via Sqlite table (The INDEXER_TASKS_RUN gives a way to
39c42a1196Sgerardnico         * manipulate this queue)
40266b617eSgerardnico         *
41266b617eSgerardnico         * There is no need to do it at page write
42266b617eSgerardnico         * https://www.dokuwiki.org/devel:event:io_wikipage_write
43266b617eSgerardnico         * because after the page is written, the page is shown and trigger the index tasks run
44d262537cSgerardnico         *
45d262537cSgerardnico         * We do it after because if there is an error
46d262537cSgerardnico         * We will not stop the Dokuwiki Processing
47c42a1196Sgerardnico         */
48d262537cSgerardnico        $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'handle_refresh_analytics', array());
4955d4462bSgerardnico
50db974367Sgerardnico        /**
51db974367Sgerardnico         * Add a icon in the page tools menu
52db974367Sgerardnico         * https://www.dokuwiki.org/devel:event:menu_items_assembly
53db974367Sgerardnico         */
54db974367Sgerardnico        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handle_page_tools');
55db974367Sgerardnico
56c25e802bSgerardnico    }
57c25e802bSgerardnico
5855d4462bSgerardnico    public function handle_refresh_analytics(Doku_Event $event, $param)
5955d4462bSgerardnico    {
6055d4462bSgerardnico
61c42a1196Sgerardnico        /**
62c42a1196Sgerardnico         * Check that the actual page has analytics data
63c42a1196Sgerardnico         * (if there is a cache, it's pretty quick)
64c42a1196Sgerardnico         */
65c42a1196Sgerardnico        global $ID;
66*d81822adSgerardnico        $page = new Page($ID);
67*d81822adSgerardnico        if ($page->shouldAnalyticsProcessOccurs()) {
687c33ecc6Sgerardnico            $page->processAnalytics();
6955d4462bSgerardnico        }
7055d4462bSgerardnico
71*d81822adSgerardnico        /**
72*d81822adSgerardnico         * Process the analytics to refresh
73*d81822adSgerardnico         */
74*d81822adSgerardnico        $this->analyticsBatchBackgroundRefresh();
75*d81822adSgerardnico
7655d4462bSgerardnico    }
77db974367Sgerardnico
78*d81822adSgerardnico    public function handle_page_tools(Doku_Event $event, $param)
79*d81822adSgerardnico    {
80db974367Sgerardnico
81d262537cSgerardnico        if (!Auth::isWriter()) {
82db974367Sgerardnico            return;
83db974367Sgerardnico        }
84db974367Sgerardnico
85db974367Sgerardnico        /**
86db974367Sgerardnico         * The `view` property defines the menu that is currently built
87db974367Sgerardnico         * https://www.dokuwiki.org/devel:menus
88db974367Sgerardnico         * If this is not the page menu, return
89db974367Sgerardnico         */
90db974367Sgerardnico        if ($event->data['view'] != 'page') return;
91db974367Sgerardnico
92db974367Sgerardnico        global $INFO;
93db974367Sgerardnico        if (!$INFO['exists']) {
94db974367Sgerardnico            return;
95db974367Sgerardnico        }
96db974367Sgerardnico        array_splice($event->data['items'], -1, 0, array(new AnalyticsMenuItem()));
97db974367Sgerardnico
98db974367Sgerardnico    }
99*d81822adSgerardnico
100*d81822adSgerardnico    private function analyticsBatchBackgroundRefresh()
101*d81822adSgerardnico    {
102*d81822adSgerardnico        $sqlite = Sqlite::getSqlite();
103*d81822adSgerardnico        $res = $sqlite->query("SELECT ID FROM ANALYTICS_TO_REFRESH");
104*d81822adSgerardnico        if (!$res) {
105*d81822adSgerardnico            LogUtility::msg("There was a problem during the select: {$sqlite->getAdapter()->getDb()->errorInfo()}");
106*d81822adSgerardnico        }
107*d81822adSgerardnico        $rows = $sqlite->res2arr($res, true);
108*d81822adSgerardnico        $sqlite->res_close($res);
109*d81822adSgerardnico
110*d81822adSgerardnico        /**
111*d81822adSgerardnico         * In case of a start or if there is a recursive bug
112*d81822adSgerardnico         * We don't want to take all the resources
113*d81822adSgerardnico         */
114*d81822adSgerardnico        $maxRefresh = 5;
115*d81822adSgerardnico        $maxRefreshLow = 2;
116*d81822adSgerardnico        if (sizeof($rows) > $maxRefresh) {
117*d81822adSgerardnico            LogUtility::msg("There is more than {$maxRefresh} page to refresh in the queue (table `ANALYTICS_TO_REFRESH`). Batch background Analytics refresh was reduced to {$maxRefreshLow} page to not hit the computer resources.", LogUtility::LVL_MSG_ERROR, "analytics");
118*d81822adSgerardnico            $maxRefresh = $maxRefreshLow;
119*d81822adSgerardnico        }
120*d81822adSgerardnico        $refreshCounter = 0;
121*d81822adSgerardnico        foreach ($rows as $row) {
122*d81822adSgerardnico            $page = new Page($row['ID']);
123*d81822adSgerardnico            $page->processAnalytics();
124*d81822adSgerardnico            $refreshCounter++;
125*d81822adSgerardnico            if ($refreshCounter>=$maxRefresh){
126*d81822adSgerardnico                break;
127*d81822adSgerardnico            }
128*d81822adSgerardnico        }
129*d81822adSgerardnico
130*d81822adSgerardnico    }
131c25e802bSgerardnico}
132c25e802bSgerardnico
133c25e802bSgerardnico
134c25e802bSgerardnico
135