Completed
Push — master ( 323b54...b3455a )
by David
04:27
created

Wordlift_Entity_Service::save_post()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 14
rs 9.4286
cc 3
eloc 5
nc 3
nop 3
1
<?php
2
3
/**
4
 * Provide entity-related services.
5
 *
6
 * @since 3.1.0
7
 */
8
class Wordlift_Entity_Service {
9
10
	/**
11
	 * The Log service.
12
	 *
13
	 * @since 3.2.0
14
	 * @access private
15
	 * @var \Wordlift_Log_Service $log_service The Log service.
16
	 */
17
	private $log_service;
18
19
	/**
20
	 * The UI service.
21
	 *
22
	 * @since 3.2.0
23
	 * @access private
24
	 * @var \Wordlift_UI_Service $ui_service The UI service.
25
	 */
26
	private $ui_service;
27
28
	/**
29
	 * The entity post type name.
30
	 *
31
	 * @since 3.1.0
32
	 */
33
	const TYPE_NAME = 'entity';
34
35
	/**
36
	 * The alternative label meta key.
37
	 *
38
	 * @since 3.2.0
39
	 */
40
	const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label';
41
42
	/**
43
	 * The alternative label input template.
44
	 *
45
	 * @since 3.2.0
46
	 */
47
	// TODO: this should be moved to a class that deals with HTML code.
48
	const ALTERNATIVE_LABEL_INPUT_TEMPLATE = '<div class="wl-alternative-label">
49
                <label class="screen-reader-text" id="wl-alternative-label-prompt-text" for="wl-alternative-label">Enter alternative label here</label>
50
                <input name="wl_alternative_label[]" size="30" value="%s" id="wl-alternative-label" type="text">
51
                <button class="button wl-delete-button">%s</button>
52
                </div>';
53
54
	/**
55
	 * A singleton instance of the Entity service.
56
	 *
57
	 * @since 3.2.0
58
	 * @access private
59
	 * @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service.
60
	 */
61
	private static $instance;
62
63
	/**
64
	 * Create a Wordlift_Entity_Service instance.
65
	 *
66
	 * @since 3.2.0
67
	 *
68
	 * @param \Wordlift_UI_Service $ui_service The UI service.
69
	 */
70
	public function __construct( $ui_service ) {
71
72
		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' );
73
74
		// Set the UI service.
75
		$this->ui_service = $ui_service;
76
77
		// Set the singleton instance.
78
		self::$instance = $this;
79
80
	}
81
82
	/**
83
	 * Get the singleton instance of the Entity service.
84
	 *
85
	 * @since 3.2.0
86
	 * @return \Wordlift_Entity_Service The singleton instance of the Entity service.
87
	 */
88
	public static function get_instance() {
89
90
		return self::$instance;
91
	}
92
93
	/**
94
	 * Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to
95
	 * its specific function).
96
	 *
97
	 * @since 3.1.0
98
	 *
99
	 * @return array An array of post IDs.
100
	 */
101
	public function get_all_related_to_last_50_published_posts() {
102
103
		// Global timeline. Get entities from the latest posts.
104
		$latest_posts_ids = get_posts( array(
105
			'numberposts' => 50,
106
			'fields'      => 'ids', //only get post IDs
107
			'post_type'   => 'post',
108
			'post_status' => 'publish'
109
		) );
110
111
		if ( empty( $latest_posts_ids ) ) {
112
			// There are no posts.
113
			return array();
114
		}
115
116
		// Collect entities related to latest posts
117
		$entity_ids = array();
118
		foreach ( $latest_posts_ids as $id ) {
119
			$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array(
120
				'status' => 'publish'
121
			) ) );
122
		}
123
124
		return $entity_ids;
125
	}
126
127
	/**
128
	 * Determines whether a post is an entity or not.
129
	 *
130
	 * @since 3.1.0
131
	 *
132
	 * @param int $post_id A post id.
133
	 *
134
	 * @return true if the post is an entity otherwise false.
135
	 */
136
	public function is_entity( $post_id ) {
137
138
		return ( self::TYPE_NAME === get_post_type( $post_id ) );
139
	}
