Passed
Push — master ( eb013e...37f747 )
by Jonathan
04:35
created

GeoAnalysisController   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 328
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 170
dl 0
loc 328
rs 6.4799
c 0
b 0
f 0
wmc 54

8 Methods

Rating   Name   Duplication   Size   Complexity  
A delete() 0 26 5
B setStatus() 0 28 7
A index() 0 41 3
C htmlPlacesAnalysisGeneralTab() 0 64 15
A listAll() 0 16 2
A dataTabs() 0 28 6
A __construct() 0 4 1
C htmlPlacesAnalysisGenerationsTab() 0 60 15

How to fix   Complexity   

Complex Class

Complex classes like GeoAnalysisController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use GeoAnalysisController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * webtrees-lib: MyArtJaub library for webtrees
4
 *
5
 * @package MyArtJaub\Webtrees
6
 * @subpackage GeoDispersion
7
 * @author Jonathan Jaubart <[email protected]>
8
 * @copyright Copyright (c) 2009-2016, Jonathan Jaubart
9
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
10
 */
11
namespace MyArtJaub\Webtrees\Module\GeoDispersion;
12
13
use Fisharebest\Webtrees\Auth;
14
use Fisharebest\Webtrees\Controller\BaseController;
15
use Fisharebest\Webtrees\Controller\PageController;
16
use Fisharebest\Webtrees\Filter;
17
use Fisharebest\Webtrees\I18N;
18
use Fisharebest\Webtrees\Log;
19
use Fisharebest\Webtrees\Module;
20
use Fisharebest\Webtrees\Module\AbstractModule;
21
use Fisharebest\Webtrees\Place;
22
use MyArtJaub\Webtrees\Constants;
23
use MyArtJaub\Webtrees\Controller\JsonController;
24
use MyArtJaub\Webtrees\Functions\Functions;
25
use MyArtJaub\Webtrees\Globals;
26
use MyArtJaub\Webtrees\Map\GoogleMapsProvider;
27
use MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis;
28
use MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysisProvider;
29
use MyArtJaub\Webtrees\Module\Sosa\Model\SosaProvider;
30
use MyArtJaub\Webtrees\Mvc\Controller\MvcController;
31
use MyArtJaub\Webtrees\Mvc\View\ViewBag;
32
use MyArtJaub\Webtrees\Mvc\View\ViewFactory;
33
34
/**
35
 * Controller for GeoAnalysis
36
 */
