Completed
Push — master ( 8ff7a8...c0c536 )
by Stephen
77:04 queued 40:03
created

Twenty_Fourteen_Ephemera_Widget   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 277
Duplicated Lines 2.53 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 39
lcom 1
cbo 2
dl 7
loc 277
rs 8.2857
c 1
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 3
A enqueue_scripts() 0 10 2
F widget() 4 172 25
A update() 0 9 3
B form() 3 19 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Custom Widget for displaying specific post formats
4
 *
5
 * Displays posts from Aside, Quote, Video, Audio, Image, Gallery, and Link formats.
6
 *
7
 * @link https://codex.wordpress.org/Widgets_API#Developing_Widgets
8
 *
9
 * @package WordPress
10
 * @subpackage Twenty_Fourteen
11
 * @since Twenty Fourteen 1.0
12
 */
13
14
class Twenty_Fourteen_Ephemera_Widget extends WP_Widget {
15
16
	/**
17
	 * The supported post formats.
18
	 *
19
	 * @access private
20
	 * @since Twenty Fourteen 1.0
21
	 *
22
	 * @var array
23
	 */
24
	private $formats = array( 'aside', 'image', 'video', 'audio', 'quote', 'link', 'gallery' );
25
26
	/**
27
	 * Constructor.
28
	 *
29
	 * @since Twenty Fourteen 1.0
30
	 *
31
	 * @return Twenty_Fourteen_Ephemera_Widget
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
32
	 */
33
	public function __construct() {
34
		parent::__construct( 'widget_twentyfourteen_ephemera', __( 'Twenty Fourteen Ephemera', 'twentyfourteen' ), array(
35
			'classname'   => 'widget_twentyfourteen_ephemera',
36
			'description' => __( 'Use this widget to list your recent Aside, Quote, Video, Audio, Image, Gallery, and Link posts.', 'twentyfourteen' ),
37
			'customize_selective_refresh' => true,
38
		) );
39
40
		if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
41
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
42
		}
43
	}
44
45
	/**
46
	 * Enqueue scripts.
47
	 *
48
	 * @since Twenty Fourteen 1.7
49
	 */
50
	public function enqueue_scripts() {
51
		/** This filter is documented in wp-includes/media.php */
52
		$audio_library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
53
		/** This filter is documented in wp-includes/media.php */
54
		$video_library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
55
		if ( in_array( 'mediaelement', array( $video_library, $audio_library ), true ) ) {
56
			wp_enqueue_style( 'wp-mediaelement' );
57
			wp_enqueue_script( 'wp-mediaelement' );
58
		}
59
	}
60
61
	/**
62
	 * Output the HTML for this widget.
63
	 *
64
	 * @access public
65
	 * @since Twenty Fourteen 1.0
66
	 *
67
	 * @param array $args     An array of standard parameters for widgets in this theme.
68
	 * @param array $instance An array of settings for this widget instance.
69
	 */
