Completed
Push — 2.1 ( 3e87a2...1ad0d0 )
by Daniel
9s
created

TranslatableCMSMainExtension   C

Complexity

Total Complexity 43

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 19

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 43
c 1
b 0
f 0
lcom 1
cbo 19
dl 0
loc 228
rs 5.6245

13 Methods

Rating   Name   Duplication   Size   Complexity  
A updatePageOptions() 0 3 1
A updateLink() 0 4 3
A updateLinkWithSearch() 0 4 3
A updateExtraTreeTools() 0 4 2
A updateLinkPageAdd() 0 4 3
A selectlang() 0 3 1
A IsTranslatableEnabled() 0 3 1
A updateEditForm() 0 6 3
A MultipleLanguages() 0 5 1
C init() 0 76 18
B createtranslation() 0 31 3
B LangForm() 0 36 2
A updateDoAdd() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like TranslatableCMSMainExtension 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 TranslatableCMSMainExtension, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package translatable
4
 */
5
class TranslatableCMSMainExtension extends Extension {
6
7
	private static $allowed_actions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
8
		'createtranslation',
9
	);
10
11
	function init() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
12
		$req = $this->owner->getRequest();
13
14
		// Ignore being called on LeftAndMain base class,
15
		// which is the case when requests are first routed through AdminRootController
16
		// as an intermediary rather than the endpoint controller
17
		if(!$this->owner->stat('tree_class')) return;
18
19
		// Locale" attribute is either explicitly added by LeftAndMain Javascript logic,
20
		// or implied on a translated record (see {@link Translatable->updateCMSFields()}).
21
		// $Lang serves as a "context" which can be inspected by Translatable - hence it
22
		// has the same name as the database property on Translatable.
23
		$id = $req->param('ID');
24
		if($req->requestVar("Locale")) {
25
			$this->owner->Locale = $req->requestVar("Locale");
26
		} else if($id && is_numeric($id)) {
27
			$record = DataObject::get_by_id($this->owner->stat('tree_class'), $id);
28
			if($record && $record->Locale) $this->owner->Locale = $record->Locale;
29
		} else {
30
			$this->owner->Locale = Translatable::default_locale();
31
			if ($this->owner->class == 'CMSPagesController') {
32
				// the CMSPagesController always needs to have the locale set,
33
				// otherwise page editing will cause an extra
34
				// ajax request which looks weird due to multiple "loading"-flashes
35
				$getVars = $req->getVars();
36
				if(isset($getVars['url'])) unset($getVars['url']);
37
				return $this->owner->redirect(Controller::join_links(
38
					$this->owner->Link(),
39
					$req->param('Action'),
40
					$req->param('ID'),
41
					$req->param('OtherID'),
42
					($query = http_build_query($getVars)) ? "?$query" : null
43
				));
44
			}
45
		}
46
		Translatable::set_current_locale($this->owner->Locale);
47
48
		// If a locale is set, it needs to match to the current record
49
		$requestLocale = $req->requestVar("Locale");
50
		$page = $this->owner->currentPage();
51
		if(
52
			$req->httpMethod() == 'GET' // leave form submissions alone
53
			&& $requestLocale
54
			&& $page
55
			&& $page->hasExtension('Translatable')
56
			&& $page->Locale != $requestLocale
57
			&& $req->latestParam('Action') != 'EditorToolbar'
58
		) {
59
			$transPage = $page->getTranslation($requestLocale);
60
			if($transPage) {
61
				Translatable::set_current_locale($transPage->Locale);
62
				return $this->owner->redirect(Controller::join_links(
63
					$this->owner->Link('show'),
64
					$transPage->ID
65
					// ?locale will automatically be added
66
				));
67
			} else if ($this->owner->class != 'CMSPagesController') {
68
				// If the record is not translated, redirect to pages overview
69
				return $this->owner->redirect(Controller::join_links(
70
					singleton('CMSPagesController')->Link(),
71
					'?Locale=' . $requestLocale
72
				));
73
			}
74
		}
75
76
		// collect languages for TinyMCE spellchecker plugin.
77
		// see http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
78
		$langName = i18n::get_locale_name($this->owner->Locale);
79
		HtmlEditorConfig::get('cms')->setOption(
80
			'spellchecker_languages',
81
			"+{$langName}={$this->owner->Locale}"
82
		);
83
84
		Requirements::javascript('translatable/javascript/CMSMain.Translatable.js');
85
		Requirements::css('translatable/css/CMSMain.Translatable.css');
86
	}
87
88
	function updateEditForm(&$form) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
89
		if($form->getName() == 'RootForm' && SiteConfig::has_extension("Translatable")) {
90
			$siteConfig = SiteConfig::current_site_config();
91
			$form->Fields()->push(new HiddenField('Locale','', $siteConfig->Locale));
92
		}
93
	}
94
95
	function updatePageOptions(&$fields) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