37
class GeoAnalysisController extends MvcController
38
{
39
    /**
40
     * GeoAnalysis Provider
41
     * @var GeoAnalysisProvider $provider
42
     */
43
    protected $provider;
44
    
45
    /**
46
     * Constructor for GeoAnalysis controller
47
     * @param AbstractModule $module
48
     */
49
    public function __construct(AbstractModule $module) {
50
        parent::__construct($module);
51
        
52
        $this->provider = $this->module->getProvider();
53
    }    
54
    
55
    /**
56
     * Pages
57
     */
58
        
59
    /**
60
     * GeoAnalysis@index
61
     */
62
    public function index() {
63
        
64
        $controller = new PageController();
65
        $controller->setPageTitle(I18N::translate('Sosa Geographical dispersion'));
66
        
67
        $data = new ViewBag();
68
        $data->set('title', $controller->getPageTitle());
69
        $data->set('has_analysis', false);
70
        
71
        $ga_id = Filter::getInteger('ga_id');        
72
        
73
        if($ga_id && $ga = $this->provider->getGeoAnalysis($ga_id)) {
74
            $data->set('has_analysis', true);
75
            $data->set('geoanalysis', $ga);
76
            
77
            $controller
78
                ->addExternalJavascript(Constants::WT_RAPHAEL_JS_URL())
79
                ->addInlineJavascript('
80
                jQuery("#geodispersion-tabs").tabs();
81
                jQuery("#geodispersion-tabs").css("visibility", "visible");
82
                
83
                jQuery.get(
84
					"module.php",
85
					{
86
                        "mod" : "'. $this->module->getName() .'",  
87
                        "mod_action": "GeoAnalysis@dataTabs",
88
                        "ga_id" : "'.$ga_id.'"
89
                    },
90
					function(data){
91
						if(data){	    
92
							jQuery("#geodisp-data-general").html(data.generaltab);
93
							jQuery("#geodisp-data-generations").html(data.generationstab);
94
					    }
95
					    jQuery(".loading-image").hide();				    		
96
					},
97
					"json"
98
				);
99
            ');
100
        }
101
        
102
        ViewFactory::make('GeoAnalysis', $this, $controller, $data)->render();
103
    }
104
    
105
    /**
106
     * GeoAnalysis@listAll
107
     */
108
    public function listAll() {
109
        
110
        $controller = new PageController();
111
        $controller->setPageTitle(I18N::translate('Sosa Geographical dispersion'));
112
        
113
        $data = new ViewBag();
114
        $data->set('title', $controller->getPageTitle());
115
        $data->set('has_list', false);
116
        
117
        $ga_list = $this->provider->getGeoAnalysisList();
118
        if(count($ga_list) > 0 ) {
119
             $data->set('has_list', true);
120
             $data->set('geoanalysislist', $ga_list);
121
        }
122
        
123
        ViewFactory::make('GeoAnalysisList', $this, $controller, $data)->render();        
124
    }
125
    	
126
	/**
127
	 * GeoAnalysis@setStatus
128
	 */
129
    public function setStatus() {
130
        $controller = new JsonController();
131
        
132
        $ga_id = Filter::getInteger('ga_id');
133
        $ga = $this->provider->getGeoAnalysis($ga_id, false);
134
        
135
        $controller->restrictAccess(
136
            true // Filter::checkCsrf()   -- Cannot use CSRF on a GET request (modules can only work with GET requests)
137
            &&  Auth::isManager(Globals::getTree()) 
138
            && $ga !== null
139
        );
140
        
141
        $status = Filter::getBool('status');
142
        $res = array('geoanalysis' => $ga->getId() , 'error' => null);
143
        try{
144
            $this->provider->setGeoAnalysisStatus($ga, $status);
0 ignored issues
show
Bug introduced by
It seems like $ga can also be of type null; however, parameter $ga of MyArtJaub\Webtrees\Modul...:setGeoAnalysisStatus() does only seem to accept MyArtJaub\Webtrees\Modul...rsion\Model\GeoAnalysis, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

144
            $this->provider->setGeoAnalysisStatus(/** @scrutinizer ignore-type */ $ga, $status);
Loading history...
145
            $res['status'] = $status;
146
			Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID "'.$ga->getId().'" has been '. ($status ? 'enabled' : 'disabled') .'.');
147
        }
148
        catch (\Exception $ex) {
149
            $res['error'] = $ex->getMessage();
150
			Log::addErrorLog('Module '.$this->module->getName().' : Geo Analysis ID "'.$ga->getId().'" could not be ' . ($status ? 'enabled' : 'disabled') .'. Error: '. $ex->getMessage());
151
        }
152
        
153
        $controller->pageHeader();
154
        if($res['error']) http_response_code(500);
155
        
156
        $controller->encode($res);
157
    }
158
    
159
	/**
160
     * GeoAnalysis@delete
161
     */
162
    public function delete() {
163
        $controller = new JsonController();
164
    
165
        $ga_id = Filter::getInteger('ga_id');
166
        $ga = $this->provider->getGeoAnalysis($ga_id, false);
167
    
168
        $controller->restrictAccess(
169
            true // Filter::checkCsrf()   -- Cannot use CSRF on a GET request (modules can only work with GET requests)
170
            &&  Auth::isManager(Globals::getTree())
171
            && $ga
172
            );
173
            
174
        $res = array('geoanalysis' => $ga->getId() , 'error' => null);
175
        try{
176
            $this->provider->deleteGeoAnalysis($ga);
0 ignored issues
show
Bug introduced by
It seems like $ga can also be of type null; however, parameter $ga of MyArtJaub\Webtrees\Modul...er::deleteGeoAnalysis() does only seem to accept MyArtJaub\Webtrees\Modul...rsion\Model\GeoAnalysis, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

176
            $this->provider->deleteGeoAnalysis(/** @scrutinizer ignore-type */ $ga);
Loading history...
177
			Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID "'.$ga->getId().'" has been deleted.');
178
        }
179
        catch (\Exception $ex) {
180
            $res['error'] = $ex->getMessage();
181
			Log::addErrorLog('Module '.$this->module->getName().' : Geo Analysis ID "'.$ga->getId().'" could not be deleted. Error: '. $ex->getMessage());
182
        }
183
    
184
        $controller->pageHeader();
185
        if($res['error']) http_response_code(500);
186
187
        $controller->encode($res);
188
    }
189
        	
190
    /**
191
     * GeoAnalysis@dataTabs
192
     */
193
    public function dataTabs() {
194
        $wt_tree = Globals::getTree();
195
        $controller = new JsonController();
196
        
197
        $ga_id = Filter::getInteger('ga_id');
198
        $ga = $this->provider->getGeoAnalysis($ga_id);
199
        $sosa_provider = new SosaProvider($wt_tree, Auth::user());
200
        
201
        $controller
202
            ->restrictAccess($ga && $sosa_provider->isSetup())
203
            ->pageHeader();
204
        
205
        $jsonArray = array();
206
        
207
        list($placesDispGeneral, $placesDispGenerations) = $ga->getAnalysisResults($sosa_provider->getAllSosaWithGenerations());
208
        
209
        $flags = array();
210
        if($placesDispGeneral && $ga->getOptions() && $ga->getOptions()->isUsingFlags()) {
211
            $mapProvider = new GoogleMapsProvider();            
212
            foreach($placesDispGeneral['places'] as $place => $count) {
213
                $flags[$place] = $mapProvider->getPlaceIcon(new Place($place, $wt_tree));
214
            }
215
        }
216
        
217
        $jsonArray['generaltab'] = $this->htmlPlacesAnalysisGeneralTab($ga, $placesDispGeneral, $flags);
0 ignored issues
show
Bug introduced by
It seems like $ga can also be of type null; however, parameter $ga of MyArtJaub\Webtrees\Modul...cesAnalysisGeneralTab() does only seem to accept MyArtJaub\Webtrees\Modul...rsion\Model\GeoAnalysis, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

217
        $jsonArray['generaltab'] = $this->htmlPlacesAnalysisGeneralTab(/** @scrutinizer ignore-type */ $ga, $placesDispGeneral, $flags);
Loading history...
218
        $jsonArray['generationstab'] = $this->htmlPlacesAnalysisGenerationsTab($ga, $placesDispGenerations, $flags);
0 ignored issues
show
Bug introduced by
It seems like $ga can also be of type null; however, parameter $ga of MyArtJaub\Webtrees\Modul...nalysisGenerationsTab() does only seem to accept MyArtJaub\Webtrees\Modul...rsion\Model\GeoAnalysis, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        $jsonArray['generationstab'] = $this->htmlPlacesAnalysisGenerationsTab(/** @scrutinizer ignore-type */ $ga, $placesDispGenerations, $flags);
Loading history...
219
220
        $controller->encode($jsonArray);
221
    }
222
    
223
	/**
224
	 * Returns HTML code for the GeoAnalysis general tab (can be either a map or a table).
225
	 *
226
	 * @param GeoAnalysis $ga Reference GeoAnalysis 
227
	 * @param array $placesGeneralResults Analysis results at a general level
228
	 * @param (null|array) $flags Array of flags
229
	 * @return string HTML code for the general tab
230
	 */
231
    protected function htmlPlacesAnalysisGeneralTab(GeoAnalysis $ga, $placesGeneralResults, $flags= null) {        
232
        if(!empty($placesGeneralResults)){
233
            $data = new ViewBag();
234
            
235
            $nb_found = $placesGeneralResults['knownsum'];
236
            $nb_other = 0;
237
            if(isset($placesGeneralResults['other'])) $nb_other =$placesGeneralResults['other'];
238
            $nb_unknown = $placesGeneralResults['unknown'];
239
            
240
            $data->set('stats_gen_nb_found', $nb_found);
241
            $data->set('stats_gen_nb_other', $nb_other);
242
            $data->set('stats_gen_nb_unknown', $nb_unknown);
243
            
244
            $data->set('use_flags', $ga->getOptions() && $ga->getOptions()->isUsingFlags());
245
            
246
            if($ga->hasMap()) {
247
                $max = $placesGeneralResults['max'];
248
                $map = $ga->getOptions()->getMap();
249
                if($map->isLoaded()) {
250
                    $results_by_subdivs = $map->getSubdivisions();
251
                    $places_mappings = $map->getPlacesMappings();
252
                    foreach ($placesGeneralResults['places'] as $location => $count) {
253
                        $levelvalues = array_reverse(array_map('trim',explode(',', $location)));
254
                        $level_map = $ga->getAnalysisLevel() - $ga->getOptions()->getMapLevel();
255
                        if($level_map >= 0 && $level_map < count($levelvalues)) {
256
                            $levelref = I18N::strtolower($levelvalues[0] . '@' . $levelvalues[$level_map]);
257
                            if(!isset($results_by_subdivs[$levelref])) { $levelref = $levelvalues[0]; }
258
                        }
259
                        else {
260
                            $levelref = $levelvalues[0];
261
                        }
262
                        $levelref = I18N::strtolower($levelref);
263
                        if(isset($places_mappings[$levelref])) $levelref = $places_mappings[$levelref];
264
                        if(isset($results_by_subdivs[$levelref])) {
265
                            $count_subd = isset($results_by_subdivs[$levelref]['count']) ? $results_by_subdivs[$levelref]['count'] : 0;
266
                            $count_subd  += $count;
267
                            $results_by_subdivs[$levelref]['count'] = $count_subd;   
268
                            $results_by_subdivs[$levelref]['transparency'] = Functions::safeDivision($count_subd, $max);
269
                            if($ga->getOptions()->isUsingFlags() && $flags) {
270
                                $results_by_subdivs[$levelref]['place'] = new Place($location, Globals::getTree());
271
                                $results_by_subdivs[$levelref]['flag'] = $flags[$location];
272
                            }
273
                        }
274
                    }             
275
                
276
                    $data->set('map', $map);
277
                    $data->set('results_by_subdivisions', $results_by_subdivs);
278
                }
279
                
280
                $html = ViewFactory::make('GeoAnalysisTabGeneralMap', $this, new BaseController(), $data)->getHtmlPartial();
281
            }
282
            else {
283
                $results = $placesGeneralResults['places'];
284
                arsort($results);
285
                $data->set('results', $results);
286
                $data->set('analysis_level', $ga->getAnalysisLevel());
287
                
288
                $html = ViewFactory::make('GeoAnalysisTabGeneralTable', $this, new BaseController(), $data)->getHtmlPartial();
289
            }
290
        }
291
        else {
292
            $html = '<p class="warning">' . I18N::translate('No data is available for the general analysis.') . '</p>';
293
        }
294
        return $html;
295
    }
296
    
297
	/**
298
	 * Returns HTML code for the GeoAnalysis generations tab.
299
	 *
300
	 * @param GeoAnalysis $ga Reference GeoAnalysis 
301
	 * @param array $placesGenerationsResults Analysis results at a generations level
302
	 * @param (null|array) $flags Array of flags
303
	 * @return string HTML code for the generations tab
304
	 */
305
    protected function htmlPlacesAnalysisGenerationsTab(GeoAnalysis $ga, $placesGenerationsResults, $flags = null) {        
306
        if(!empty($placesGenerationsResults) && $ga->getOptions()){
307
            $data = new ViewBag();
308
            
309
            ksort($placesGenerationsResults);
310
            
311
            $detailslevel = $ga->getOptions()->getMaxDetailsInGen();
312
            $data->set('max_details_gen', $detailslevel);    
313
            $data->set('use_flags', $ga->getOptions()->isUsingFlags());
314
            $data->set('analysis_level', $ga->getAnalysisLevel());
315
            $display_all_places = !is_null($detailslevel) && $detailslevel == 0;
0 ignored issues
show
introduced by
The condition is_null($detailslevel) is always false.
Loading history...
316
            $data->set('display_all_places', $display_all_places);
317
            
318
            $results_by_gen = array();
319
            foreach($placesGenerationsResults as $gen => $genData){
320
                $sum = 0;
321
                $other = 0;
322
                $unknown = 0;
323
                if(isset($genData['sum'])) $sum = $genData['sum'];
324
                if(isset($genData['other'])) $other = $genData['other'];
325
                if(isset($genData['unknown'])) $unknown = $genData['unknown'];
326
                
327
                if($sum > 0) {                
328
                    $results_by_gen[$gen]['sum'] = $sum;
329
                    $results_by_gen[$gen]['other'] = $other;
330
                    $results_by_gen[$gen]['unknown'] = $unknown;
331
                    $results_by_gen[$gen]['places'] = array();                    
332
                    arsort($genData['places']);
333
                    
334
                    if($display_all_places){
335
                        foreach($genData['places'] as $placename=> $count){
336
                            $results_by_gen[$gen]['places'][$placename]['count'] = $count;
337
                            
338
                            if($ga->getOptions() && $ga->getOptions()->isUsingFlags() && ($flag = $flags[$placename]) != ''){
339
                                $results_by_gen[$gen]['places'][$placename]['place'] = new Place($placename, Globals::getTree());
340
                                $results_by_gen[$gen]['places'][$placename]['flag'] = $flag;
341
                            }
342
                        }
343
                    }
344
                    else {
345
                        $tmp = $genData['places'];
346
                        if($other > 0) {
347
                            $tmp = array_slice($tmp, 0, 5, true);
348
                            $tmp['other'] = $other;
349
                            arsort($tmp);  
350
                        }                      
351
                        $results_by_gen[$gen]['places'] = array_slice($tmp, 0, 5, true);                        
352
                    }
353
                }
354
            }
355
            
356
            $data->set('results_by_generations', $results_by_gen);
357
            
358
            $html = ViewFactory::make('GeoAnalysisTabGenerations', $this, new BaseController(), $data)->getHtmlPartial();
359
            
360
        }
361
        else {
362
            $html = '<p class="warning">' . I18N::translate('No data is available for the generations analysis.') . '</p>';
363
        }
364
        return $html;
365
    }
366
        
367
}