Completed
Push — master ( ea28d3...1760c1 )
by Dennis
04:45
created

MslsPostTag::set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * MslsPostTag
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
namespace lloc\Msls;
9
10
/**
11
 * Post Tag
12
 * @package Msls
13
 */
14
class MslsPostTag extends MslsMain {
15
16
	/**
17
	 * Suggest
18
	 *
19
	 * Echo a JSON-ified array of posts of the given post-type and
20
	 * the requested search-term and then die silently
21
	 */
22
	public static function suggest() {
23
		$json = new MslsJson;
24
25
		if ( filter_has_var( INPUT_POST, 'blog_id' ) ) {
26
			switch_to_blog(
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...
27
				filter_input( INPUT_POST, 'blog_id', FILTER_SANITIZE_NUMBER_INT )
28
			);
29
30
			$args = array(
31
				'orderby'    => 'name',
32
				'order'      => 'ASC',
33
				'number'     => 10,
34
				'hide_empty' => 0,
35
			);
36
37
			if ( filter_has_var( INPUT_POST, 's' ) ) {
38
				$args['s'] = sanitize_text_field(
39
					filter_input( INPUT_POST, 's' )
40
				);
41
			}
42
43
			/**
44
			 * Overrides the query-args for the suggest fields
45
			 * @since 0.9.9
46
			 * @param array $args
47
			 */
48
			$args = (array) apply_filters( 'msls_post_tag_suggest_args', $args );
49
50
			foreach ( get_terms( sanitize_text_field( filter_input( INPUT_POST, 'post_type' ) ), $args ) as $term ) {
51
52
				/**
53
				 * Manipulates the term object before using it
54
				 * @since 0.9.9
55
				 * @param \StdClass $term
56
				 */
57
				$term = apply_filters( 'msls_post_tag_suggest_term', $term );
58
59
				if ( is_object( $term ) ) {
60
					$json->add( $term->term_id, $term->name );
61
				}
62
			}
63
			restore_current_blog();
64
		}
65
		wp_die( $json->encode() );
66
	}
67
68
	/**
69
	 * Init
70
	 *
71
	 * @codeCoverageIgnore
72
	 *
73
	 * @return MslsPostTag
74
	 */
75
	public static function init() {
76
		$options    = MslsOptions::instance();
77
		$collection = MslsBlogCollection::instance();
78
79
		if ( $options->activate_autocomplete	) {
80
			$obj = new static( $options, $collection );
81
		}
82
		else {
83
			$obj = MslsPostTagClassic::init();
84
		}
85
86
		$taxonomy = MslsContentTypes::create()->acl_request();
87
		if ( '' != $taxonomy ) {
88
			add_action( "{$taxonomy}_add_form_fields",  [ $obj, 'add_input' ] );
89
			add_action( "{$taxonomy}_edit_form_fields", [ $obj, 'edit_input' ] );
90
			add_action( "edited_{$taxonomy}", [ $obj, 'set' ] );
91
			add_action( "create_{$taxonomy}", [ $obj, 'set' ] );
92
		}
93
94
		return $obj;
95
	}
96
97
	/**
98
	 * Add the input fields to the add-screen of the taxonomies
99
	 *
100
	 * @param \StdClass $tag
101
	 */
102
	public function add_input( $tag ) {
103
		$title_format = '<h3>%s</h3>
104
			<input type="hidden" name="msls_post_type" id="msls_post_type" value="%s"/>
105
			<input type="hidden" name="msls_action" id="msls_action" type="text" value="suggest_terms"/>';
106
107
		$item_format = '<label for="msls_title_%1$s">%2$s</label>
108
			<input type="hidden" id="msls_id_%1$s" name="msls_input_%3$s" value="%4$s"/>
109
			<input class="msls_title" id="msls_title_%1$s" name="msls_title_%1$s" type="text" value="%5$s"/>';
110
111
		echo '<div class="form-field">';
112
		$this->the_input( $tag, $title_format, $item_format );
113
		echo '</div>';
114
	}
115
116
	/**
117
	 * Add the input fields to the edit-screen of the taxonomies
118
	 * @param \StdClass $tag
119
	 */
120
	public function edit_input( $tag ) {
121
		$title_format = '<tr>
122
			<th colspan="2">
123
			<strong>%s</strong>
124
			<input type="hidden" name="msls_post_type" id="msls_post_type" value="%s"/>
125
			<input type="hidden" name="msls_action" id="msls_action" type="text" value="suggest_terms"/>
126
			</th>
127
			</tr>';
128
129
		$item_format = '<tr class="form-field">
130
			<th scope="row" valign="top">
131
			<label for="msls_title_%1$s">%2$s</label>
132
			</th>
133
			<td>
134
			<input type="hidden" id="msls_id_%1$s" name="msls_input_%3$s" value="%4$s"/>
135
			<input class="msls_title" id="msls_title_%1$s" name="msls_title_%1$s" type="text" value="%5$s"/>
136
			</td>
137
			</tr>';
138
139
		$this->the_input( $tag, $title_format, $item_format );
140
	}
141
142
	/**
143
	 * Print the input fields
144
	 * Returns true if the blogcollection is not empty
145
	 * @param \StdClass $tag
146
	 * @param string $title_format
147
	 * @param string $item_format
148
	 * @return boolean
149
	 */
150
	public function the_input( $tag, $title_format, $item_format ) {
151
		$term_id = ( is_object( $tag ) ? $tag->term_id : 0 );
152
		$blogs   = $this->collection->get();
153
		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...
154
			$my_data = MslsOptionsTax::create( $term_id );
155
156
			$this->maybe_set_linked_term( $my_data );
157
158
			$type    = MslsContentTypes::create()->get_request();
159
160
			printf(
161
				$title_format,
162
				__( 'Multisite Language Switcher', 'multisite-language-switcher' ),
163
				$type
164
			);
165
			foreach ( $blogs as $blog ) {
166
				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...
167
168
				$language = $blog->get_language();
169
				$flag_url = $this->options->get_flag_url( $language );
170
				$icon     = MslsAdminIcon::create()->set_language( $language )->set_src( $flag_url );
171
172
				$value = $title = '';
173
				if ( $my_data->has_value( $language ) ) {
174
					$term = get_term( $my_data->$language, $type );
175
					if ( is_object( $term ) ) {
176
						$icon->set_href( $my_data->$language );
177
						$value = $my_data->$language;
178
						$title = $term->name;
179
					}
180
				}
181
182
				printf(
183
					$item_format,
184
					$blog->userblog_id,
185
					$icon,
186
					$language,
187
					$value,
188
					$title
189
				);
190
				restore_current_blog();
191
			}
192
			return true;
193
		}
194
		return false;
195
	}
