Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
27 | class helper_plugin_spatialhelper_index extends DokuWiki_Plugin { |
||
28 | /** |
||
29 | * directory for index files. |
||
30 | * |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $idx_dir = ''; |
||
34 | |||
35 | /** |
||
36 | * spatial index, well lookup list/array so we can do spatial queries. |
||
37 | * entries should be: array("geohash" => {"id1","id3",}) |
||
38 | * |
||
39 | * @var array |
||
40 | */ |
||
41 | protected $spatial_idx = array(); |
||
42 | |||
43 | /** |
||
44 | * handle to the geoPHP plugin. |
||
45 | */ |
||
46 | protected $geophp; |
||
47 | |||
48 | /** |
||
49 | * Constructor, initialises the spatial index. |
||
50 | */ |
||
51 | public function __construct() { |
||
52 | // parent::__construct (); |
||
|
|||
53 | View Code Duplication | if (!$geophp = &plugin_load('helper', 'geophp')) { |
|
54 | $message = 'helper_plugin_spatialhelper_index::spatialhelper_index: geophp plugin is not available.'; |
||
55 | msg($message, - 1); |
||
56 | return ""; |
||
57 | } |
||
58 | |||
59 | global $conf; |
||
60 | $this->idx_dir = $conf ['indexdir']; |
||
61 | // test if there is a spatialindex, if not build one for the wiki |
||
62 | if (!@file_exists($this->idx_dir . '/spatial.idx')) { |
||
63 | // creates and stores the index |
||
64 | $this->generateSpatialIndex(); |
||
65 | } else { |
||
66 | $this->spatial_idx = unserialize(io_readFile($this->idx_dir . '/spatial.idx', false)); |
||
67 | dbglog($this->spatial_idx, 'done loading spatial index'); |
||
68 | } |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Update the spatial index for the page. |
||
73 | * |
||
74 | * @param string $id |
||
75 | * the document ID |
||
76 | */ |
||
77 | public function updateSpatialIndex($id) { |
||
78 | $geotags = p_get_metadata($id, 'geo'); |
||
79 | if (empty ($geotags)) { |
||
80 | return false; |
||
81 | } |
||
82 | if (empty ($geotags ['lon']) || empty ($geotags ['lat'])) { |
||
83 | return false; |
||
84 | } |
||
85 | dbglog($geotags, "Geo metadata found for page $id"); |
||
86 | $geometry = new Point($geotags ['lon'], $geotags ['lat']); |
||
87 | $geohash = $geometry->out('geohash'); |
||
88 | dbglog('Update index for geohash: ' . $geohash); |
||
89 | $succes = $this->_addToIndex($geohash, $id); |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Looks up the geohash(es) for the document in the index. |
||
94 | * |
||
95 | * @param String $id |
||
96 | * document ID |
||
97 | * @param array $index |
||
98 | * spatial index |
||
99 | */ |
||
100 | public function findHashesForId($id, $index) { |
||
101 | $hashes = array(); |
||
102 | foreach ($index as $hash => $docIds) { |
||
103 | if (in_array($id, $docIds, false)) { |
||
104 | $hashes [] = $hash; |
||
105 | } |
||
106 | } |
||
107 | dbglog($hashes, "Found the following hashes for $id (should only be 1)"); |
||
108 | return $hashes; |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * Deletes the page from the index. |
||
113 | * |
||
114 | * @param String $id |
||
115 | * document ID |
||
116 | */ |
||
117 | public function deleteFromIndex($id) { |
||
118 | // check the index for document |
||
119 | $knownHashes = $this->findHashesForId($id, $this->spatial_idx); |
||
120 | if (empty ($knownHashes)) { |
||
121 | return; |
||
122 | } |
||
123 | |||
124 | // TODO shortcut, need to make sure there is only one element, if not the index is corrupt |
||
125 | $knownHash = $knownHashes [0]; |
||
126 | $knownIds = $this->spatial_idx [$knownHash]; |
||
127 | $i = array_search($id, $knownIds); |
||
128 | dbglog("removing: $knownIds[$i] from the index."); |
||
129 | unset ($knownIds [$i]); |
||
130 | $this->spatial_idx [$knownHash] = $knownIds; |
||
131 | if (empty ($this->spatial_idx [$knownHash])) { |
||
132 | // dbglog ( "removing key: $knownHash from the index." ); |
||
133 | unset ($this->spatial_idx [$knownHash]); |
||
134 | } |
||
135 | $succes = $this->_saveIndex(); |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Save spatial index. |
||
140 | */ |
||
141 | private function _saveIndex() { |
||
144 | |||
145 | /** |
||
146 | * (re-)Generates the spatial index by running through all the pages in the wiki. |
||
147 | * |
||
148 | * @todo add an option to erase the old index |
||
149 | */ |
||
150 | public function generateSpatialIndex() { |
||
168 | |||
169 | /** |
||
170 | * Add an index entry for this file having EXIF / IPTC data. |
||
171 | * |
||
172 | * @param unknown_type $img Dokuwiki image |
||
173 | * @see http://www.php.net/manual/en/function.iptcparse.php |
||
174 | * @see http://php.net/manual/en/function.exif-read-data.php |
||
175 | * |
||
176 | * @return boolean true when image was succesfully added to the index. |
||
177 | */ |
||
178 | public function indexImage($img) { |
||
194 | |||
195 | /** |
||
196 | * retrieve GPS decimal coordinates from exif. |
||
197 | * |
||
198 | * @param |
||
199 | * $id |
||
200 | * @return Point or false |
||
201 | */ |
||
202 | public function getCoordsFromExif($id) { |
||
224 | |||
225 | /** |
||
226 | * Store the hash/id entry in the index. |
||
227 | * |
||
228 | * @param string $geohash |
||
229 | * @param string $id |
||
230 | * page or media id |
||
231 | * @return boolean true when succesful |
||
232 | */ |
||
233 | private function _addToIndex($geohash, $id) { |
||
274 | |||
275 | /** |
||
276 | * convert DegreesMinutesSeconds to Decimal degrees. |
||
277 | * |
||
278 | * @param array $param array of rational DMS |
||
279 | * @return number |
||
280 | */ |
||
281 | public function convertDMStoD($param) { |
||
292 | |||
293 | private function _convertRationaltoFloat($param) { |
||
302 | } |
||
303 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.