96
		$fields->push(new HiddenField("Locale", 'Locale', Translatable::get_current_locale()));
97
	}
98
99
	/**
100
	 * Create a new translation from an existing item, switch to this language and reload the tree.
101
	 */
102
	function createtranslation($data, $form) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
103
		$request = $this->owner->getRequest();
104
105
		// Protect against CSRF on destructive action
106
		if(!SecurityToken::inst()->checkRequest($request)) return $this->owner->httpError(400);
107
108
		$langCode = Convert::raw2sql($request->postVar('NewTransLang'));
109
		$record = $this->owner->getRecord($request->postVar('ID'));
110
		if(!$record) return $this->owner->httpError(404);
111
112
		$this->owner->Locale = $langCode;
113
		Translatable::set_current_locale($langCode);
114
115
		// Create a new record in the database - this is different
116
		// to the usual "create page" pattern of storing the record
117
		// in-memory until a "save" is performed by the user, mainly
118
		// to simplify things a bit.
119
		// @todo Allow in-memory creation of translations that don't
120
		// persist in the database before the user requests it
121
		$translatedRecord = $record->createTranslation($langCode);
122
123
		$url = Controller::join_links(
124
			$this->owner->Link('show'),
125
			$translatedRecord->ID
126
		);
127
128
		// set the X-Pjax header to Content, so that the whole admin panel will be refreshed
129
		$this->owner->getResponse()->addHeader('X-Pjax', 'Content');
130
131
		return $this->owner->redirect($url);
132
	}
133
134
	function updateLink(&$link) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
135
		$locale = $this->owner->Locale ? $this->owner->Locale : Translatable::get_current_locale();
136
		if($locale) $link = Controller::join_links($link, '?Locale=' . $locale);
137
	}
138
139
	function updateLinkWithSearch(&$link) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
140
		$locale = $this->owner->Locale ? $this->owner->Locale : Translatable::get_current_locale();
141
		if($locale) $link = Controller::join_links($link, '?Locale=' . $locale);
142
	}
143
144
	function updateExtraTreeTools(&$html) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
145
		$locale = $this->owner->Locale ? $this->owner->Locale : Translatable::get_current_locale();
0 ignored issues
show
Unused Code introduced by
$locale is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
146
		$html = $this->LangForm()->forTemplate() . $html;
147
	}
148
149
	function updateLinkPageAdd(&$link) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
150
		$locale = $this->owner->Locale ? $this->owner->Locale : Translatable::get_current_locale();
151
		if($locale) $link = Controller::join_links($link, '?Locale=' . $locale);
152
	}
153
154
	/**
155
	 * Returns a form with all languages with languages already used appearing first.
156
	 *
157
	 * @return Form
158
	 */
159
	function LangForm() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
160
		$member = Member::currentUser(); //check to see if the current user can switch langs or not
161
		if(Permission::checkMember($member, 'VIEW_LANGS')) {
162
			$field = new LanguageDropdownField(
163
				'Locale',
164
				_t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language'),
165
				array(),
166
				'SiteTree',
167
				'Locale-English',
168
				singleton('SiteTree')
169
			);
170
			$field->setValue(Translatable::get_current_locale());
171
		} else {
172
			// user doesn't have permission to switch langs
173
			// so just show a string displaying current language
174
			$field = new LiteralField(
175
				'Locale',
176
				i18n::get_locale_name( Translatable::get_current_locale())
177
			);
178
		}
179
180
		$form = new Form(
181
			$this->owner,
182
			'LangForm',
183
			new FieldList(
184
				$field
185
			),
186
			new FieldList(
187
				new FormAction('selectlang', _t('CMSMain_left.GO','Go'))
188
			)
189
		);
190
		$form->unsetValidator();
191
		$form->addExtraClass('nostyle');
192
193
		return $form;
194
	}
195
196
	function selectlang($data, $form) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
197
		return $this->owner;
198
	}
199
200
	/**
201
	 * Determine if there are more than one languages in our site tree.
202
	 *
203
	 * @return boolean
204
	 */
205
	function MultipleLanguages() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
206
		$langs = Translatable::get_existing_content_languages('SiteTree');
207
208
		return (count($langs) > 1);
209
	}
210
211
	/**
212
	 * @return boolean
213
	 */
214
	function IsTranslatableEnabled() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
215
		return SiteTree::has_extension('Translatable');
216
	}
217
218
	/**
219
	 * Injects the locale into a new page on creation.
220
	 *
221
	 * @param SiteTree $record
222
	 * @param Form $form
223
	 */
224
	public function updateDoAdd(SiteTree $record, Form $form) {
225
		$data = $form->getData();
226
		if(!isset($data['Locale'])) {
227
			$data['Locale'] = Translatable::get_current_locale();
228
		}
229
		$record->Locale = $data['Locale'];
230
	}
231
232
}
233