Completed
Push — charts ( 02447f )
by Greg
12:32
created

InteractiveTreeModule   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 17
lcom 1
cbo 9
dl 0
loc 163
rs 10
c 2
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getTitle() 0 3 1
A getDescription() 0 3 1
A defaultTabOrder() 0 3 1
A getTabContent() 0 12 1
A hasTabContent() 0 3 1
A isGrayedOut() 0 3 1
A canLoadAjax() 0 3 1
A getChartMenu() 0 8 1
A getBoxChartMenu() 0 3 1
A getPreLoadContent() 0 15 1
B modAction() 0 53 5
A css() 0 3 1
A js() 0 3 1
1
<?php
2
/**
3
 * webtrees: online genealogy
4
 * Copyright (C) 2016 webtrees development team
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 * GNU General Public License for more details.
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
 */
16
namespace Fisharebest\Webtrees\Module;
17
18
use Fisharebest\Webtrees\Auth;
19
use Fisharebest\Webtrees\Controller\ChartController;
20
use Fisharebest\Webtrees\Filter;
21
use Fisharebest\Webtrees\I18N;
22
use Fisharebest\Webtrees\Individual;
23
use Fisharebest\Webtrees\Module\InteractiveTree\TreeView;
24
use Fisharebest\Webtrees\Menu;
25
26
/**
27
 * Class InteractiveTreeModule
28
 * Tip : you could change the number of generations loaded before ajax calls both in individual page and in treeview page to optimize speed and server load
29
 */
30
class InteractiveTreeModule extends AbstractModule implements ModuleTabInterface, ModuleChartInterface {
31
	/** {@inheritdoc} */
32
	public function getTitle() {
33
		return /* I18N: Name of a module */ I18N::translate('Interactive tree');
34
	}
35
36
	/** {@inheritdoc} */
37
	public function getDescription() {
38
		return /* I18N: Description of the “Interactive tree” module */ I18N::translate('An interactive tree, showing all the ancestors and descendants of an individual.');
39
	}
40
41
	/** {@inheritdoc} */
42
	public function defaultTabOrder() {
43
		return 68;
44
	}
45
46
	/** {@inheritdoc} */
47
	public function getTabContent() {
48
		global $controller;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
49
50
		$tv              = new TreeView('tvTab');
51
		list($html, $js) = $tv->drawViewport($controller->record, 3);
52
53
		return
54
			'<script src="' . $this->js() . '"></script>' .
55
			'<script src="' . WT_JQUERYUI_TOUCH_PUNCH_URL . '"></script>' .
56
			'<script>' . $js . '</script>' .
57
			$html;
58
	}
59
60
	/** {@inheritdoc} */
61
	public function hasTabContent() {
62
		return !Auth::isSearchEngine();
63
	}
64
65
	/** {@inheritdoc} */
66
	public function isGrayedOut() {
67
		return false;
68
	}
69
70
	/** {@inheritdoc} */
71
	public function canLoadAjax() {
72
		return true;
73
	}
74
	
75
	/**
76
	 * Return a menu item for this chart.
77
	 *
78
	 * @return Menu|null
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Menu.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
79
	 */
80
	public function getChartMenu(Individual $individual) {
81
		return new Menu(
82
			$this->getTitle(), 
83
			'module.php?mod=tree&amp;mod_action=treeview&amp;rootid=' . $individual->getXref() . '&amp;ged=' . $individual->getTree()->getNameUrl(), 
84
			'menu-chart-tree', 
85
			array('rel' => 'nofollow')
86
		);
87
	}
88
	
89
	/**
90
	 * Return a menu item for this chart - for use in individual boxes.
91
	 *
92
	 * @return Menu|null
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Menu.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
93
	 */
94
	public function getBoxChartMenu(Individual $individual) {
95
		return $this->getChartMenu($individual);
96
	}
97
	
98
	/** {@inheritdoc} */
99
	public function getPreLoadContent() {
100
		// We cannot use jQuery("head").append(<link rel="stylesheet" ...as jQuery is not loaded at this time
101
		return
102
			'<script>
103
			if (document.createStyleSheet) {
104
				document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer
105
			} else {
106
				var newSheet=document.createElement("link");
107
				newSheet.setAttribute("rel","stylesheet");
108
				newSheet.setAttribute("type","text/css");
109
				newSheet.setAttribute("href","' . $this->css() . '");
110
				document.getElementsByTagName("head")[0].appendChild(newSheet);
111
			}
112
			</script>';
113
	}
114
115
	/**
116
	 * This is a general purpose hook, allowing modules to respond to routes
117
	 * of the form module.php?mod=FOO&mod_action=BAR
118
	 *
119
	 * @param string $mod_action
120
	 */
121
	public function modAction($mod_action) {
122
		global $controller, $WT_TREE;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
123
124
		switch ($mod_action) {
125
		case 'treeview':
126
			$controller = new ChartController;
127
			$tv         = new TreeView('tv');
128
			ob_start();
129
130
			$person = $controller->getSignificantIndividual();
131
132
			list($html, $js) = $tv->drawViewport($person, 4);
133
134
			$controller
135
				->setPageTitle(I18N::translate('Interactive tree of %s', $person->getFullName()))
136
				->pageHeader()
137
				->addExternalJavascript($this->js())
138
				->addExternalJavascript(WT_JQUERYUI_TOUCH_PUNCH_URL)
139
				->addInlineJavascript($js)
140
				->addInlineJavascript('
141
					if (document.createStyleSheet) {
142
						document.createStyleSheet("' . $this->css() . '"); // For Internet Explorer
143
					} else {
144
						jQuery("head").append(\'<link rel="stylesheet" type="text/css" href="' . $this->css() . '">\');
145
					}
146
				');
147
			echo $html;
148
			break;
149
150
		case 'getDetails':
151
			header('Content-Type: text/html; charset=UTF-8');
152
			$pid        = Filter::get('pid', WT_REGEX_XREF);
153
			$i          = Filter::get('instance');
154
			$tv         = new TreeView($i);
155
			$individual = Individual::getInstance($pid, $WT_TREE);
156
			if ($individual) {
157
				echo $tv->getDetails($individual);
0 ignored issues
show
Compatibility introduced by
$individual of type object<Fisharebest\Webtrees\GedcomRecord> is not a sub-type of object<Fisharebest\Webtrees\Individual>. It seems like you assume a child class of the class Fisharebest\Webtrees\GedcomRecord to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
158
			}
159
			break;
160
161
		case 'getPersons':
162
			header('Content-Type: text/html; charset=UTF-8');
163
			$q  = Filter::get('q');
164
			$i  = Filter::get('instance');
165
			$tv = new TreeView($i);
166
			echo $tv->getPersons($q);
167
			break;
168
169
		default:
170
			http_response_code(404);
171
			break;
172
		}
173
	}
174
175
	/**
176
	 * URL for our style sheet.
177
	 *
178
	 * @return string
179
	 */
180
	public function css() {
181
		return WT_STATIC_URL . WT_MODULES_DIR . $this->getName() . '/css/treeview.css';
182
	}
183
184
	/**
185
	 * URL for our JavaScript.
186
	 *
187
	 * @return string
188
	 */
189
	public function js() {
190
		return WT_STATIC_URL . WT_MODULES_DIR . $this->getName() . '/js/treeview.js';
191
	}
192
}
193