Completed
Push — master ( ee928d...1fc1bc )
by Dennis
02:34
created

MslsOutput::get_alternate_links()   B

Complexity

Conditions 9
Paths 20

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 20
nop 0
dl 0
loc 59
rs 7.3389
c 0
b 0
f 0

How to fix   Long Method   

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
 * MslsOutput
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
namespace lloc\Msls;
9
10
/**
11
 * Output in the frontend
12
 * @package Msls
13
 */
14
class MslsOutput extends MslsMain {
15
16
	/**
17
	 * Holds the format for the output
18
	 * @var array $tags
19
	 */
20
	protected $tags;
21
22
	/**
23
	 * Creates and gets the output as an array
24
	 *
25
	 * @param int $display
26
	 * @param bool $filter
27
	 * @param bool $exists
28
	 *
29
	 * @uses MslsOptions
30
	 * @uses MslsLink
31
	 * @return array
32
	 */
33
	public function get( $display, $filter = false, $exists = false ) {
34
		$arr = [];
35
36
		$blogs = $this->collection->get_filtered( $filter );
37
		if ( $blogs ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $blogs of type lloc\Msls\MslsBlog[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
38
			$mydata = MslsOptions::create();
39
			$link   = MslsLink::create( $display );
40
41
			foreach ( $blogs as $blog ) {
42
				$language = $blog->get_language();
43
44
				$link->src = $this->options->get_flag_url( $language );
45
				$link->alt = $language;
46
47
				$is_current_blog = $this->collection->is_current_blog( $blog );
48
				if ( $is_current_blog ) {
49
					$url       = $mydata->get_current_link();
50
					$link->txt = $blog->get_description();
51
				} else {
52
					switch_to_blog( $blog->userblog_id );
0 ignored issues
show
introduced by
switch_to_blog is not something you should ever need to do in a VIP theme context. Instead use an API (XML-RPC, REST) to interact with other sites if needed.
Loading history...
53
54
					if ( $this->is_requirements_not_fulfilled( $mydata, $exists, $language ) ) {
55
						restore_current_blog();
56
						continue;
57
					} else {
58
						$url       = $mydata->get_permalink( $language );
59
						$link->txt = $blog->get_description();
60
					}
61
62
					restore_current_blog();
63
				}
64
65
				if ( has_filter( 'msls_output_get' ) ) {
66
					/**
67
					 * Returns HTML-link for an item of the output-arr
68
					 * @since 0.9.8
69
					 *
70
					 * @param string $url
71
					 * @param MslsLink $link
72
					 * @param bool $is_current_blog
73
					 */
74
					$arr[] = ( string ) apply_filters( 'msls_output_get', $url, $link, $is_current_blog );
0 ignored issues
show
introduced by
Cast statements must not contain whitespace; expected "(string)" but found "( string )"
Loading history...
75
				} else {
76
					$arr[] = sprintf(
77
						'<a href="%s" title="%s"%s>%s</a>',
78
						$url,
79
						$link->txt,
80
						$is_current_blog ? ' class="current_language"' : '',
81
						$link
82
					);
83
				}
84
			}
85
		}
86
87
		return $arr;
88
	}
89
90
	/**
91
	 * @return string
92
	 */
93
    public function get_alternate_links() {
94
		$blogs  = MslsBlogCollection::instance();
95
		$mydata = MslsOptions::create();
96
97
		foreach ( $blogs->get_objects() as $blog ) {
98
			$language = $blog->get_language();
99
			$url      = $mydata->get_current_link();
100
			$current  = ( $blog->userblog_id == MslsBlogCollection::instance()->get_current_blog_id() );
101
			$title    = $blog->get_description();
102
103
			if ( ! $current ) {
104
				switch_to_blog( $blog->userblog_id );
0 ignored issues
show
introduced by
switch_to_blog is not something you should ever need to do in a VIP theme context. Instead use an API (XML-RPC, REST) to interact with other sites if needed.
Loading history...
105
106
				if ( 'MslsOptions' != get_class( $mydata ) && ( is_null( $mydata ) || ! $mydata->has_value( $language ) ) ) {
107
					restore_current_blog();
108
					continue;
109
				}
110
111
				$url   = $mydata->get_permalink( $language );
112
				$title = $blog->get_description();
113
114
				restore_current_blog();
115
			}
116
117
			if ( has_filter( 'msls_head_hreflang' ) ) {
118
				/**
119
				 * Overrides the hreflang value
120
				 * @since 0.9.9
121
				 * @param string $language
122
				 */
123
				$hreflang = (string) apply_filters( 'msls_head_hreflang', $language );
124
			}
125
			else {
126
				$hreflang = $blog->get_alpha2();
127
			}
128
129
			if ( ! isset( $default ) ) {
130
				$default = sprintf(
131
					'<link rel="alternate" hreflang="x-default" href="%s" title="%s" />',
132
					$url,
133
					esc_attr( $title )
134
				);
135
			}
136
137
			$arr[] = sprintf(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
138
				'<link rel="alternate" hreflang="%s" href="%s" title="%s" />',
139
				$hreflang,
140
				$url,
141
				esc_attr( $title )
142
			);
143
		}
144
145
		if ( 1 === count( $arr ) ) {
146
			return $default;
0 ignored issues
show
Bug introduced by
The variable $default does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
147
		}
148
		else {
149
			return implode( PHP_EOL, $arr );
0 ignored issues
show
Bug introduced by
The variable $arr does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
150
		}
151
	}
152
153
	/**
154
	 * Returns a string when the object will be treated like a string
155
	 * @return string
156
	 */
157
	public function __toString() {
158
		$display = (int) $this->options->display;
159
		$filter  = false;
160
		$exists  = isset( $this->options->only_with_translation );
161
162
		$arr = $this->get( $display, $filter, $exists );
163
		if ( empty( $arr ) ) {
164
			return '';
165
		}
166
167
		$tags = $this->get_tags();
168
169
		return $tags['before_output'] . $tags['before_item'] .
170
		       implode( $tags['after_item'] . $tags['before_item'], $arr ) .
171
		       $tags['after_item'] . $tags['after_output'];
172
	}
173
174
	/**
175
	 * Gets tags for the output
176
	 * @return array
177
	 */
178
	public function get_tags() {
179
		if ( empty( $this->tags ) ) {
180
			$this->tags = array(
181
				'before_item'   => $this->options->before_item,
182
				'after_item'    => $this->options->after_item,
183
				'before_output' => $this->options->before_output,
184
				'after_output'  => $this->options->after_output,
185
			);
186
187
			/**
188
			 * Returns tags array for the output
189
			 * @since 1.0
190
			 *
191
			 * @param array $tags
192
			 */
193
			$this->tags = ( array ) apply_filters( 'msls_output_get_tags', $this->tags );
0 ignored issues
show
introduced by
Cast statements must not contain whitespace; expected "(array)" but found "( array )"
Loading history...
194
		}
195
196
		return $this->tags;
197
	}
198
199
	/**
200
	 * Sets tags for the output
201
	 *
202
	 * @param array $arr
203
	 *
204
	 * @return MslsOutput
205
	 */
206
	public function set_tags( array $arr = [] ) {
207
		$this->tags = wp_parse_args( $this->get_tags(), $arr );
208
209
		return $this;
210
	}
211
212
	/**
213
	 * Returns true if the requirements not fulfilled
214
	 *
215
	 * @param MslsOptions|null $thing
216
	 * @param boolean $exists
217
	 * @param string $language
218
	 *
219
	 * @return boolean
220
	 */
221
	public function is_requirements_not_fulfilled( $thing, $exists, $language ) {
222
		if ( is_null( $thing ) ) {
223
			return $exists;
224
		}
225
226
		return MslsOptions::class != get_class( $thing ) && ! $thing->has_value( $language ) && $exists;
227
	}
228
229
}
230