Completed
Push — develop ( 370152...d94e50 )
by David
03:11
created

Wordlift_Rebuild_Service::rebuild()   C

Complexity

Conditions 9
Paths 64

Size

Total Lines 60
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 26
nc 64
nop 0
dl 0
loc 60
rs 6.8358
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
/**
4
 * Define the Wordlift_Rebuild_Service class.
5
 */
6
7
/**
8
 * The Wordlift_Rebuild_Service allows to rebuild the Linked Data dataset from
9
 * scratch by clearing out data on the remote dataset, parsing all data in WordPress
10
 * and resending data to the remote dataset.
11
 *
12
 * @since 3.6.0
13
 */
14
class Wordlift_Rebuild_Service extends Wordlift_Listable {
15
16
	/**
17
	 * A {@link Wordlift_Log_Service} instance.
18
	 *
19
	 * @since  3.6.0
20
	 * @access private
21
	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
22
	 */
23
	private $log;
24
25
	/**
26
	 * A {@link Wordlift_Sparql_Service} instance.
27
	 * @since  3.6.0
28
	 * @access private
29
	 * @var \Wordlift_Sparql_Service $sparql_service A {@link Wordlift_Sparql_Service} instance.
30
	 */
31
	private $sparql_service;
32
33
	/**
34
	 * @var \Wordlift_Uri_Service
35
	 */
36
	private $uri_service;
37
38
	/**
39
	 * Create an instance of Wordlift_Rebuild_Service.
40
	 *
41
	 * @since 3.6.0
42
	 *
43
	 * @param \Wordlift_Sparql_Service $sparql_service A {@link Wordlift_Sparql_Service} instance used to query the remote dataset.
44
	 * @param \Wordlift_Uri_Service    $uri_service
45
	 */
46
	public function __construct( $sparql_service, $uri_service ) {
47
48
		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Rebuild_Service' );
49
50
		$this->sparql_service = $sparql_service;
51
		$this->uri_service    = $uri_service;
52
	}
53
54
	/**
55
	 * Rebuild the Linked Data remote dataset by clearing it out and repopulating
56
	 * it with local data.
57
	 *
58
	 * @since 3.6.0
59
	 */
60
	public function rebuild() {
0 ignored issues
show
Coding Style introduced by
rebuild 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...
61
62
		ob_clean();
63
64
		// Give ourselves some time to process the data.
65
		set_time_limit( 21600 ); // 6 hours
66
67
		// Send textual output.
68
		header( 'Content-type: text/plain; charset=utf-8' );
69
70
		// We start at 0 by default and get to max.
71
		$offset      = $_GET['offset'] ?: 0;
72
		$limit       = $_GET['limit'] ?: 1;
73
		$entity_only = isset( $_GET['entity_only'] ) && '1' === $_GET['entity_only'];
74
		$max         = $offset + $limit;
75
76
		// If we're starting at offset 0, then delete existing URIs and data from
77
		// the remote dataset.
78
		if ( 0 === $offset ) {
79
80
			// Clear out all generated URIs, since the dataset URI might have changed
81
			// in the process.
82
			$this->uri_service->delete_all();
83
84
			// Delete all the triples in the remote dataset.
85
			$this->sparql_service->queue( 'DELETE { ?s ?p ?o } WHERE { ?s ?p ?o };' );
86
87
		}
88
89
		// Go through the list of published entities and posts and call the (legacy)
90
		// `wl_linked_data_save_post` function for each one. We're using the `process`
91
		// function which is provided by the parent `Wordlift_Listable` abstract class
92
		// and will cycle through all the posts w/ a very small memory footprint
93
		// in order to avoid memory errors.
94
95
		$count = 0;
96
		$this->process( function ( $post ) use ( &$count ) {
97
			$count ++;
98
			wl_linked_data_save_post( $post->ID );
99
		}, array(
100
			'post_status' => 'publish',
101
			'post_type'   => $entity_only ? 'entity' : array(
102
				'entity',
103
				'post',
104
			),
105
		), $offset, $max );
106
107
		// Redirect to the next chunk.
108
		if ( $count == $limit ) {
109
			$this->redirect( admin_url( 'admin-ajax.php?action=wl_rebuild&offset=' . ( $offset + $limit ) . '&limit=' . $limit . '&entity_only=' . ( $entity_only ? '1' : '0' ) ) );
110
		}
111
112
		echo( "done [ count :: $count ][ limit :: $limit ]" );
113
114
		// If we're being called as AJAX, die here.
115
		if ( DOING_AJAX ) {
116
			wp_die();
117
		}
118
119
	}
120
121
	/**
122
	 * Redirect using a client-side meta to avoid browsers' redirect restrictions.
123
	 *
124
	 * @since 3.9.8
125
	 *
126
	 * @param string $url The URL to redirect to.
127
	 */
128
	private function redirect( $url ) {
129
130
		ob_clean();
131
132
		@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
133
		?>
134
		<html>
135
		<head>
136
			<meta http-equiv="refresh"
137
			      content="1; <?php echo esc_attr( $url ); ?>">
138
		</head>
139
		</html>
140
		<?php
141
142
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
143
144
	}
145
146
	/**
147
	 * List the items starting at the specified offset and up to the specified limit.
148
	 *
149
	 * @since 3.6.0
150
	 *
151
	 * @param int   $offset The start offset.
152
	 * @param int   $limit  The maximum number of items to return.
153
	 * @param array $args   Additional arguments.
154
	 *
155
	 * @return array A array of items (or an empty array if no items are found).
156
	 */
157
	function find( $offset = 0, $limit = 10, $args = array() ) {
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...
158
159
		return get_posts( wp_parse_args( $args, array(
160
			'offset'      => $offset,
161
			'numberposts' => $limit,
162
			'fields'      => 'all',
163
			'orderby'     => 'ID',
164
			'order'       => 'ASC',
165
			'post_status' => 'any',
166
			'post_type'   => 'post',
167
		) ) );
168
	}
169
170
}
171