Widget_Cache::update_widget()   B
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 32
rs 8.439
cc 6
eloc 18
nc 7
nop 0
1
<?php
2
3
namespace Rarst\Fragment_Cache;
4
5
/**
6
 * Cache widgets.
7
 */
8
class Widget_Cache extends Fragment_Cache {
9
10
	/**
11
	 * @inheritDoc
12
	 */
13 View Code Duplication
	public function enable() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
14
15
		if ( is_admin() ) {
16
			add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ) );
17
			add_action( 'wp_ajax_update-widget', array( $this, 'update_widget' ), 0 );
18
		} else {
19
			add_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ), 10, 3 );
20
		}
21
	}
22
23
	/**
24
	 * @inheritDoc
25
	 */
26 View Code Duplication
	public function disable() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
27
28
		if ( is_admin() ) {
29
			remove_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ) );
30
			remove_action( 'wp_ajax_update-widget', array( $this, 'update_widget' ), 0 );
31
		} else {
32
			remove_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ), 10 );
33
		}
34
	}
35
36
	/**
37
	 * Adds timestamp to widget instance to use as salt.
38
	 *
39
	 * @param array $instance Widget instance to modify.
40
	 *
41
	 * @return array
42
	 */
43
	public function widget_update_callback( $instance ) {
44
45
		if ( is_array( $instance ) ) {
46
			$instance['fc_widget_edited'] = time();
47
		}
48
49
		return $instance;
50
	}
51
52
	/**
53
	 * Invalidate widget instance cache on Customizer save.
54
	 */
55
	public function update_widget() {
0 ignored issues
show
Coding Style introduced by
update_widget uses the super-global variable $_POST 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...
56
57
		$customized = filter_input( INPUT_POST, 'customized' );
58
59
		if ( empty( $customized ) ) {
60
			return;
61
		}
62
63
		$customized = json_decode( $customized, true );
64
		$changed    = false;
65
66
		foreach ( $customized as $key => $data ) {
67
68
			if ( ! isset( $data['encoded_serialized_instance'] ) || 0 !== stripos( $key, 'widget' ) ) {
69
				continue;
70
			}
71
72
			$instance                     = unserialize( base64_decode( $data['encoded_serialized_instance'] ) );
73
			$instance['fc_widget_edited'] = time();
74
			$instance                     = base64_encode( serialize( $instance ) );
75
76
			$data['encoded_serialized_instance'] = $instance;
77
			$data['instance_hash_key']           = wp_hash( $instance );
78
			$customized[ $key ]                  = $data;
79
80
			$changed = true;
81
		}
82
83
		if ( $changed ) {
84
			$_POST['customized'] = wp_json_encode( $customized );
85
		}
86
	}
87
88
	/**
89
	 * Set up and echo widget cache
90
	 *
91
	 * @param array  $instance Widget instance data.
92
	 * @param object $widget   Widget object instance.
93
	 * @param array  $args     Arguments.
94
	 *
95
	 * @return bool false
96
	 */
97
	public function widget_display_callback( $instance, $widget, $args ) {
98
99
		$edited = isset( $instance['fc_widget_edited'] ) ? $instance['fc_widget_edited'] : '';
100
101
		echo $this->fetch(
102
			$widget->id,
103
			array(
104
				'callback' => array( $widget, 'widget' ),
105
				'args'     => array( $args, $instance ),
106
			),
107
			$edited
108
		);
109
110
		return false;
111
	}
112
113
	/**
114
	 * Generate widget output, capture with buffer and timestamp.
115
	 *
116
	 * @param string $name Fragment name.
117
	 * @param array  $args Arguments.
118
	 *
119
	 * @return string
120
	 */
121
	protected function callback( $name, $args ) {
122
123
		ob_start();
124
		call_user_func_array( $args['callback'], $args['args'] );
125
126
		return ob_get_clean() . $this->get_comment( $name );
127
	}
128
}
129