70
	public function widget( $args, $instance ) {
71
		$format = isset( $instance['format'] ) && in_array( $instance['format'], $this->formats ) ? $instance['format'] : 'aside';
72
73
		switch ( $format ) {
74
			case 'image':
75
				$format_string      = __( 'Images', 'twentyfourteen' );
76
				$format_string_more = __( 'More images', 'twentyfourteen' );
77
				break;
78
			case 'video':
79
				$format_string      = __( 'Videos', 'twentyfourteen' );
80
				$format_string_more = __( 'More videos', 'twentyfourteen' );
81
				break;
82
			case 'audio':
83
				$format_string      = __( 'Audio', 'twentyfourteen' );
84
				$format_string_more = __( 'More audio', 'twentyfourteen' );
85
				break;
86
			case 'quote':
87
				$format_string      = __( 'Quotes', 'twentyfourteen' );
88
				$format_string_more = __( 'More quotes', 'twentyfourteen' );
89
				break;
90
			case 'link':
91
				$format_string      = __( 'Links', 'twentyfourteen' );
92
				$format_string_more = __( 'More links', 'twentyfourteen' );
93
				break;
94
			case 'gallery':
95
				$format_string      = __( 'Galleries', 'twentyfourteen' );
96
				$format_string_more = __( 'More galleries', 'twentyfourteen' );
97
				break;
98
			case 'aside':
99
			default:
100
				$format_string      = __( 'Asides', 'twentyfourteen' );
101
				$format_string_more = __( 'More asides', 'twentyfourteen' );
102
				break;
103
		}
104
105
		$number = empty( $instance['number'] ) ? 2 : absint( $instance['number'] );
106
		$title  = apply_filters( 'widget_title', empty( $instance['title'] ) ? $format_string : $instance['title'], $instance, $this->id_base );
107
108
		$ephemera = new WP_Query( array(
109
			'order'          => 'DESC',
110
			'posts_per_page' => $number,
111
			'no_found_rows'  => true,
112
			'post_status'    => 'publish',
113
			'post__not_in'   => get_option( 'sticky_posts' ),
114
			'tax_query'      => array(
115
				array(
116
					'taxonomy' => 'post_format',
117
					'terms'    => array( "post-format-$format" ),
118
					'field'    => 'slug',
119
					'operator' => 'IN',
120
				),
121
			),
122
		) );
123
124
		if ( $ephemera->have_posts() ) :
125
			$tmp_content_width = $GLOBALS['content_width'];
126
			$GLOBALS['content_width'] = 306;
127
128
			echo $args['before_widget'];
129
			?>
130
			<h1 class="widget-title <?php echo esc_attr( $format ); ?>">
131
				<a class="entry-format" href="<?php echo esc_url( get_post_format_link( $format ) ); ?>"><?php echo esc_html( $title ); ?></a>
132
			</h1>
133
			<ol>
134
135
				<?php
136
					while ( $ephemera->have_posts() ) :
137
						$ephemera->the_post();
138
						$tmp_more = $GLOBALS['more'];
139
						$GLOBALS['more'] = 0;
140
				?>
141
				<li>
142
				<article <?php post_class(); ?>>
143
					<div class="entry-content">
144
						<?php
145
							if ( has_post_format( 'gallery' ) ) :
146
147
								if ( post_password_required() ) :
148
									the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ) );
149
								else :
150
									$images = array();
151
152
									$galleries = get_post_galleries( get_the_ID(), false );
0 ignored issues
show
Security Bug introduced by
It seems like get_the_ID() can also be of type false; however, get_post_galleries() does only seem to accept integer|object<WP_Post>, did you maybe forget to handle an error condition?
Loading history...
153
									if ( isset( $galleries[0]['ids'] ) )
154
										$images = explode( ',', $galleries[0]['ids'] );
155
156
									if ( ! $images ) :
0 ignored issues
show
Bug Best Practice introduced by
The expression $images of type array 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...
157
										$images = get_posts( array(
158
											'fields'         => 'ids',
159
											'numberposts'    => -1,
160
											'order'          => 'ASC',
161
											'orderby'        => 'menu_order',
162
											'post_mime_type' => 'image',
163
											'post_parent'    => get_the_ID(),
164
											'post_type'      => 'attachment',
165
										) );
166
									endif;
167
168
									$total_images = count( $images );
169
170
									if ( has_post_thumbnail() ) :
171
										$post_thumbnail = get_the_post_thumbnail();
172
									elseif ( $total_images > 0 ) :
173
										$image          = reset( $images );
174
										$post_thumbnail = wp_get_attachment_image( $image, 'post-thumbnail' );
175
									endif;
176
177
									if ( ! empty ( $post_thumbnail ) ) :
178
						?>
179
						<a href="<?php the_permalink(); ?>"><?php echo $post_thumbnail; ?></a>
180
						<?php endif; ?>
181
						<p class="wp-caption-text">
182
							<?php
183
								printf( _n( 'This gallery contains <a href="%1$s" rel="bookmark">%2$s photo</a>.', 'This gallery contains <a href="%1$s" rel="bookmark">%2$s photos</a>.', $total_images, 'twentyfourteen' ),
184
									esc_url( get_permalink() ),
0 ignored issues
show
Security Bug introduced by
It seems like get_permalink() can also be of type false; however, esc_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
185
									number_format_i18n( $total_images )
186
								);
187
							?>
188
						</p>
189
						<?php
190
								endif;
191
192
							else :
193
								the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ) );
194
							endif;
195
						?>
196
					</div><!-- .entry-content -->
197
198
					<header class="entry-header">
199
						<div class="entry-meta">
200
							<?php
201
								if ( ! has_post_format( 'link' ) ) :
202
									the_title( '<h1 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h1>' );
0 ignored issues
show
Security Bug introduced by
It seems like get_permalink() can also be of type false; however, esc_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
203
								endif;
