Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
WordAds_Sidebar_Widget
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 6
462
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 hide_widget_in_block_editor
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 widget
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
72
 get_widget_snippet
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
30
 form
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
 update
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Widget for adding ads to a sidebar.
4 *
5 * @package automattic/jetpack
6 */
7
8if ( ! defined( 'ABSPATH' ) ) {
9    exit( 0 );
10}
11
12/**
13 * Widget for inserting an ad into your sidebar
14 *
15 * @since 4.5.0
16 */
17class WordAds_Sidebar_Widget extends WP_Widget {
18
19    /**
20     * Allowed tags.
21     *
22     * @var string[]
23     */
24    private static $allowed_tags = array( 'mrec', 'wideskyscraper', 'leaderboard' );
25
26    /**
27     * Mapping array of widget sizes with the WordAds_Smart formats.
28     *
29     * @var string[]
30     */
31    private static $sizes_x_smart_format = array(
32        '300x250' => 'sidebar_widget_mediumrectangle',
33        '728x90'  => 'sidebar_widget_leaderboard',
34        '160x600' => 'sidebar_widget_wideskyscraper',
35    );
36
37    /**
38     * Number of widgets.
39     *
40     * @var int
41     */
42    private static $num_widgets = 0;
43
44    /**
45     * WordAds_Sidebar_Widget constructor.
46     */
47    public function __construct() {
48        parent::__construct(
49            'wordads_sidebar_widget',
50            /** This filter is documented in modules/widgets/facebook-likebox.php */
51            apply_filters( 'jetpack_widget_name', 'Ads' ),
52            array(
53                'description'                 => __( 'Insert an ad unit wherever you can place a widget.', 'jetpack' ),
54                'customize_selective_refresh' => true,
55            )
56        );
57
58        add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_widget_in_block_editor' ) );
59    }
60
61    /**
62     * Remove the Ad widget from the Legacy Widget block
63     *
64     * @param array $widget_types List of widgets that are currently removed from the Legacy Widget block.
65     *
66     * @return array $widget_types New list of widgets that will be removed.
67     */
68    public function hide_widget_in_block_editor( $widget_types ) {
69        $widget_types[] = 'wordads_sidebar_widget';
70        return $widget_types;
71    }
72
73    /**
74     * The Widget outputter.
75     *
76     * @param array $args Widget args.
77     * @param array $instance The Widget instance.
78     *
79     * @return bool|void
80     */
81    public function widget( $args, $instance ) {
82        global $wordads;
83        if ( $wordads->should_bail() ) {
84            return false;
85        }
86
87        if ( ! isset( $instance['unit'] ) ) {
88            $instance['unit'] = 'mrec';
89        }
90
91        ++self::$num_widgets;
92        $width      = WordAds::$ad_tag_ids[ $instance['unit'] ]['width'];
93        $height     = WordAds::$ad_tag_ids[ $instance['unit'] ]['height'];
94        $unit_id    = 1 === self::$num_widgets ? 3 : self::$num_widgets + 3; // 2nd belowpost is '4'
95        $section_id = 0 === $wordads->params->blog_id ?
96            WORDADS_API_TEST_ID :
97            $wordads->params->blog_id . $unit_id;
98
99        $smart_format = self::$sizes_x_smart_format[ "{$width}x{$height}" ];
100        // phpcs:disable WordPress.Security.NonceVerification.Recommended
101        $is_watl_enabled = isset( $_GET['wordads-logging'] ) && isset( $_GET[ $smart_format ] ) && 'true' === $_GET[ $smart_format ];
102
103        // Get the widget snippet.
104        $widget_snippet = $this->get_widget_snippet( $instance, $section_id, $height, $width );
105
106        // Render the IPW or house ad if WATL is disabled.
107        if ( ! $is_watl_enabled ) {
108            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
109            echo $widget_snippet;
110            return;
111        }
112
113        // Remove linebreaks and sanitize.
114        $tag = esc_js( str_replace( array( "\n", "\t", "\r" ), '', $widget_snippet ) );
115
116        // Add the fallback to be processed by WATL.
117        $fallback_snippet = <<<HTML
118        <script type="text/javascript">
119            var sas_fallback = sas_fallback || [];
120            sas_fallback.push(
121                { tag: "$tag", type: '$smart_format' }
122            );
123        </script>
124HTML;
125
126            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
127            echo $fallback_snippet . $wordads::get_watl_ad_html_tag( $smart_format );
128    }
129
130    /**
131     * The widget snippet.
132     *
133     * @param array  $instance The widget instance.
134     * @param string $section_id The section id.
135     * @param int    $height The ad height.
136     * @param int    $width The ad width.
137     *
138     * @return string
139     */
140    private function get_widget_snippet( $instance, $section_id, $height, $width ) {
141        global $wordads;
142
143        if ( $wordads->option( 'wordads_house', true ) ) {
144            $unit = 'mrec';
145            if ( 'leaderboard' === $instance['unit'] && ! $this->params->mobile_device ) {
146                $unit = 'leaderboard';
147            } elseif ( 'wideskyscraper' === $instance['unit'] ) {
148                $unit = 'widesky';
149            }
150
151            $snippet = $wordads->get_house_ad( $unit );
152        } else {
153            return $wordads->get_ad_snippet( $section_id, $height, $width, 'widget' );
154        }
155
156        $about = __( 'Advertisements', 'jetpack' );
157        $unit  = esc_attr( $instance['unit'] );
158
159        return <<<HTML
160        <div class="wpcnt">
161            <div class="wpa">
162                <span class="wpa-about">$about</span>
163                <div class="u $unit">
164                    $snippet
165                </div>
166            </div>
167        </div>
168HTML;
169    }
170
171    /**
172     * The widget settings form.
173     *
174     * @param array $instance Widget instance.
175     *
176     * @return string|void
177     */
178    public function form( $instance ) {
179        // ad unit type.
180        if ( isset( $instance['unit'] ) ) {
181            $unit = $instance['unit'];
182        } else {
183            $unit = 'mrec';
184        }
185        ?>
186        <p>
187            <label for="<?php echo esc_attr( $this->get_field_id( 'unit' ) ); ?>"><?php esc_html_e( 'Tag Dimensions:', 'jetpack' ); ?></label>
188            <select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'unit' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'unit' ) ); ?>">
189        <?php
190        foreach ( WordAds::$ad_tag_ids as $ad_unit => $properties ) {
191            if ( ! in_array( $ad_unit, self::$allowed_tags, true ) ) {
192                continue;
193            }
194
195                $splits      = explode( '_', $properties['tag'] );
196                $unit_pretty = "{$splits[0]} {$splits[1]}";
197                $selected    = selected( $ad_unit, $unit, false );
198                echo "<option value='", esc_attr( $ad_unit ), "' ", esc_attr( $selected ), '>', esc_html( $unit_pretty ), '</option>';
199        }
200        ?>
201            </select>
202        </p>
203        <?php
204    }
205
206    /**
207     * The Widget updater.
208     *
209     * @param array $new_instance The revised instance.
210     * @param array $old_instance Original instance.
211     *
212     * @return array
213     */
214    public function update( $new_instance, $old_instance ) {
215        $instance = $old_instance;
216
217        if ( in_array( $new_instance['unit'], self::$allowed_tags, true ) ) {
218            $instance['unit'] = $new_instance['unit'];
219        } else {
220            $instance['unit'] = 'mrec';
221        }
222
223        return $instance;
224    }
225}