Completed
Push — master ( 33d925...cc7944 )
by Thomas
09:52
created

Profile::getPanel()   C

Complexity

Conditions 12
Paths 20

Size

Total Lines 70
Code Lines 49

Duplication

Lines 8
Ratio 11.43 %

Importance

Changes 0
Metric Value
cc 12
eloc 49
c 0
b 0
f 0
nc 20
nop 0
dl 8
loc 70
rs 5.6441

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @author Tom Needham <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2016, ownCloud GmbH.
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OC\Settings\Panels\Personal;
23
24
use OCP\Settings\ISettings;
25
use OCP\Template;
26
use OCP\IUser;
27
use OCP\IGroupManager;
28
use OCP\IUserSession;
29
use OCP\IConfig;
30
use OC\Settings\Panels\Helper;
31
use OCP\L10N\IFactory;
32
33
class Profile implements ISettings {
34
35
	/* @var IConfig */
36
	protected $config;
37
	/* @var IGroupManager */
38
	protected $groupManager;
39
	/* @var IUserSession */
40
	protected $userSession;
41
	/** @var Helper */
42
	protected $helper;
43
	/** @var IFactory */
44
	protected $lfactory;
45
46
	public function __construct(IConfig $config,
47
								IGroupManager $groupManager,
48
								IUserSession $userSession,
49
								Helper $helper,
50
								IFactory $lfactory) {
51
		$this->config = $config;
52
		$this->groupManager = $groupManager;
53
		$this->userSession = $userSession;
54
		$this->helper = $helper;
55
		$this->lfactory = $lfactory;
56
	}
57
58
	public function getPriority() {
59
		return 100;
60
	}
61
62
	public function getPanel() {
63
		$tmpl = new Template('settings', 'panels/personal/profile');
64
		// Assign some data
65
		$lang = $this->lfactory->findLanguage();
66
		$userLang = $this->config->getUserValue( $this->userSession->getUser(), 'core', 'lang', $lang);
0 ignored issues
show
Documentation introduced by
$this->userSession->getUser() is of type object<OCP\IUser>|null, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
67
		$languageCodes = $this->lfactory->findAvailableLanguages();
68
		// array of common languages
69
		$commonLangCodes = [
70
			'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
71
		];
72
		$languageNames = $this->helper->getLanguageCodes();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $languageNames is correct as $this->helper->getLanguageCodes() (which targets OC\Settings\Panels\Helper::getLanguageCodes()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
73
		$languages= [];
74
		$commonLanguages = [];
75
		foreach($languageCodes as $lang) {
76
			$l = $this->lfactory->get('settings', $lang);
77
			// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
78
			$potentialName = (string) $l->t('__language_name__');
79
			if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
80
				$ln = ['code'=>$lang, 'name'=> $potentialName];
81
			} elseif (isset($languageNames[$lang])) {
82
				$ln = ['code'=>$lang, 'name'=>$languageNames[$lang]];
83
			} else {//fallback to language code
84
				$ln = ['code'=>$lang, 'name'=>$lang];
85
			}
86
			// put appropriate languages into appropriate arrays, to print them sorted
87
			// used language -> common languages -> divider -> other languages
88
			if ($lang === $userLang) {
89
				$userLang = $ln;
90
			} elseif (in_array($lang, $commonLangCodes)) {
91
				$commonLanguages[array_search($lang, $commonLangCodes)]=$ln;
92
			} else {
93
				$languages[]=$ln;
94
			}
95
		}
96
		// if user language is not available but set somehow: show the actual code as name
97
		if (!is_array($userLang)) {
98
			$userLang = [
99
				'code' => $userLang,
100
				'name' => $userLang,
101
			];
102
		}
103
		ksort($commonLanguages);
104
		// sort now by displayed language not the iso-code
105
		usort( $languages, function ($a, $b) {
106 View Code Duplication
			if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
				// If a doesn't have a name, but b does, list b before a
108
				return 1;
109
			}
110 View Code Duplication
			if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
				// If a does have a name, but b doesn't, list a before b
112
				return -1;
113
			}
114
			// Otherwise compare the names
115
			return strcmp($a['name'], $b['name']);
116
		});
117
118
		$tmpl->assign('email', $this->userSession->getUser()->getEMailAddress());
119
		$tmpl->assign('languages', $languages);
120
		$tmpl->assign('commonlanguages', $commonLanguages);
121
		$tmpl->assign('activelanguage', $userLang);
122
		$tmpl->assign('displayName', $this->userSession->getUser()->getDisplayName());
123
		$tmpl->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true) === true);
124
		$tmpl->assign('avatarChangeSupported', $this->userSession->getUser()->canChangeAvatar());
125
		$tmpl->assign('displayNameChangeSupported', $this->userSession->getUser()->canChangeDisplayName());
126
		$tmpl->assign('passwordChangeSupported', $this->userSession->getUser()->canChangePassword());
127
		$groups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
0 ignored issues
show
Bug introduced by
It seems like $this->userSession->getUser() can be null; however, getUserGroupIds() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
128
		sort($groups);
129
		$tmpl->assign('groups', $groups);
130
		return $tmpl;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $tmpl; (OCP\Template) is incompatible with the return type declared by the interface OCP\Settings\ISettings::getPanel of type OCP\AppFramework\Http\TemplateResponse.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
131
	}
132
133
	public function getSectionID() {
134
		return 'general';
135
	}
136
137
}
138