140
141
	/**
142
	 * Find entity posts by the entity URI. Entity as searched by their entity URI or same as.
143
	 *
144
	 * @since 3.2.0
145
	 *
146
	 * @param string $uri The entity URI.
147
	 *
148
	 * @return WP_Post|null A WP_Post instance or null if not found.
149
	 */
150 View Code Duplication
	public function get_entity_post_by_uri( $uri ) {
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...
151
152
		$query = new WP_Query( array(
153
				'posts_per_page' => 1,
154
				'post_status'    => 'any',
155
				'post_type'      => self::TYPE_NAME,
156
				'meta_query'     => array(
157
					'relation' => 'OR',
158
					array(
159
						'key'     => Wordlift_Schema_Service::FIELD_SAME_AS,
160
						'value'   => $uri,
161
						'compare' => '='
162
					),
163
					array(
164
						'key'     => WL_ENTITY_URL_META_NAME,
165
						'value'   => $uri,
166
						'compare' => '='
167
					)
168
				)
169
			)
170
		);
171
172
		// Get the matching entity posts.
173
		$posts = $query->get_posts();
174
175
		// Return null if no post is found.
176
		if ( 0 === count( $posts ) ) {
177
			return null;
178
		}
179
180
		// Return the found post.
181
		return $posts[0];
182
	}
183
184
	/**
185
	 * Fires once a post has been saved.
186
	 *
187
	 * @since 3.2.0
188
	 *
189
	 * @param int $post_id Post ID.
190
	 * @param WP_Post $post Post object.
191
	 * @param bool $update Whether this is an existing post being updated or not.
192
	 */
193
	public function save_post( $post_id, $post, $update ) {
0 ignored issues
show
Unused Code introduced by
The parameter $post is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
save_post uses the super-global variable $_REQUEST 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...
194
195
		// If it's not an entity, return.
196
		if ( ! $this->is_entity( $post_id ) ) {
197
			return;
198
		}
199
200
		// Get the alt labels from the request (or empty array).
201
		$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array();
202
203
		// Set the alternative labels.
204
		$this->set_alternative_labels( $post_id, $alt_labels );
205
206
	}
207
208
	/**
209
	 * Set the alternative labels.
210
	 *
211
	 * @since 3.2.0
212
	 *
213
	 * @param int $post_id The post id.
214
	 * @param array $alt_labels An array of labels.
215
	 */
216
	public function set_alternative_labels( $post_id, $alt_labels ) {
217
		
218
		// Force $alt_labels to be an array
219
		if( !is_array( $alt_labels ) ) {
220
			$alt_labels = array( $alt_labels );
221
		}
222
223
		$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" );
224
225
		// Delete all the existing alternate labels.
226
		delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
227
		
228
		// Set the alternative labels.
229
		foreach ( $alt_labels as $alt_label ) {
230
			if ( ! empty( $alt_label ) ) {
231
				add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label );
232
			}
233
		}
234
235
	}
236
237
	/**
238
	 * Retrieve the alternate labels.
239
	 *
240
	 * @since 3.2.0
241
	 *
242
	 * @param int $post_id Post id.
243
	 *
244
	 * @return mixed An array  of alternative labels.
245
	 */
246
	public function get_alternative_labels( $post_id ) {
247
248
		return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY );
249
	}
250
251
	/**
252
	 * Fires before the permalink field in the edit form (this event is available in WP from 4.1.0).
253
	 *
254
	 * @since 3.2.0
255
	 *
256
	 * @param WP_Post $post Post object.
257
	 */
258
	public function edit_form_before_permalink( $post ) {
259
260
		// If it's not an entity, return.
261
		if ( ! $this->is_entity( $post->ID ) ) {
262
			return;
263
		}
264
265
		// Print the input template.
266
		$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() );
267
268
		// Print all the currently set alternative labels.
269
		foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) {
270
271
			echo $this->get_alternative_label_input( $alt_label );
272
273
		};
274
275
		// Print the button.
276
		$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) );
277
278
	}
279
280
	/**
281
	 * Get the alternative label input HTML code.
282
	 *
283
	 * @since 3.2.0
284
	 *
285
	 * @param string $value The input value.
286
	 *
287
	 * @return string The input HTML code.
288
	 */
289
	private function get_alternative_label_input( $value = '' ) {
290
291
		return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) );
292
	}
293
}
294