196
197
	/**
198
	 * Set calls the save method if taxonomy is set
199
	 * @param int $term_id
200
 	 * @codeCoverageIgnore
201
	 */
202
	public function set( $term_id ) {
203
		if ( MslsContentTypes::create()->acl_request() ) {
204
			$this->save( $term_id, MslsOptionsTax::class );
205
		}
206
	}
207
208
	/**
209
	 * Sets the selected element in the data from the `$_GET` superglobal, if any.
210
	 *
211
	 * @param MslsOptionsTax $mydata
212
	 *
213
	 * @return MslsOptionsTax
214
	 */
215
	public function maybe_set_linked_term( MslsOptionsTax $mydata ) {
0 ignored issues
show
Coding Style introduced by
maybe_set_linked_term uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
216
		if ( ! isset( $_GET['msls_id'], $_GET['msls_lang'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
217
			return $mydata;
218
		}
219
220
		$origin_lang = trim( $_GET['msls_lang'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
221
222
		if ( isset( $mydata->{$origin_lang} ) ) {
223
			return $mydata;
224
		}
225
226
		$origin_term_id = (int) $_GET['msls_id'];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
227
228
		$origin_blog_id = $this->collection->get_blog_id( $origin_lang );
229
230
		if ( null === $origin_blog_id ) {
231
			return $mydata;
232
		}
233
234
		switch_to_blog( $origin_blog_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...
235
		$origin_term = get_term( $origin_term_id, $mydata->base );
0 ignored issues
show
Documentation introduced by
The property base does not exist on object<lloc\Msls\MslsOptionsTax>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
236
		restore_current_blog();
237
238
		if ( ! $origin_term instanceof \WP_Term ) {
0 ignored issues
show
Bug introduced by
The class WP_Term does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
239
			return $mydata;
240
		}
241
242
		$mydata->{$origin_lang} = $origin_term_id;
243
244
		return $mydata;
245
	}
246
247
}
248