1*007225e5Sgerardnico<?php 2*007225e5Sgerardnico/** 3*007225e5Sgerardnico * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4*007225e5Sgerardnico * 5*007225e5Sgerardnico * This source code is licensed under the GPL license found in the 6*007225e5Sgerardnico * COPYING file in the root directory of this source tree. 7*007225e5Sgerardnico * 8*007225e5Sgerardnico * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9*007225e5Sgerardnico * @author ComboStrap <support@combostrap.com> 10*007225e5Sgerardnico * 11*007225e5Sgerardnico */ 12*007225e5Sgerardnicoif (!defined('DOKU_INC')) die(); 13*007225e5Sgerardnico 14*007225e5Sgerardnicouse ComboStrap\Analytics; 15*007225e5Sgerardnicouse splitbrain\phpcli\Options; 16*007225e5Sgerardnico 17*007225e5Sgerardnicorequire_once(__DIR__ . '/class/Analytics.php'); 18*007225e5Sgerardnico 19*007225e5Sgerardnico/** 20*007225e5Sgerardnico * The memory of the server 128 is not enough 21*007225e5Sgerardnico */ 22*007225e5Sgerardnicoini_set('memory_limit', '256M'); 23*007225e5Sgerardnico 24*007225e5Sgerardnico/** 25*007225e5Sgerardnico * Class cli_plugin_combo 26*007225e5Sgerardnico * 27*007225e5Sgerardnico * This is a cli: 28*007225e5Sgerardnico * https://www.dokuwiki.org/devel:cli_plugins#example 29*007225e5Sgerardnico * 30*007225e5Sgerardnico * Usage: 31*007225e5Sgerardnico * 32*007225e5Sgerardnico * ``` 33*007225e5Sgerardnico * docker exec -ti $(CONTAINER) /bin/bash 34*007225e5Sgerardnico * ./bin/plugin.php combo -c 35*007225e5Sgerardnico * ``` 36*007225e5Sgerardnico * or via the IDE 37*007225e5Sgerardnico * 38*007225e5Sgerardnico * 39*007225e5Sgerardnico * Example: 40*007225e5Sgerardnico * https://www.dokuwiki.org/tips:grapher 41*007225e5Sgerardnico * 42*007225e5Sgerardnico */ 43*007225e5Sgerardnicoclass cli_plugin_combo extends DokuWiki_CLI_Plugin 44*007225e5Sgerardnico{ 45*007225e5Sgerardnico 46*007225e5Sgerardnico /** 47*007225e5Sgerardnico * register options and arguments 48*007225e5Sgerardnico * @param Options $options 49*007225e5Sgerardnico */ 50*007225e5Sgerardnico protected function setup(Options $options) 51*007225e5Sgerardnico { 52*007225e5Sgerardnico $options->setHelp('Run the analytics process'); 53*007225e5Sgerardnico $options->registerOption('version', 'print version', 'v'); 54*007225e5Sgerardnico $options->registerArgument( 55*007225e5Sgerardnico 'namespaces', 56*007225e5Sgerardnico "If no namespace is given, the root namespace is assumed.", 57*007225e5Sgerardnico false); 58*007225e5Sgerardnico $options->registerOption( 59*007225e5Sgerardnico 'output', 60*007225e5Sgerardnico "Optional, where to store the analytical data as csv eg. a filename.", 61*007225e5Sgerardnico 'o', 'file'); 62*007225e5Sgerardnico $options->registerOption( 63*007225e5Sgerardnico 'cache', 64*007225e5Sgerardnico "Optional, returns from the cache if set", 65*007225e5Sgerardnico 'c', false); 66*007225e5Sgerardnico 67*007225e5Sgerardnico } 68*007225e5Sgerardnico 69*007225e5Sgerardnico /** 70*007225e5Sgerardnico * The main entry 71*007225e5Sgerardnico * @param Options $options 72*007225e5Sgerardnico */ 73*007225e5Sgerardnico protected function main(Options $options) 74*007225e5Sgerardnico { 75*007225e5Sgerardnico 76*007225e5Sgerardnico $namespaces = array_map('cleanID', $options->getArgs()); 77*007225e5Sgerardnico if (!count($namespaces)) $namespaces = array(''); //import from top 78*007225e5Sgerardnico 79*007225e5Sgerardnico $output = $options->getOpt('output', ''); 80*007225e5Sgerardnico //if ($output == '-') $output = 'php://stdout'; 81*007225e5Sgerardnico $cache = $options->getOpt('cache', false); 82*007225e5Sgerardnico 83*007225e5Sgerardnico 84*007225e5Sgerardnico $this->process($namespaces, $output, $cache); 85*007225e5Sgerardnico 86*007225e5Sgerardnico 87*007225e5Sgerardnico } 88*007225e5Sgerardnico 89*007225e5Sgerardnico /** 90*007225e5Sgerardnico * @param $namespaces 91*007225e5Sgerardnico * @param $output 92*007225e5Sgerardnico * @param bool $cache 93*007225e5Sgerardnico * @param int $depth recursion depth. 0 for unlimited 94*007225e5Sgerardnico */ 95*007225e5Sgerardnico private function process($namespaces, $output, $cache = false, $depth = 0) 96*007225e5Sgerardnico { 97*007225e5Sgerardnico global $conf; 98*007225e5Sgerardnico 99*007225e5Sgerardnico $fileHandle = null; 100*007225e5Sgerardnico if (!empty($output)) { 101*007225e5Sgerardnico $fileHandle = @fopen($output, 'w'); 102*007225e5Sgerardnico if (!$fileHandle) $this->fatal("Failed to open $output"); 103*007225e5Sgerardnico } 104*007225e5Sgerardnico 105*007225e5Sgerardnico // find pages 106*007225e5Sgerardnico $pages = array(); 107*007225e5Sgerardnico foreach ($namespaces as $ns) { 108*007225e5Sgerardnico 109*007225e5Sgerardnico search( 110*007225e5Sgerardnico $pages, 111*007225e5Sgerardnico $conf['datadir'], 112*007225e5Sgerardnico 'search_universal', 113*007225e5Sgerardnico array( 114*007225e5Sgerardnico 'depth' => $depth, 115*007225e5Sgerardnico 'listfiles' => true, 116*007225e5Sgerardnico 'listdirs' => false, 117*007225e5Sgerardnico 'pagesonly' => true, 118*007225e5Sgerardnico 'skipacl' => true, 119*007225e5Sgerardnico 'firsthead' => false, 120*007225e5Sgerardnico 'meta' => false, 121*007225e5Sgerardnico ), 122*007225e5Sgerardnico str_replace(':', '/', $ns) 123*007225e5Sgerardnico ); 124*007225e5Sgerardnico 125*007225e5Sgerardnico // add the ns start page 126*007225e5Sgerardnico if ($ns && page_exists($ns)) { 127*007225e5Sgerardnico $pages[] = array( 128*007225e5Sgerardnico 'id' => $ns, 129*007225e5Sgerardnico 'ns' => getNS($ns), 130*007225e5Sgerardnico 'title' => p_get_first_heading($ns, false), 131*007225e5Sgerardnico 'size' => filesize(wikiFN($ns)), 132*007225e5Sgerardnico 'mtime' => filemtime(wikiFN($ns)), 133*007225e5Sgerardnico 'perm' => 16, 134*007225e5Sgerardnico 'type' => 'f', 135*007225e5Sgerardnico 'level' => 0, 136*007225e5Sgerardnico 'open' => 1, 137*007225e5Sgerardnico ); 138*007225e5Sgerardnico } 139*007225e5Sgerardnico 140*007225e5Sgerardnico } 141*007225e5Sgerardnico 142*007225e5Sgerardnico 143*007225e5Sgerardnico if (!empty($fileHandle)) { 144*007225e5Sgerardnico $header = array( 145*007225e5Sgerardnico 'id', 146*007225e5Sgerardnico 'backlinks', 147*007225e5Sgerardnico 'broken_links', 148*007225e5Sgerardnico 'changes', 149*007225e5Sgerardnico 'chars', 150*007225e5Sgerardnico 'external_links', 151*007225e5Sgerardnico 'external_medias', 152*007225e5Sgerardnico 'h1', 153*007225e5Sgerardnico 'h2', 154*007225e5Sgerardnico 'h3', 155*007225e5Sgerardnico 'h4', 156*007225e5Sgerardnico 'h5', 157*007225e5Sgerardnico 'internal_links', 158*007225e5Sgerardnico 'internal_medias', 159*007225e5Sgerardnico 'words', 160*007225e5Sgerardnico 'score' 161*007225e5Sgerardnico ); 162*007225e5Sgerardnico fwrite($fileHandle, implode(",", $header) . PHP_EOL); 163*007225e5Sgerardnico } 164*007225e5Sgerardnico while ($page = array_shift($pages)) { 165*007225e5Sgerardnico $id = $page['id']; 166*007225e5Sgerardnico 167*007225e5Sgerardnico // Run as admin to overcome the fact that 168*007225e5Sgerardnico // anonymous user cannot set all links and backlinnks 169*007225e5Sgerardnico global $USERINFO; 170*007225e5Sgerardnico $USERINFO['grps'] = array('admin'); 171*007225e5Sgerardnico 172*007225e5Sgerardnico 173*007225e5Sgerardnico echo 'Processing the page ' . $id ."\n"; 174*007225e5Sgerardnico 175*007225e5Sgerardnico $data = Analytics::getDataAsArray($id, $cache); 176*007225e5Sgerardnico if (!empty($fileHandle)) { 177*007225e5Sgerardnico $statistics = $data[Analytics::STATISTICS]; 178*007225e5Sgerardnico $row = array( 179*007225e5Sgerardnico 'id' => $id, 180*007225e5Sgerardnico 'backlinks' => $statistics[Analytics::INTERNAL_BACKLINKS_COUNT], 181*007225e5Sgerardnico 'broken_links' => $statistics[Analytics::INTERNAL_LINKS_BROKEN_COUNT], 182*007225e5Sgerardnico 'changes' => $statistics[Analytics::EDITS_COUNT], 183*007225e5Sgerardnico 'chars' => $statistics[Analytics::CHARS_COUNT], 184*007225e5Sgerardnico 'external_links' => $statistics[Analytics::EXTERNAL_LINKS_COUNT], 185*007225e5Sgerardnico 'external_medias' => $statistics[Analytics::EXTERNAL_MEDIAS], 186*007225e5Sgerardnico 'h1' => $statistics[Analytics::HEADERS_COUNT]['h1'], 187*007225e5Sgerardnico 'h2' => $statistics[Analytics::HEADERS_COUNT]['h2'], 188*007225e5Sgerardnico 'h3' => $statistics[Analytics::HEADERS_COUNT]['h3'], 189*007225e5Sgerardnico 'h4' => $statistics[Analytics::HEADERS_COUNT]['h4'], 190*007225e5Sgerardnico 'h5' => $statistics[Analytics::HEADERS_COUNT]['h5'], 191*007225e5Sgerardnico 'internal_links' => $statistics[Analytics::INTERNAL_LINKS_COUNT], 192*007225e5Sgerardnico 'internal_medias' => $statistics[Analytics::INTERNAL_MEDIAS_COUNT], 193*007225e5Sgerardnico 'words' => $statistics[Analytics::WORDS_COUNT], 194*007225e5Sgerardnico 'low' => $data[Analytics::QUALITY]['low'] 195*007225e5Sgerardnico ); 196*007225e5Sgerardnico fwrite($fileHandle, implode(",", $row) . PHP_EOL); 197*007225e5Sgerardnico } 198*007225e5Sgerardnico } 199*007225e5Sgerardnico if (!empty($fileHandle)) { 200*007225e5Sgerardnico fclose($fileHandle); 201*007225e5Sgerardnico } 202*007225e5Sgerardnico 203*007225e5Sgerardnico } 204*007225e5Sgerardnico} 205