*/ class action_plugin_networkgraph_grapher extends ActionPlugin { /** @inheritDoc */ public function register(EventHandler $controller) { $controller->register_hook('INDEXER_PAGE_ADD', 'AFTER', $this, 'rebuildGraphData'); } /** * Event handler for INDEXER_TASKS_RUN * * @see https://www.dokuwiki.org/devel:events:INDEXER_TASKS_RUN * @param Event $event Event object * @param mixed $param optional parameter passed when event was registered * @return void */ public function rebuildGraphData(Event $event, $param) { global $conf; $namespaces = ['']; $depth = 0; $incmedia = 'ns'; $pages = []; $media = []; $nodes = []; $links = []; foreach($namespaces as $ns) { // find media if($incmedia == 'ns') { $data = []; search( $data, $conf['mediadir'], 'search_universal', [ 'depth' => $depth, 'listfiles' => true, 'listdirs' => false, 'pagesonly' => false, 'skipacl' => true, 'keeptxt' => true, 'meta' => true, ], str_replace(':', '/', $ns) ); // go through all those media files while($item = array_shift($data)) { $media[$item['id']] = [ 'title' => noNS($item['id']), 'size' => $item['size'], 'ns' => getNS($item['id']), 'time' => $item['mtime'], ]; } } // find pages $data = []; search( $data, $conf['datadir'], 'search_universal', [ 'depth' => $depth, 'listfiles' => true, 'listdirs' => false, 'pagesonly' => true, 'skipacl' => true, 'firsthead' => true, 'meta' => true, ], str_replace(':', '/', $ns) ); // ns start page if($ns && page_exists($ns)) { $data[] = [ 'id' => $ns, 'ns' => getNS($ns), 'title' => p_get_first_heading($ns, false), 'size' => filesize(wikiFN($ns)), 'mtime' => filemtime(wikiFN($ns)), 'perm' => 16, 'type' => 'f', 'level' => 0, 'open' => 1, ]; } // go through all those pages while($item = array_shift($data)) { $time = (int) p_get_metadata($item['id'], 'date created', false); if(!$time) $time = $item['mtime']; $pages[$item['id']] = [ 'title' => $item['title'], 'ns' => $item['ns'], 'size' => $item['size'], 'time' => $time, 'links' => [], 'media' => [], ]; } } // now get links and media foreach($pages as $pid => $item) { // get instructions $ins = p_cached_instructions(wikiFN($pid), false, $pid); // find links and media usage foreach($ins as $i) { $mid = null; if($i[0] == 'internallink') { $id = $i[1][0]; $exists = true; resolve_pageid($item['ns'], $id, $exists); list($id) = explode('#', $id, 2); if($id == $pid) continue; // skip self references if($exists && isset($pages[$id])) { $pages[$pid]['links'][] = $id; } if(is_array($i[1][1]) && $i[1][1]['type'] == 'internalmedia') { $mid = $i[1][1]['src']; // image link } else { continue; // we're done here } } if($i[0] == 'internalmedia') { $mid = $i[1][0]; } if(is_null($mid)) continue; if($incmedia == 'none') continue; // no media wanted $exists = true; resolve_mediaid($item['ns'], $mid, $exists); list($mid) = explode('#', $mid, 2); $mid = cleanID($mid); if($exists) { if($incmedia == 'all') { if(!isset($media[$mid])) { //add node $media[$mid] = [ 'size' => filesize(mediaFN($mid)), 'time' => filemtime(mediaFN($mid)), 'ns' => getNS($mid), 'title' => noNS($mid), ]; } $pages[$pid]['media'][] = $mid; } elseif(isset($media[$mid])) { $pages[$pid]['media'][] = $mid; } } } $backlinks = ft_backlinks($pid, true); foreach($backlinks as $backlink) { $pages[$backlink]['links'][] = $pid; } } // clean up duplicates then create nodes foreach($pages as $pid => $item) { $pages[$pid]['links'] = array_unique($pages[$pid]['links']); $pages[$pid]['media'] = array_unique($pages[$pid]['media']); //create nodes $nodes[] = [ 'id' => $pid, 'group' => 'page', 'label' => $pid."\n".$item['title'] ]; //create links foreach($pages[$pid]['links'] as $link) { $links[] = [ 'source' => $pid, 'target' => $link ]; } foreach($pages[$pid]['media'] as $mediaLink) { $links[] = [ 'source' => $pid, 'target' => $mediaLink ]; } } foreach($media as $mid => $item) { $nodes[] = [ 'id' => $mid, 'group' => 'media', 'label' => $mid."\n".$item['title'] ]; } $graphData = json_encode(['nodes' => $nodes, 'links' => $links]); $saveFile = metaFN('networkgraph_data', '.json'); io_saveFile($saveFile, json_encode([ 'nodes' => $nodes, 'links' => $links ])); } }