204
205
								printf( '<span class="entry-date"><a href="%1$s" rel="bookmark"><time class="entry-date" datetime="%2$s">%3$s</time></a></span> <span class="byline"><span class="author vcard"><a class="url fn n" href="%4$s" rel="author">%5$s</a></span></span>',
206
									esc_url( get_permalink() ),
0 ignored issues
show
Security Bug introduced by
It seems like get_permalink() can also be of type false; however, esc_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
207
									esc_attr( get_the_date( 'c' ) ),
208
									esc_html( get_the_date() ),
0 ignored issues
show
Security Bug introduced by
It seems like get_the_date() can also be of type false; however, esc_html() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
209
									esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
210
									get_the_author()
211
								);
212
213 View Code Duplication
								if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) :
214
							?>
215
							<span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'twentyfourteen' ), __( '1 Comment', 'twentyfourteen' ), __( '% Comments', 'twentyfourteen' ) ); ?></span>
216
							<?php endif; ?>
217
						</div><!-- .entry-meta -->
218
					</header><!-- .entry-header -->
219
				</article><!-- #post-## -->
220
				</li>
221
				<?php endwhile; ?>
222
223
			</ol>
224
			<a class="post-format-archive-link" href="<?php echo esc_url( get_post_format_link( $format ) ); ?>">
225
				<?php
226
					/* translators: used with More archives link */
227
					printf( __( '%s <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ), $format_string_more );
228
				?>
229
			</a>
230
			<?php
231
232
			echo $args['after_widget'];
233
234
			// Reset the post globals as this query will have stomped on it.
235
			wp_reset_postdata();
236
237
			$GLOBALS['more']          = $tmp_more;
0 ignored issues
show
Bug introduced by
The variable $tmp_more 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...
238
			$GLOBALS['content_width'] = $tmp_content_width;
239
240
		endif; // End check for ephemeral posts.
241
	}
242
243
	/**
244
	 * Deal with the settings when they are saved by the admin.
245
	 *
246
	 * Here is where any validation should happen.
247
	 *
248
	 * @since Twenty Fourteen 1.0
249
	 *
250
	 * @param array $new_instance New widget instance.
251
	 * @param array $instance     Original widget instance.
252
	 * @return array Updated widget instance.
253
	 */
254
	function update( $new_instance, $instance ) {
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...
255
		$instance['title']  = strip_tags( $new_instance['title'] );
256
		$instance['number'] = empty( $new_instance['number'] ) ? 2 : absint( $new_instance['number'] );
257
		if ( in_array( $new_instance['format'], $this->formats ) ) {
258
			$instance['format'] = $new_instance['format'];
259
		}
260
261
		return $instance;
262
	}
263
264
	/**
265
	 * Display the form for this widget on the Widgets page of the Admin area.
266
	 *
267
	 * @since Twenty Fourteen 1.0
268
	 *
269
	 * @param array $instance
270
	 */
271
	function form( $instance ) {
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...
272
		$title  = empty( $instance['title'] ) ? '' : esc_attr( $instance['title'] );
273
		$number = empty( $instance['number'] ) ? 2 : absint( $instance['number'] );
274
		$format = isset( $instance['format'] ) && in_array( $instance['format'], $this->formats ) ? $instance['format'] : 'aside';
275
		?>
276
			<p><label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:', 'twentyfourteen' ); ?></label>
277
			<input id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"></p>
278
279
			<p><label for="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>"><?php _e( 'Number of posts to show:', 'twentyfourteen' ); ?></label>
280
			<input id="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'number' ) ); ?>" type="text" value="<?php echo esc_attr( $number ); ?>" size="3"></p>
281
282
			<p><label for="<?php echo esc_attr( $this->get_field_id( 'format' ) ); ?>"><?php _e( 'Post format to show:', 'twentyfourteen' ); ?></label>
283
			<select id="<?php echo esc_attr( $this->get_field_id( 'format' ) ); ?>" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'format' ) ); ?>">
284 View Code Duplication
				<?php foreach ( $this->formats as $slug ) : ?>
285
				<option value="<?php echo esc_attr( $slug ); ?>"<?php selected( $format, $slug ); ?>><?php echo esc_html( get_post_format_string( $slug ) ); ?></option>
286
				<?php endforeach; ?>
287
			</select>
288
		<?php
289
	}
290
}
291