Failed Conditions
Push — refactorCachePSR2 ( 0db577 )
by Michael
05:36 queued 02:56
created

helper_plugin_extension_repository   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 186
rs 9.92
c 0
b 0
f 0
wmc 31
lcom 1
cbo 4

5 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 36 9
A hasAccess() 0 22 4
B getData() 0 24 6
A search() 0 22 3
B parseQuery() 0 43 9
1
<?php
2
/**
3
 * DokuWiki Plugin extension (Helper Component)
4
 *
5
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6
 * @author  Michael Hamann <[email protected]>
7
 */
8
9
use dokuwiki\Cache\Cache;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Cache.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
10
11
/**
12
 * Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org
13
 */
14
class helper_plugin_extension_repository extends DokuWiki_Plugin
15
{
16
17
    const EXTENSION_REPOSITORY_API = 'http://www.dokuwiki.org/lib/plugins/pluginrepo/api.php';
18
19
    private $loaded_extensions = array();
20
    private $has_access = null;
21
22
    /**
23
     * Initialize the repository (cache), fetches data for all installed plugins
24
     */
25
    public function init()
26
    {
27
        /* @var Doku_Plugin_Controller $plugin_controller */
28
        global $plugin_controller;
29
        if ($this->hasAccess()) {
30
            $list = $plugin_controller->getList('', true);
31
            $request_data = array('fmt' => 'php');
32
            $request_needed = false;
33
            foreach ($list as $name) {
34
                $cache = new Cache('##extension_manager##'.$name, '.repo');
35
36
                if (!isset($this->loaded_extensions[$name]) &&
37
                    $this->hasAccess() &&
38
                    !$cache->useCache(array('age' => 3600 * 24))
39
                ) {
40
                    $this->loaded_extensions[$name] = true;
41
                    $request_data['ext'][] = $name;
42
                    $request_needed = true;
43
                }
44
            }
45
46
            if ($request_needed) {
47
                $httpclient = new DokuHTTPClient();
48
                $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $request_data);
49
                if ($data !== false) {
50
                    $extensions = unserialize($data);
51
                    foreach ($extensions as $extension) {
52
                        $cache = new Cache('##extension_manager##'.$extension['plugin'], '.repo');
53
                        $cache->storeCache(serialize($extension));
54
                    }
55
                } else {
56
                    $this->has_access = false;
57
                }
58
            }
59
        }
60
    }
61
62
    /**
63
     * If repository access is available
64
     *
65
     * @return bool If repository access is available
66
     */
67
    public function hasAccess()
68
    {
69
        if ($this->has_access === null) {
70
            $cache = new Cache('##extension_manager###hasAccess', '.repo');
71
72
            if (!$cache->useCache(array('age' => 3600 * 24, 'purge'=>1))) {
73
                $httpclient = new DokuHTTPClient();
74
                $httpclient->timeout = 5;
75
                $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?cmd=ping');
76
                if ($data !== false) {
77
                    $this->has_access = true;
78
                    $cache->storeCache(1);
79
                } else {
80
                    $this->has_access = false;
81
                    $cache->storeCache(0);
82
                }
83
            } else {
84
                $this->has_access = ($cache->retrieveCache(false) == 1);
85
            }
86
        }
87
        return $this->has_access;
88
    }
89
90
    /**
91
     * Get the remote data of an individual plugin or template
92
     *
93
     * @param string $name  The plugin name to get the data for, template names need to be prefix by 'template:'
94
     * @return array The data or null if nothing was found (possibly no repository access)
95
     */
96
    public function getData($name)
97
    {
98
        $cache = new Cache('##extension_manager##'.$name, '.repo');
99
100
        if (!isset($this->loaded_extensions[$name]) &&
101
            $this->hasAccess() &&
102
            !$cache->useCache(array('age' => 3600 * 24))
103
        ) {
104
            $this->loaded_extensions[$name] = true;
105
            $httpclient = new DokuHTTPClient();
106
            $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?fmt=php&ext[]='.urlencode($name));
107
            if ($data !== false) {
108
                $result = unserialize($data);
109
                $cache->storeCache(serialize($result[0]));
110
                return $result[0];
111
            } else {
112
                $this->has_access = false;
113
            }
114
        }
115
        if (file_exists($cache->cache)) {
116
            return unserialize($cache->retrieveCache(false));
117
        }
118
        return array();
119
    }
120
121
    /**
122
     * Search for plugins or templates using the given query string
123
     *
124
     * @param string $q the query string
125
     * @return array a list of matching extensions
126
     */
127
    public function search($q)
128
    {
129
        $query = $this->parseQuery($q);
130
        $query['fmt'] = 'php';
131
132
        $httpclient = new DokuHTTPClient();
133
        $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $query);
134
        if ($data === false) return array();
135
        $result = unserialize($data);
136
137
        $ids = array();
138
139
        // store cache info for each extension
140
        foreach ($result as $ext) {
141
            $name = $ext['plugin'];
142
            $cache = new Cache('##extension_manager##'.$name, '.repo');
143
            $cache->storeCache(serialize($ext));
144
            $ids[] = $name;
145
        }
146
147
        return $ids;
148
    }
149
150
    /**
151
     * Parses special queries from the query string
152
     *
153
     * @param string $q
154
     * @return array
155
     */
156
    protected function parseQuery($q)
157
    {
158
        $parameters = array(
159
            'tag'  => array(),
160
            'mail' => array(),
161
            'type' => array(),
162
            'ext'  => array()
163
        );
164
165
        // extract tags
166
        if (preg_match_all('/(^|\s)(tag:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
167
            foreach ($matches as $m) {
168
                $q = str_replace($m[2], '', $q);
169
                $parameters['tag'][] = $m[3];
170
            }
171
        }
172
        // extract author ids
173
        if (preg_match_all('/(^|\s)(authorid:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
174
            foreach ($matches as $m) {
175
                $q = str_replace($m[2], '', $q);
176
                $parameters['mail'][] = $m[3];
177
            }
178
        }
179
        // extract extensions
180
        if (preg_match_all('/(^|\s)(ext:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
181
            foreach ($matches as $m) {
182
                $q = str_replace($m[2], '', $q);
183
                $parameters['ext'][] = $m[3];
184
            }
185
        }
186
        // extract types
187
        if (preg_match_all('/(^|\s)(type:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
188
            foreach ($matches as $m) {
189
                $q = str_replace($m[2], '', $q);
190
                $parameters['type'][] = $m[3];
191
            }
192
        }
193
194
        // FIXME make integer from type value
195
196
        $parameters['q'] = trim($q);
197
        return $parameters;
198
    }
199
}
200
201
// vim:ts=4:sw=4:et:
202