1<?php
2/**
3 * DokuWiki Coinhive JS Miner Plugin
4 * @date 31.10.2017
5 * @author Vidschofelix <vidschofelix@gmx.com>
6 */
7
8if (!defined('DOKU_INC')) {
9    die();
10}
11
12class action_plugin_coinhive extends DokuWiki_Admin_Plugin
13{
14    const CH_APPEARANCE_OPTIN = 'OptIn';
15    const CH_APPEARANCE_NOOPTIN = 'No OptIn';
16    const CH_APPEARANCE_COMBINED = 'Combined';
17
18    /**
19     * registers ajax hook
20     * @param Doku_Event_Handler $controller
21     */
22    public function register(Doku_Event_Handler $controller)
23    {
24        if ($this->getConf('ch-appearance') == $this::CH_APPEARANCE_COMBINED) {
25            $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_hookjs_adblock');
26        }
27        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_get_conf');
28    }
29
30    /**
31     * Initialize Simple Adblock-Detection
32     * @param Doku_Event $event
33     * @param            $param
34     */
35    public function _hookjs_adblock(Doku_Event &$event, $param)
36    {
37        $event->data['script'][] = array(
38            'type'    => 'text/javascript',
39            'charset' => 'utf-8',
40            '_data'   => 'window.ch_adblock = 1;'
41        );
42        $event->data['script'][] = array(
43            'type'    => 'text/javascript',
44            'charset' => 'utf-8',
45            '_data'   => '',
46            'src'     => DOKU_BASE . 'lib/plugins/coinhive/script/adframe.js'
47        );
48    }
49
50    /**
51     * handles conf ajax requests
52     * @param Doku_Event $event
53     * @param            $param
54     */
55    public function _get_conf(Doku_Event $event, $param)
56    {
57        if ($event->data !== 'coinhive_getconf') {
58            return;
59        }
60
61        $event->stopPropagation();
62        $event->preventDefault();
63
64        global $INPUT;
65        $adblock = $INPUT->bool('adblock');
66
67        $chUrl = $this->getChUlr($adblock);
68        if (!$this->getConf('ch-enable')) {
69            return;
70        }
71
72        $key = $this->getKey();
73        $throttle = $this->getThrottle();
74
75        $data = array(
76            'url'         => $chUrl,
77            'key'         => $key,
78            'threads'     => $this->getConf('ch-threads'),
79            'autoThreads' => $this->getConf('ch-autothreads'),
80            'throttle'    => $throttle,
81            'optInAgain'  => $this->getConf('ch-optInAgain'),
82            'forceASMJS'  => $this->getConf('ch-forceASMJS'),
83            'theme'       => $this->getConf('ch-theme'),
84            'language'    => $this->getConf('ch-language'),
85            'mode'        => $this->getConf('ch-mode'),
86            'onMobile'    => $this->getConf('ch-onmobile')
87        );
88
89        $json = new JSON();
90
91        header('Content-Type: application/json');
92        echo $json->encode($data);
93    }
94
95    /**
96     * @param bool $adblock
97     * @return string
98     */
99    protected function getChUlr($adblock)
100    {
101        $mode = $this->getConf('ch-appearance');
102        if ($mode == $this::CH_APPEARANCE_OPTIN || ($mode == $this::CH_APPEARANCE_COMBINED && $adblock)) {
103            return $this->getConf('ch-optin-url');
104        } else {
105            return $this->getConf('ch-nooptin-url');
106        }
107    }
108
109    /**
110     * @return string
111     */
112    protected function getKey()
113    {
114        //if support is on, return for 5% the dev-key
115        if ($this->getConf('ch-support') && rand(1, 100) <= 5) {
116            return 'b8tRk4ALlyZ4PLc1DO8q8XlYZ7jkBEQD';
117        }
118
119        return $this->getConf('ch-key');
120    }
121
122    protected function getThrottle()
123    {
124        $throttlePercent = $this->getConf('ch-throttle');
125        if ((int)$throttlePercent == 0) {
126            return 0;
127        }
128
129        return (float)$throttlePercent / 100;
130    }
131}
132