PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.29.0
Advanced Ads – Ad Manager & AdSense v1.29.0
2.0.26 2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / modules / import-export / classes / import.php
advanced-ads / modules / import-export / classes Last commit date
XmlEncoder.php 5 years ago export.php 5 years ago import.php 5 years ago
import.php
710 lines
1 <?php
2
3 /**
4 * Class Advanced_Ads_Import
5 */
6 class Advanced_Ads_Import {
7 /**
8 * @var Advanced_Ads_Export
9 */
10 private static $instance;
11
12 /**
13 * Uploaded XML file path
14 */
15 private $import_id;
16
17 /**
18 * Status messages
19 */
20 private $messages = array();
21
22 /**
23 * Imported data mapped with previous data, e.g. ['ads'][ new_ad_id => old_ad_id (or null if does not exist) ]
24 */
25 public $imported_data = array(
26 'ads' => array(),
27 'groups' => array(),
28 'placements' => array()
29 );
30
31 /**
32 * Created groups during this import session ['slug' => 'id']
33 */
34 private $created_groups = array();
35
36 /**
37 * Attachments, created for Image Ads and images in ad content
38 */
39 private $created_attachments = array();
40
41 private function __construct() {}
42
43 /**
44 * Return an instance of this class.
45 */
46 public static function get_instance() {
47 if ( null == self::$instance ) {
48 self::$instance = new self;
49 }
50 return self::$instance;
51 }
52
53 /**
54 * Manages stages of the XML import process
55 */
56 public function dispatch() {
57 if ( ! isset( $_POST['_wpnonce'] )
58 || ! wp_verify_nonce( $_POST['_wpnonce'], 'advads-import' )
59 || ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_options') ) ) {
60 return;
61 }
62
63 if ( ! isset( $_POST['import_type'] ) ) {
64 return;
65 }
66
67 switch ( $_POST['import_type'] ) {
68 case 'xml_content':
69 if ( empty( $_POST['xml_textarea'] ) ) {
70 $this->messages[] = array( 'error', __( 'Please enter XML content', 'advanced-ads' ) );
71 return;
72 }
73 // see wp_magic_quotes()
74 $content = stripslashes( $_POST['xml_textarea'] );
75 $this->import( $content );
76 break;
77 case 'xml_file':
78 if ( $this->handle_upload() ) {
79 $content = file_get_contents( $this->import_id );
80 $this->import( $content );
81 @unlink( $this->import_id );
82 }
83 break;
84 }
85 }
86
87 /**
88 * The main controller for the actual import stage
89 *
90 * @param string $xml_content XML content to import.
91 */
92 public function import( &$xml_content ) {
93 @set_time_limit( 0 );
94 @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
95
96 $xml_content = trim( $xml_content );
97
98 if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
99 error_log( 'source XML:' );
100 error_log( $xml_content );
101 }
102
103 try {
104 $decoded = Advanced_Ads_XmlEncoder::get_instance()->decode( $xml_content );
105 } catch ( Exception $e ) {
106 error_log( $e->getMessage() );
107 $this->messages[] = array ( 'error', $e->getMessage() );
108 return;
109 }
110
111 if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
112 error_log( 'decoded XML:' );
113 error_log(print_r($decoded, true));
114 }
115
116 $this->import_ads_and_groups( $decoded );
117 $this->import_empty_groups( $decoded );
118 $this->import_placements( $decoded );
119 $this->import_options( $decoded );
120
121 do_action_ref_array( 'advanced-ads-import', array( &$decoded, &$this->imported_data, &$this->messages ) );
122
123 wp_cache_flush();
124 }
125
126 /**
127 * Create new ads and groups based on import information
128 *
129 * @param array $decoded decoded XML.
130 */
131 private function import_ads_and_groups( &$decoded ) {
132 if ( isset( $decoded['ads'] ) && is_array( $decoded['ads'] ) ) {
133 foreach ( $decoded['ads'] as $k => $ad ) {
134 $ad_title = isset( $ad['post_title'] ) ? $ad['post_title'] : '';
135 $ad_date = isset( $ad['post_date'] ) ? $ad['post_date'] : '';
136
137 if ( isset( $ad['meta_input'] ) && is_array( $ad['meta_input'] ) ) {
138 foreach ( $ad['meta_input'] as $meta_k => &$meta_v ) {
139 if ( $meta_k !== Advanced_Ads_Ad::$options_meta_field ) {
140 $meta_v = maybe_unserialize( $meta_v );
141 }
142 }
143 }
144
145 // upload images for Image ad ad type
146 if ( isset( $ad['attached_img_url'] ) && isset( $ad['meta_input']['advanced_ads_ad_options']['output']['image_id'] ) ) {
147 $attached_img_url = $this->replace_placeholders( $ad['attached_img_url'] );
148 $attachment_id = null;
149
150 if ( isset( $this->created_attachments[ $attached_img_url ] ) ) {
151 $attachment_id = $this->created_attachments[ $attached_img_url ]['post_id'];
152 } else if ( $attachment = $this->upload_image_from_url( $attached_img_url ) ) {
153 $link = ( $link = get_attachment_link( $attachment['post_id'] ) ) ? sprintf( '<a href="%s">%s</a>', esc_url( $link ), __( 'Edit', 'advanced-ads' ) ) : '';
154 $this->messages[] = array( 'update', sprintf( __( 'New attachment created <em>%s</em> %s', 'advanced-ads' ), $attachment['post_id'], $link ) );
155 $this->created_attachments[ $attached_img_url ] = $attachment;
156 $attachment_id = $attachment['post_id'];
157 }
158
159 if ( $attachment_id ) {
160 $ad['meta_input']['advanced_ads_ad_options']['output']['image_id'] = $attachment_id;
161 }
162 }
163
164 $insert_ad = array(
165 'post_title' => $ad_title,
166 'post_date' => $ad_date,
167 'post_date_gmt' => isset( $ad['post_date_gmt'] ) ? $ad['post_date_gmt'] : '',
168 'post_content' => isset( $ad['post_content'] ) ? $this->process_ad_content( $ad['post_content'] ) : '',
169 'post_password' => isset( $ad['post_password'] ) ? $ad['post_password'] : '',
170 'post_name' => isset( $ad['post_name'] ) ? $ad['post_name'] : '',
171 'post_status' => isset( $ad['post_status'] ) ? $ad['post_status'] : 'publish',
172 'post_modified' => isset( $ad['post_modified'] ) ? $ad['post_modified'] : '',
173 'post_modified_gmt' => isset( $ad['post_modified_gmt'] ) ? $ad['post_modified_gmt'] : '',
174 'guid' => isset( $ad['guid'] ) ? $ad['guid'] :'',
175 'post_author' => get_current_user_id(),
176 'post_type' => Advanced_Ads::POST_TYPE_SLUG,
177 'comment_status' => 'closed',
178 'ping_status' => 'closed',
179 'meta_input' => isset( $ad['meta_input'] ) ? $ad['meta_input'] : '',
180 );
181
182
183 $post_id = wp_insert_post( $insert_ad, true );
184
185 if ( is_wp_error( $post_id ) ) {
186 $this->messages[] = array( 'error', sprintf( __( 'Failed to import <em>%s</em>', 'advanced-ads' ), esc_html($ad['post_title'] ) ) );
187 if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) {
188 $this->messages[] = array( 'error', ' > ' . $post_id->get_error_message() );
189 }
190
191 continue;
192 } else {
193 $link = ( $link = get_edit_post_link( $post_id ) ) ? sprintf( '<a href="%s">%s</a>', esc_url( $link ), __( 'Edit', 'advanced-ads' ) ) : '';
194 $this->messages[] = array( 'update', sprintf( __( 'New ad created: <em>%s</em> %s', 'advanced-ads' ), $post_id, $link ) );
195 }
196
197 // new ad id => old ad id, if exists
198 $this->imported_data['ads'][ $post_id ] = isset( $ad['ID'] ) ? absint( $ad['ID'] ) : null;
199
200 // import ad groups
201 if ( ! empty( $ad['groups'] ) && is_array( $ad['groups'] ) ) {
202 $groups_to_set = array();
203 $advads_ad_groups = get_option( 'advads-ad-groups', array() );
204 $advads_ad_weights = get_option( 'advads-ad-weights', array() );
205
206 foreach ( $ad['groups'] as $_group ) {
207 if ( ! $group_id = $this->create_group_term( $_group ) ) {
208 continue;
209 }
210
211 $ad_group_id = null;
212 if ( isset( $ad['meta_input']['advanced_ads_ad_options']['output']['group_id'] ) ) {
213 $ad_group_id = $ad['meta_input']['advanced_ads_ad_options']['output']['group_id'];
214 }
215
216 // do not save the ad group, if this is the group assigned as ad content
217 if ( $ad_group_id !== $group_id ) {
218 $groups_to_set[] = (int) $group_id;
219 }
220
221 if ( ! isset( $advads_ad_groups[ $group_id ] ) ) {
222 $advads_ad_groups[ $group_id ] = array (
223 'type' => isset( $_group['type']) ? $_group['type'] : 'default',
224 'ad_count' => isset($_group['ad_count']) ? $_group['ad_count'] : 1,
225 'options' => isset($_group['options']) ? $_group['options'] : array()
226 );
227
228 update_option( 'advads-ad-groups', $advads_ad_groups );
229 }
230
231 $ad_weight = isset( $_group['weight'] ) ? absint( $_group['weight'] ) : Advanced_Ads_Group::MAX_AD_GROUP_DEFAULT_WEIGHT;
232 $advads_ad_weights[ $group_id ][ $post_id ] = $ad_weight;
233 }
234
235 update_option( 'advads-ad-weights', $advads_ad_weights );
236
237 $this->messages[] = array( 'update', sprintf( __( 'Assigned terms: <em>%s</em>, to post: <em>%s</em>', 'advanced-ads' ), implode(',',$groups_to_set), $post_id ) );
238
239 $tt_ids = wp_set_post_terms( $post_id, $groups_to_set, Advanced_Ads::AD_GROUP_TAXONOMY );
240 }
241 }
242 }
243 }
244
245 /**
246 * Create new empty groups based on import information
247 *
248 * @param array $decoded decoded XML
249 */
250 private function import_empty_groups( &$decoded ) {
251 if ( isset( $decoded['groups'] ) && is_array( $decoded['groups'] ) ) {
252 $advads_ad_groups = get_option( 'advads-ad-groups', array() );
253
254 foreach ( $decoded['groups'] as $_group ) {
255 if ( $group_id = $this->create_group_term( $_group ) ) {
256 if ( ! isset( $advads_ad_groups[ $group_id ] ) ) {
257 $advads_ad_groups[ $group_id ] = array (
258 'type' => isset( $_group['type']) ? $_group['type'] : 'default',
259 'ad_count' => isset( $_group['ad_count'] ) ? $_group['ad_count'] : 1,
260 'options' => isset( $_group['options'] ) ? $_group['options'] : array()
261 );
262 }
263 }
264 }
265 update_option( 'advads-ad-groups', $advads_ad_groups );
266 }
267 }
268
269 /**
270 * Create new group term if it haven't already been created
271 *
272 * @param array $_group decoded XML
273 * @return int group_id, false on failure
274 */
275 private function create_group_term( $_group ) {
276 if ( empty( $_group['slug'] ) || empty( $_group['name'] ) ) {
277 return false;
278 }
279
280 $slug = $original_slug = $_group['slug'];
281
282 if ( isset( $this->created_groups[ $original_slug ] ) ) {
283 return $this->created_groups[ $slug ];
284 }
285
286 if ( term_exists( $slug, Advanced_Ads::AD_GROUP_TAXONOMY ) ) {
287 $count = 1;
288 while ( term_exists( $slug . '_' . $count, Advanced_Ads::AD_GROUP_TAXONOMY ) ) {
289 $count++;
290 }
291 $slug = $slug . '_' . $count;
292 }
293
294 $t = wp_insert_term( $_group['name'], Advanced_Ads::AD_GROUP_TAXONOMY, array( 'slug' => $slug) );
295
296 if ( ! is_wp_error( $t ) ) {
297 $this->created_groups[ $original_slug ] = $t['term_id'];
298 $group_id = $t['term_id'];
299 $this->messages[] = array( 'update', sprintf( __( 'New group created, id: <em>%s</em>, name: <em>%s</em>', 'advanced-ads' ), $group_id, esc_html( $_group['name'] ) ) );
300 } else {
301 $this->messages[] = array( 'error', sprintf( __( 'Failed to import taxonomy: <em>%s</em>, term: <em>%s</em>', 'advanced-ads' ), esc_html(Advanced_Ads::AD_GROUP_TAXONOMY), esc_html($_group['name'] ) ) );
302 if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) {
303 $this->messages[] = array( 'error', ' > ' . $t->get_error_message() );
304 }
305
306 return false;
307 }
308
309 // new group id => old group id, if exists
310 $this->imported_data['groups'][ $group_id ] = isset( $_group['term_id'] ) ? absint( $_group['term_id'] ) : null;
311
312 return $group_id;
313 }
314
315 /**
316 * Create new placements based on import information
317 *
318 * @param array $decoded decoded XML.
319 */
320 private function import_placements( &$decoded ) {
321 if ( isset( $decoded['placements'] ) && is_array( $decoded['placements'] ) ) {
322
323 $existing_placements = $updated_placements = Advanced_Ads::get_instance()->get_model()->get_ad_placements_array();
324 $placement_types = Advanced_Ads_Placements::get_placement_types();
325
326 foreach ( $decoded['placements'] as &$placement ) {
327 $use_existing = ! empty( $placement['use_existing'] );
328
329 // use existing placement
330 if ( $use_existing ) {
331 if ( empty( $placement['key'] ) ) {
332 continue;
333 }
334
335 $placement_key_uniq = sanitize_title( $placement['key'] );
336 if ( ! isset( $existing_placements[ $placement_key_uniq ] ) ) {
337 continue;
338 }
339
340 $existing_placement = $existing_placements[ $placement_key_uniq ];
341 $existing_placement['key'] = $placement_key_uniq;
342
343 // create new placement
344 } else {
345 if ( empty( $placement['key'] ) || empty( $placement['name'] ) || empty( $placement['type'] ) ) {
346 continue;
347 }
348
349 $placement_key_uniq = sanitize_title( $placement['key'] );
350 if ( $placement_key_uniq === '' ) {
351 continue;
352 }
353
354 $placement['type'] = ( isset( $placement_types[ $placement['type'] ] ) ) ? $placement['type'] : 'default';
355 $placement['name'] = esc_attr( $placement['name'] );
356
357 // make sure the key in placement array is unique
358 if ( isset( $existing_placements[ $placement_key_uniq ] ) ) {
359 $count = 1;
360 while ( isset( $existing_placements[ $placement_key_uniq . '_' . $count ] ) ) {
361 $count++;
362 }
363 $placement_key_uniq .= '_' . $count;
364 }
365
366 $this->messages[] = array( 'update', sprintf( __( 'Placement <em>%s</em> created', 'advanced-ads' ), esc_html( $placement['name'] ) ) );
367
368 // new placement key => old placement key
369 $this->imported_data['placements'][ $placement_key_uniq ] = $placement['key'];
370 }
371
372 // try to set "Item" (ad or group)
373 if ( ! empty( $placement['item'] ) ) {
374 $_item = explode( '_', $placement['item'] );
375 if ( ! empty( $_item[1] ) ) {
376 switch ( $_item[0] ) {
377 case 'ad':
378 case Advanced_Ads_Select::AD :
379
380 $found = $this->search_item( $_item[1], Advanced_Ads_Select::AD );
381 if ( $found === false ) { break; }
382
383 if ( $use_existing ) {
384 // assign new ad to an existing placement
385 // - if the placement has no or a single ad assigned, it will be swapped against the new one
386 // - if a group is assigned to the placement, the new ad will be added to this group with a weight of 1
387 $placement = $existing_placement;
388
389 if ( ! empty( $placement['item'] ) ) {
390 // get the item from the existing placement
391 $_item_existing = explode( '_', $placement['item'] );
392
393 if ( ! empty( $_item_existing[1] ) && $_item_existing[0] === Advanced_Ads_Select::GROUP ) {
394 $advads_ad_weights = get_option( 'advads-ad-weights', array() );
395
396 if ( term_exists( absint( $_item_existing[1] ), Advanced_Ads::AD_GROUP_TAXONOMY ) ) {
397 wp_set_post_terms( $found, $_item_existing[1], Advanced_Ads::AD_GROUP_TAXONOMY, true );
398
399 /**
400 * By default, a new add added to a group receives the weight of 5
401 * so that users could set the weight of existing ads either higher or lower
402 * depending on whether they want to show the new ad with a higher weight or not.
403 * This is especially useful with Selling Ads to replace an existing ad in a group
404 * with a newly sold one
405 *
406 * Advanced users could use the `advanced-ads-import-default-group-weight` filter
407 * to manipulate the value
408 */
409 $advads_ad_weights[ $_item_existing[1] ][ $found ] = apply_filters( 'advanced-ads-import-default-group-weight', 5 );
410 update_option( 'advads-ad-weights', $advads_ad_weights );
411 // new placement key => old placement key
412 $this->imported_data['placements'][ $placement_key_uniq ] = $placement_key_uniq;
413 break;
414 }
415 }
416 }
417 }
418
419 $placement['item'] = 'ad_' . $found;
420 // new placement key => old placement key
421 $this->imported_data['placements'][ $placement_key_uniq ] = $placement_key_uniq;
422 break;
423 case Advanced_Ads_Select::GROUP :
424 $found = $this->search_item( $_item[1], Advanced_Ads_Select::GROUP );
425 if ( $found === false ) { break; }
426
427 $placement['item'] = 'group_' . $found;
428 // new placement key => old placement key
429 $this->imported_data['placements'][ $placement_key_uniq ] = $placement_key_uniq;
430 break;
431 }
432 }
433 }
434
435 $updated_placements[ $placement_key_uniq ] = apply_filters( 'advanced-ads-import-placement', $placement, $this );
436 }
437
438 if ( $existing_placements !== $updated_placements ) {
439 Advanced_Ads::get_instance()->get_model()->update_ad_placements_array( $updated_placements );
440 }
441 }
442 }
443
444 /**
445 * Search for ad/group id
446 *
447 * @param string $id ad/group id
448 * @param string $type
449 * @return
450 * - int id of the imported ad/group if exists
451 * - or int id of the existing ad/group if exists
452 * - or bool false
453 */
454 public function search_item( $id, $type ) {
455 $found = false;
456
457 switch ( $type ) {
458 case 'ad':
459 case Advanced_Ads_Select::AD :
460 // if the ad was was imported
461 if ( ! $found = array_search( $id, $this->imported_data['ads'] ) ) {
462 // if the ad already exists
463 if ( get_post_type( $id ) === Advanced_Ads::POST_TYPE_SLUG ) {
464 $found = $id;
465 }
466 }
467 break;
468 case Advanced_Ads_Select::GROUP :
469 if ( ! $found = array_search( $id, $this->imported_data['groups'] ) ) {
470 if ( term_exists( absint( $id ), Advanced_Ads::AD_GROUP_TAXONOMY ) ) {
471 $found = $id;
472 }
473 }
474 break;
475 }
476
477 return (int) $found;
478 }
479
480 /**
481 * Create new options based on import information.
482 *
483 * @param array $decoded decoded XML.
484 */
485 private function import_options( &$decoded ) {
486 if ( isset( $decoded['options'] ) && is_array( $decoded['options'] ) ) {
487 foreach ( $decoded['options'] as $option_name => $imported_option ) {
488 // Ignore options not belonging to advanced ads.
489 if (
490 0 !== strpos( $option_name, 'advads-' )
491 && 0 !== strpos( $option_name, 'advads_' )
492 && 0 !== strpos( $option_name, 'advanced-ads' )
493 && 0 !== strpos( $option_name, 'advanced_ads' )
494 ) {
495 continue;
496 }
497
498 $existing_option = get_option( $option_name, array() );
499
500 if ( ! is_array( $imported_option ) ) {
501 $imported_option = array();
502 }
503 if ( ! is_array( $existing_option ) ) {
504 $existing_option = array();
505 }
506
507 $option_to_import = array_merge( $existing_option, $imported_option );
508
509 /* translators: %s: Option name. */
510 $this->messages[] = array( 'update', sprintf( __( 'Option was updated: <em>%s</em>', 'advanced-ads' ), $option_name ) );
511 update_option( $option_name, maybe_unserialize( $option_to_import ) );
512 }
513 }
514 }
515
516 /**
517 * Handles the XML upload
518 *
519 * @return bool false if error, true otherwise
520 */
521 private function handle_upload() {
522 $uploads_dir = wp_upload_dir();
523 if ( ! empty( $uploads_dir['error'] ) ) {
524 $this->messages[] = array( 'error', $uploads_dir['error'] );
525 return;
526 }
527
528 $import_dir = $uploads_dir['basedir'] . '/advads-import';
529 $this->import_id = $import_dir . '/' . md5( time() . NONCE_SALT );
530
531 if ( ! is_dir( $import_dir) && ! wp_mkdir_p( $import_dir ) ) {
532 $this->messages[] = array( 'error', sprintf( __( 'Failed to create import directory <em>%s</em>', 'advanced-ads' ), $import_dir ) );
533 return;
534 }
535
536 if ( ! is_writable( $import_dir ) ) {
537 $this->messages[] = array( 'error', sprintf( __( 'Import directory is not writable: <em>%s</em>', 'advanced-ads' ), $import_dir ) );
538 return;
539 }
540
541 if ( ! @file_exists( $import_dir . '/index.php') ) @touch( $import_dir . '/index.php' );
542
543
544 if ( ! isset( $_FILES['import'] ) ) {
545 $this->messages[] = array( 'error', __( 'File is empty, uploads are disabled or post_max_size is smaller than upload_max_filesize in php.ini', 'advanced-ads' ) );
546 return;
547 }
548
549 $file = $_FILES['import'];
550
551 // determine if uploaded file exceeds space quota.
552 $file = apply_filters( "wp_handle_upload_prefilter", $file );
553
554 if ( ! empty( $file['error'] ) ) {
555 $this->messages[] = array( 'error', sprintf( __( 'Failed to upload file, error: <em>%s</em>', 'advanced-ads' ), $file['error'] ) );
556 return;
557 }
558
559 if ( ! ( $file['size'] > 0 ) ) {
560 $this->messages[] = array( 'error', __( 'File is empty.', 'advanced-ads' ), $file['error'] );
561 return;
562 }
563
564 if ( ! is_uploaded_file( $file['tmp_name'] ) || ! @ move_uploaded_file( $file['tmp_name'], $this->import_id ) || ! is_readable( $this->import_id ) ) {
565 $this->messages[] = array( 'error', sprintf( __( 'The file could not be created: <em>%s</em>. This is probably a permissions problem', 'advanced-ads' ), $this->import_id ) );
566 return;
567 }
568
569 // Set correct file permissions.
570 $stat = stat( dirname( $import_dir ) );
571 $perms = $stat['mode'] & 0000666;
572 @ chmod( $this->import_id, $perms );
573
574 // cleanup in case of failed import
575 wp_schedule_single_event( time() + 10 * MINUTE_IN_SECONDS, 'advanced-ads-cleanup-import-file', array( $this->import_id ) );
576
577 return true;
578 }
579
580 /**
581 * Ad content manipulations
582 *
583 * @param string $content
584 * @return string $content
585 */
586 private function process_ad_content( $content ) {
587 // download images, replace old image urls with urls of these new images
588 $replacement_map = array();
589
590 if ( preg_match_all( '/\<advads_import_img\>(\S+?)\<\/advads_import_img\>/i', $content, $matches ) ) {
591 foreach ( $matches[1] as $k => $url ) {
592 if ( isset( $this->created_attachments[ $url ] ) ) {
593 $replacement_map[ $url ] = $this->created_attachments[ $url ]['attachment_url'];
594 } else if ( $attachment = $this->upload_image_from_url( $url ) ) {
595 $link = ( $link = get_attachment_link( $attachment['post_id'] ) ) ? sprintf( '<a href="%s">%s</a>', esc_url( $link ), __( 'Edit', 'advanced-ads' ) ) : '';
596 $this->messages[] = array( 'update', sprintf( __( 'New attachment created <em>%s</em> %s', 'advanced-ads' ), $attachment['post_id'], $link ) );
597 $this->created_attachments[ $url ] = $attachment;
598 $replacement_map[ $url ] = $attachment['attachment_url'];
599 }
600 }
601 }
602
603 $content = str_replace( array( '<advads_import_img>', '</advads_import_img>' ), '', $content );
604
605 if ( count( $replacement_map ) ) {
606 $content = str_replace( array_keys( $replacement_map ), array_values( $replacement_map ), $content );
607 }
608
609 // replace placeholders
610 return $this->replace_placeholders( $content );
611 }
612
613 /**
614 * Replace placeholders
615 *
616 * @param string $content
617 * @return string with replaced placeholders
618 */
619 private function replace_placeholders( $content ) {
620 $content = str_replace( '{ADVADS_BASE_URL}', ADVADS_BASE_URL, $content );
621 return $content;
622 }
623
624 /**
625 * Upload image from URL and create attachment
626 *
627 * @param string $image_url Image url.
628 * @return array with indices: post_id, attachment_url, false on failure
629 */
630 private function upload_image_from_url( $image_url ) {
631 $file_name = basename( current( explode( '?', $image_url ) ) );
632 $wp_filetype = wp_check_filetype( $file_name, null );
633 $parsed_url = @parse_url( $image_url );
634 $image_url = str_replace( ' ', '%20', $image_url );
635
636
637 if ( ! $wp_filetype['type'] ) {
638 $this->messages[] = array( 'error', sprintf( __( 'Invalid filetype <em>%s</em>', 'advanced-ads' ), $image_url ) );
639 return false;
640 }
641
642 if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
643 $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
644 return false;
645 }
646
647 $response = wp_safe_remote_get( $image_url, array( 'timeout' => 20 ) );
648
649 if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
650 $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
651 return false;
652 }
653
654 // Upload the file.
655 $upload = wp_upload_bits( $file_name, '', wp_remote_retrieve_body( $response ) );
656
657 if ( $upload['error'] ) {
658 $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
659 return false;
660 }
661
662 // Get filesize.
663 $filesize = filesize( $upload['file'] );
664
665 if ( 0 == $filesize ) {
666 @unlink( $upload['file'] );
667 $this->messages[] = array( 'error', sprintf( __( 'Zero size file downloaded <em>%s</em>', 'advanced-ads' ), $image_url ) );
668 return false;
669 }
670
671 /**
672 * Get allowed image mime types.
673 *
674 * @var string Single mime type.
675 */
676 $mime_types = array_filter( get_allowed_mime_types(), function( $mime_type ) {
677 return preg_match( '/image\//', $mime_type );
678 } );
679 $fileinfo = @getimagesize( $upload['file'] );
680
681 if ( ! $fileinfo || ! in_array( $fileinfo['mime'], $mime_types, true ) ) {
682 @unlink( $upload['file'] );
683 /* translators: 1: image url */
684 $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
685
686 return false;
687 }
688
689 // create new post
690 $new_post = array(
691 'post_title' => $file_name,
692 'post_mime_type' => $wp_filetype['type'],
693 'guid' => $upload['url'],
694 );
695
696 if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
697 require_once( ABSPATH . 'wp-admin/includes/image.php' );
698 }
699
700 $post_id = wp_insert_attachment( $new_post, $upload['file'] );
701 wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
702
703 return array( 'post_id' => $post_id, 'attachment_url' => wp_get_attachment_url( $post_id ) );
704 }
705
706 public function get_messages(){
707 return $this->messages;
708 }
709 }
710