run:R W Run
1.25 KB
2026-03-11 16:18:52
R W Run
639 By
2026-03-11 16:18:52
R W Run
2.26 KB
2026-03-11 16:18:52
R W Run
3.13 KB
2026-03-11 16:18:52
R W Run
1.42 KB
2026-03-11 16:18:52
R W Run
5.16 KB
2026-03-11 16:18:52
R W Run
9.22 KB
2026-03-11 16:18:52
R W Run
588 By
2026-03-11 16:18:52
R W Run
7.84 KB
2026-03-11 16:18:52
R W Run
1.74 KB
2026-03-11 16:18:52
R W Run
1.18 KB
2026-03-11 16:18:52
R W Run
9.18 KB
2026-03-11 16:18:52
R W Run
1.1 KB
2026-03-11 16:18:52
R W Run
2.08 KB
2026-03-11 16:18:52
R W Run
7.97 KB
2026-03-11 16:18:52
R W Run
27.22 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
2.75 KB
2026-03-11 16:18:52
R W Run
1.1 KB
2026-03-11 16:18:52
R W Run
716 By
2026-03-11 16:18:52
R W Run
18.49 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
1.67 KB
2026-03-11 16:18:52
R W Run
1.65 KB
2026-03-11 16:18:52
R W Run
10.32 KB
2026-03-11 16:18:52
R W Run
13.52 KB
2026-03-11 16:18:52
R W Run
1.03 KB
2026-03-11 16:18:52
R W Run
5.04 KB
2026-03-11 16:18:52
R W Run
11.61 KB
2026-03-11 16:18:52
R W Run
3.31 KB
2026-03-11 16:18:52
R W Run
6.79 KB
2026-03-11 16:18:52
R W Run
1.17 KB
2026-03-11 16:18:52
R W Run
686 By
2026-03-11 16:18:52
R W Run
1.68 KB
2026-03-11 16:18:52
R W Run
2.58 KB
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-customize-nav-menu-setting.php
1<?php
2/**
3 * Customize API: WP_Customize_Nav_Menu_Setting class
4 *
5 * @package WordPress
6 * @subpackage Customize
7 * @since 4.4.0
8 */
9
10/**
11 * Customize Setting to represent a nav_menu.
12 *
13 * Subclass of WP_Customize_Setting to represent a nav_menu taxonomy term, and
14 * the IDs for the nav_menu_items associated with the nav menu.
15 *
16 * @since 4.3.0
17 *
18 * @see wp_get_nav_menu_object()
19 * @see WP_Customize_Setting
20 */
21class WP_Customize_Nav_Menu_Setting extends WP_Customize_Setting {
22
23 const ID_PATTERN = '/^nav_menu\[(?P<id>-?\d+)\]$/';
24
25 const TAXONOMY = 'nav_menu';
26
27 const TYPE = 'nav_menu';
28
29 /**
30 * Setting type.
31 *
32 * @since 4.3.0
33 * @var string
34 */
35 public $type = self::TYPE;
36
37 /**
38 * Default setting value.
39 *
40 * @since 4.3.0
41 * @var array
42 *
43 * @see wp_get_nav_menu_object()
44 */
45 public $default = array(
46 'name' => '',
47 'description' => '',
48 'parent' => 0,
49 'auto_add' => false,
50 );
51
52 /**
53 * Default transport.
54 *
55 * @since 4.3.0
56 * @var string
57 */
58 public $transport = 'postMessage';
59
60 /**
61 * The term ID represented by this setting instance.
62 *
63 * A negative value represents a placeholder ID for a new menu not yet saved.
64 *
65 * @since 4.3.0
66 * @var int
67 */
68 public $term_id;
69
70 /**
71 * Previous (placeholder) term ID used before creating a new menu.
72 *
73 * This value will be exported to JS via the {@see 'customize_save_response'} filter
74 * so that JavaScript can update the settings to refer to the newly-assigned
75 * term ID. This value is always negative to indicate it does not refer to
76 * a real term.
77 *
78 * @since 4.3.0
79 * @var int
80 *
81 * @see WP_Customize_Nav_Menu_Setting::update()
82 * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response()
83 */
84 public $previous_term_id;
85
86 /**
87 * Whether or not update() was called.
88 *
89 * @since 4.3.0
90 * @var bool
91 */
92 protected $is_updated = false;
93
94 /**
95 * Status for calling the update method, used in customize_save_response filter.
96 *
97 * See {@see 'customize_save_response'}.
98 *
99 * When status is inserted, the placeholder term ID is stored in `$previous_term_id`.
100 * When status is error, the error is stored in `$update_error`.
101 *
102 * @since 4.3.0
103 * @var string updated|inserted|deleted|error
104 *
105 * @see WP_Customize_Nav_Menu_Setting::update()
106 * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response()
107 */
108 public $update_status;
109
110 /**
111 * Any error object returned by wp_update_nav_menu_object() when setting is updated.
112 *
113 * @since 4.3.0
114 * @var WP_Error
115 *
116 * @see WP_Customize_Nav_Menu_Setting::update()
117 * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response()
118 */
119 public $update_error;
120
121 /**
122 * Constructor.
123 *
124 * Any supplied $args override class property defaults.
125 *
126 * @since 4.3.0
127 *
128 * @throws Exception If $id is not valid for this setting type.
129 *
130 * @param WP_Customize_Manager $manager Customizer bootstrap instance.
131 * @param string $id A specific ID of the setting.
132 * Can be a theme mod or option name.
133 * @param array $args Optional. Setting arguments.
134 */
135 public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) {
136 if ( empty( $manager->nav_menus ) ) {
137 throw new Exception( 'Expected WP_Customize_Manager::$nav_menus to be set.' );
138 }
139
140 if ( ! preg_match( self::ID_PATTERN, $id, $matches ) ) {
141 throw new Exception( "Illegal widget setting ID: $id" );
142 }
143
144 $this->term_id = (int) $matches['id'];
145
146 parent::__construct( $manager, $id, $args );
147 }
148
149 /**
150 * Get the instance data for a given widget setting.
151 *
152 * @since 4.3.0
153 *
154 * @see wp_get_nav_menu_object()
155 *
156 * @return array Instance data.
157 */
158 public function value() {
159 if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) {
160 $undefined = new stdClass(); // Symbol.
161 $post_value = $this->post_value( $undefined );
162
163 if ( $undefined === $post_value ) {
164 $value = $this->_original_value;
165 } else {
166 $value = $post_value;
167 }
168 } else {
169 $value = false;
170
171 // Note that a term_id of less than one indicates a nav_menu not yet inserted.
172 if ( $this->term_id > 0 ) {
173 $term = wp_get_nav_menu_object( $this->term_id );
174
175 if ( $term ) {
176 $value = wp_array_slice_assoc( (array) $term, array_keys( $this->default ) );
177
178 $nav_menu_options = (array) get_option( 'nav_menu_options', array() );
179 $value['auto_add'] = false;
180
181 if ( isset( $nav_menu_options['auto_add'] ) && is_array( $nav_menu_options['auto_add'] ) ) {
182 $value['auto_add'] = in_array( $term->term_id, $nav_menu_options['auto_add'], true );
183 }
184 }
185 }
186
187 if ( ! is_array( $value ) ) {
188 $value = $this->default;
189 }
190 }
191
192 return $value;
193 }
194
195 /**
196 * Handle previewing the setting.
197 *
198 * @since 4.3.0
199 * @since 4.4.0 Added boolean return value
200 *
201 * @see WP_Customize_Manager::post_value()
202 *
203 * @return bool False if method short-circuited due to no-op.
204 */
205 public function preview() {
206 if ( $this->is_previewed ) {
207 return false;
208 }
209
210 $undefined = new stdClass();
211 $is_placeholder = ( $this->term_id < 0 );
212 $is_dirty = ( $undefined !== $this->post_value( $undefined ) );
213 if ( ! $is_placeholder && ! $is_dirty ) {
214 return false;
215 }
216
217 $this->is_previewed = true;
218 $this->_original_value = $this->value();
219 $this->_previewed_blog_id = get_current_blog_id();
220
221 add_filter( 'wp_get_nav_menus', array( $this, 'filter_wp_get_nav_menus' ), 10, 2 );
222 add_filter( 'wp_get_nav_menu_object', array( $this, 'filter_wp_get_nav_menu_object' ), 10, 2 );
223 add_filter( 'default_option_nav_menu_options', array( $this, 'filter_nav_menu_options' ) );
224 add_filter( 'option_nav_menu_options', array( $this, 'filter_nav_menu_options' ) );
225
226 return true;
227 }
228
229 /**
230 * Filters the wp_get_nav_menus() result to ensure the inserted menu object is included, and the deleted one is removed.
231 *
232 * @since 4.3.0
233 *
234 * @see wp_get_nav_menus()
235 *
236 * @param WP_Term[] $menus An array of menu objects.
237 * @param array $args An array of arguments used to retrieve menu objects.
238 * @return WP_Term[] Array of menu objects.
239 */
240 public function filter_wp_get_nav_menus( $menus, $args ) {
241 if ( get_current_blog_id() !== $this->_previewed_blog_id ) {
242 return $menus;
243 }
244
245 $setting_value = $this->value();
246 $is_delete = ( false === $setting_value );
247 $index = -1;
248
249 // Find the existing menu item's position in the list.
250 foreach ( $menus as $i => $menu ) {
251 if ( (int) $this->term_id === (int) $menu->term_id || (int) $this->previous_term_id === (int) $menu->term_id ) {
252 $index = $i;
253 break;
254 }
255 }
256
257 if ( $is_delete ) {
258 // Handle deleted menu by removing it from the list.
259 if ( -1 !== $index ) {
260 array_splice( $menus, $index, 1 );
261 }
262 } else {
263 // Handle menus being updated or inserted.
264 $menu_obj = (object) array_merge(
265 array(
266 'term_id' => $this->term_id,
267 'term_taxonomy_id' => $this->term_id,
268 'slug' => sanitize_title( $setting_value['name'] ),
269 'count' => 0,
270 'term_group' => 0,
271 'taxonomy' => self::TAXONOMY,
272 'filter' => 'raw',
273 ),
274 $setting_value
275 );
276
277 array_splice( $menus, $index, ( -1 === $index ? 0 : 1 ), array( $menu_obj ) );
278 }
279
280 // Make sure the menu objects get re-sorted after an update/insert.
281 if ( ! $is_delete && ! empty( $args['orderby'] ) ) {
282 $menus = wp_list_sort(
283 $menus,
284 array(
285 $args['orderby'] => 'ASC',
286 )
287 );
288 }
289 // @todo Add support for $args['hide_empty'] === true.
290
291 return $menus;
292 }
293
294 /**
295 * Temporary non-closure passing of orderby value to function.
296 *
297 * @since 4.3.0
298 * @var string
299 *
300 * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus()
301 * @see WP_Customize_Nav_Menu_Setting::_sort_menus_by_orderby()
302 */
303 protected $_current_menus_sort_orderby;
304
305 /**
306 * Sort menu objects by the class-supplied orderby property.
307 *
308 * This is a workaround for a lack of closures.
309 *
310 * @since 4.3.0
311 * @deprecated 4.7.0 Use wp_list_sort()
312 *
313 * @param object $menu1
314 * @param object $menu2
315 * @return int
316 *
317 * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus()
318 */
319 protected function _sort_menus_by_orderby( $menu1, $menu2 ) {
320 _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' );
321
322 $key = $this->_current_menus_sort_orderby;
323 return strcmp( $menu1->$key, $menu2->$key );
324 }
325
326 /**
327 * Filters the wp_get_nav_menu_object() result to supply the previewed menu object.
328 *
329 * Requesting a nav_menu object by anything but ID is not supported.
330 *
331 * @since 4.3.0
332 *
333 * @see wp_get_nav_menu_object()
334 *
335 * @param object|null $menu_obj Object returned by wp_get_nav_menu_object().
336 * @param string $menu_id ID of the nav_menu term. Requests by slug or name will be ignored.
337 * @return object|null
338 */
339 public function filter_wp_get_nav_menu_object( $menu_obj, $menu_id ) {
340 $ok = (
341 get_current_blog_id() === $this->_previewed_blog_id
342 &&
343 is_int( $menu_id )
344 &&
345 $menu_id === $this->term_id
346 );
347 if ( ! $ok ) {
348 return $menu_obj;
349 }
350
351 $setting_value = $this->value();
352
353 // Handle deleted menus.
354 if ( false === $setting_value ) {
355 return false;
356 }
357
358 // Handle sanitization failure by preventing short-circuiting.
359 if ( null === $setting_value ) {
360 return $menu_obj;
361 }
362
363 $menu_obj = (object) array_merge(
364 array(
365 'term_id' => $this->term_id,
366 'term_taxonomy_id' => $this->term_id,
367 'slug' => sanitize_title( $setting_value['name'] ),
368 'count' => 0,
369 'term_group' => 0,
370 'taxonomy' => self::TAXONOMY,
371 'filter' => 'raw',
372 ),
373 $setting_value
374 );
375
376 return $menu_obj;
377 }
378
379 /**
380 * Filters the nav_menu_options option to include this menu's auto_add preference.
381 *
382 * @since 4.3.0
383 *
384 * @param array $nav_menu_options Nav menu options including auto_add.
385 * @return array (Maybe) modified nav menu options.
386 */
387 public function filter_nav_menu_options( $nav_menu_options ) {
388 if ( get_current_blog_id() !== $this->_previewed_blog_id ) {
389 return $nav_menu_options;
390 }
391
392 $menu = $this->value();
393 $nav_menu_options = $this->filter_nav_menu_options_value(
394 $nav_menu_options,
395 $this->term_id,
396 false === $menu ? false : $menu['auto_add']
397 );
398
399 return $nav_menu_options;
400 }
401
402 /**
403 * Sanitize an input.
404 *
405 * Note that parent::sanitize() erroneously does wp_unslash() on $value, but
406 * we remove that in this override.
407 *
408 * @since 4.3.0
409 *
410 * @param array $value The menu value to sanitize.
411 * @return array|false|null Null if an input isn't valid. False if it is marked for deletion.
412 * Otherwise the sanitized value.
413 */
414 public function sanitize( $value ) {
415 // Menu is marked for deletion.
416 if ( false === $value ) {
417 return $value;
418 }
419
420 // Invalid.
421 if ( ! is_array( $value ) ) {
422 return null;
423 }
424
425 $default = array(
426 'name' => '',
427 'description' => '',
428 'parent' => 0,
429 'auto_add' => false,
430 );
431 $value = array_merge( $default, $value );
432 $value = wp_array_slice_assoc( $value, array_keys( $default ) );
433
434 $value['name'] = trim( esc_html( $value['name'] ) ); // This sanitization code is used in wp-admin/nav-menus.php.
435 $value['description'] = sanitize_text_field( $value['description'] );
436 $value['parent'] = max( 0, (int) $value['parent'] );
437 $value['auto_add'] = ! empty( $value['auto_add'] );
438
439 if ( '' === $value['name'] ) {
440 $value['name'] = _x( '(unnamed)', 'Missing menu name.' );
441 }
442
443 /** This filter is documented in wp-includes/class-wp-customize-setting.php */
444 return apply_filters( "customize_sanitize_{$this->id}", $value, $this );
445 }
446
447 /**
448 * Storage for data to be sent back to client in customize_save_response filter.
449 *
450 * See {@see 'customize_save_response'}.
451 *
452 * @since 4.3.0
453 * @var array
454 *
455 * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response()
456 */
457 protected $_widget_nav_menu_updates = array();
458
459 /**
460 * Create/update the nav_menu term for this setting.
461 *
462 * Any created menus will have their assigned term IDs exported to the client
463 * via the {@see 'customize_save_response'} filter. Likewise, any errors will be exported
464 * to the client via the customize_save_response() filter.
465 *
466 * To delete a menu, the client can send false as the value.
467 *
468 * @since 4.3.0
469 *
470 * @see wp_update_nav_menu_object()
471 *
472 * @param array|false $value {
473 * The value to update. Note that slug cannot be updated via wp_update_nav_menu_object().
474 * If false, then the menu will be deleted entirely.
475 *
476 * @type string $name The name of the menu to save.
477 * @type string $description The term description. Default empty string.
478 * @type int $parent The id of the parent term. Default 0.
479 * @type bool $auto_add Whether pages will auto_add to this menu. Default false.
480 * }
481 * @return null|void
482 */
483 protected function update( $value ) {
484 if ( $this->is_updated ) {
485 return;
486 }
487
488 $this->is_updated = true;
489 $is_placeholder = ( $this->term_id < 0 );
490 $is_delete = ( false === $value );
491
492 add_filter( 'customize_save_response', array( $this, 'amend_customize_save_response' ) );
493
494 $auto_add = null;
495 if ( $is_delete ) {
496 // If the current setting term is a placeholder, a delete request is a no-op.
497 if ( $is_placeholder ) {
498 $this->update_status = 'deleted';
499 } else {
500 $r = wp_delete_nav_menu( $this->term_id );
501
502 if ( is_wp_error( $r ) ) {
503 $this->update_status = 'error';
504 $this->update_error = $r;
505 } else {
506 $this->update_status = 'deleted';
507 $auto_add = false;
508 }
509 }
510 } else {
511 // Insert or update menu.
512 $menu_data = wp_array_slice_assoc( $value, array( 'description', 'parent' ) );
513 $menu_data['menu-name'] = $value['name'];
514
515 $menu_id = $is_placeholder ? 0 : $this->term_id;
516 $r = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) );
517 $original_name = $menu_data['menu-name'];
518 $name_conflict_suffix = 1;
519 while ( is_wp_error( $r ) && 'menu_exists' === $r->get_error_code() ) {
520 $name_conflict_suffix += 1;
521 /* translators: 1: Original menu name, 2: Duplicate count. */
522 $menu_data['menu-name'] = sprintf( __( '%1$s (%2$d)' ), $original_name, $name_conflict_suffix );
523 $r = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) );
524 }
525
526 if ( is_wp_error( $r ) ) {
527 $this->update_status = 'error';
528 $this->update_error = $r;
529 } else {
530 if ( $is_placeholder ) {
531 $this->previous_term_id = $this->term_id;
532 $this->term_id = $r;
533 $this->update_status = 'inserted';
534 } else {
535 $this->update_status = 'updated';
536 }
537
538 $auto_add = $value['auto_add'];
539 }
540 }
541
542 if ( null !== $auto_add ) {
543 $nav_menu_options = $this->filter_nav_menu_options_value(
544 (array) get_option( 'nav_menu_options', array() ),
545 $this->term_id,
546 $auto_add
547 );
548 update_option( 'nav_menu_options', $nav_menu_options );
549 }
550
551 if ( 'inserted' === $this->update_status ) {
552 // Make sure that new menus assigned to nav menu locations use their new IDs.
553 foreach ( $this->manager->settings() as $setting ) {
554 if ( ! preg_match( '/^nav_menu_locations\[/', $setting->id ) ) {
555 continue;
556 }
557
558 $post_value = $setting->post_value( null );
559 if ( ! is_null( $post_value ) && (int) $post_value === $this->previous_term_id ) {
560 $this->manager->set_post_value( $setting->id, $this->term_id );
561 $setting->save();
562 }
563 }
564
565 // Make sure that any nav_menu widgets referencing the placeholder nav menu get updated and sent back to client.
566 foreach ( array_keys( $this->manager->unsanitized_post_values() ) as $setting_id ) {
567 $nav_menu_widget_setting = $this->manager->get_setting( $setting_id );
568 if ( ! $nav_menu_widget_setting || ! preg_match( '/^widget_nav_menu\[/', $nav_menu_widget_setting->id ) ) {
569 continue;
570 }
571
572 $widget_instance = $nav_menu_widget_setting->post_value(); // Note that this calls WP_Customize_Widgets::sanitize_widget_instance().
573 if ( empty( $widget_instance['nav_menu'] ) || (int) $widget_instance['nav_menu'] !== $this->previous_term_id ) {
574 continue;
575 }
576
577 $widget_instance['nav_menu'] = $this->term_id;
578 $updated_widget_instance = $this->manager->widgets->sanitize_widget_js_instance( $widget_instance );
579 $this->manager->set_post_value( $nav_menu_widget_setting->id, $updated_widget_instance );
580 $nav_menu_widget_setting->save();
581
582 $this->_widget_nav_menu_updates[ $nav_menu_widget_setting->id ] = $updated_widget_instance;
583 }
584 }
585 }
586
587 /**
588 * Updates a nav_menu_options array.
589 *
590 * @since 4.3.0
591 *
592 * @see WP_Customize_Nav_Menu_Setting::filter_nav_menu_options()
593 * @see WP_Customize_Nav_Menu_Setting::update()
594 *
595 * @param array $nav_menu_options Array as returned by get_option( 'nav_menu_options' ).
596 * @param int $menu_id The term ID for the given menu.
597 * @param bool $auto_add Whether to auto-add or not.
598 * @return array (Maybe) modified nav_menu_options array.
599 */
600 protected function filter_nav_menu_options_value( $nav_menu_options, $menu_id, $auto_add ) {
601 $nav_menu_options = (array) $nav_menu_options;
602 if ( ! isset( $nav_menu_options['auto_add'] ) ) {
603 $nav_menu_options['auto_add'] = array();
604 }
605
606 $i = array_search( $menu_id, $nav_menu_options['auto_add'], true );
607
608 if ( $auto_add && false === $i ) {
609 array_push( $nav_menu_options['auto_add'], $this->term_id );
610 } elseif ( ! $auto_add && false !== $i ) {
611 array_splice( $nav_menu_options['auto_add'], $i, 1 );
612 }
613
614 return $nav_menu_options;
615 }
616
617 /**
618 * Export data for the JS client.
619 *
620 * @since 4.3.0
621 *
622 * @see WP_Customize_Nav_Menu_Setting::update()
623 *
624 * @param array $data Additional information passed back to the 'saved' event on `wp.customize`.
625 * @return array Export data.
626 */
627 public function amend_customize_save_response( $data ) {
628 if ( ! isset( $data['nav_menu_updates'] ) ) {
629 $data['nav_menu_updates'] = array();
630 }
631 if ( ! isset( $data['widget_nav_menu_updates'] ) ) {
632 $data['widget_nav_menu_updates'] = array();
633 }
634
635 $data['nav_menu_updates'][] = array(
636 'term_id' => $this->term_id,
637 'previous_term_id' => $this->previous_term_id,
638 'error' => $this->update_error ? $this->update_error->get_error_code() : null,
639 'status' => $this->update_status,
640 'saved_value' => 'deleted' === $this->update_status ? null : $this->value(),
641 );
642
643 $data['widget_nav_menu_updates'] = array_merge(
644 $data['widget_nav_menu_updates'],
645 $this->_widget_nav_menu_updates
646 );
647 $this->_widget_nav_menu_updates = array();
648
649 return $data;
650 }
651}
652
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1