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