WordPress.org

Make WordPress Core

source: tags/4.4/tests/phpunit/includes/testcase.php

Last change on this file was 35350, checked in by johnbillion, 2 years ago

Initialise $_SERVER['SERVER_NAME'] during the test bootstrap to avoid individual tests having to do it.

Fixes #34394

File size: 20.6 KB
Line 
1<?php
2
3require_once dirname( __FILE__ ) . '/factory.php';
4require_once dirname( __FILE__ ) . '/trac.php';
5
6class WP_UnitTestCase extends PHPUnit_Framework_TestCase {
7
8        protected static $forced_tickets = array();
9        protected $expected_deprecated = array();
10        protected $caught_deprecated = array();
11        protected $expected_doing_it_wrong = array();
12        protected $caught_doing_it_wrong = array();
13
14        protected static $hooks_saved = array();
15        protected static $ignore_files;
16
17        function __isset( $name ) {
18                return 'factory' === $name;
19        }
20
21        function __get( $name ) {
22                if ( 'factory' === $name ) {
23                        return self::factory();
24            }
25        }
26
27        protected static function factory() {
28                static $factory = null;
29                if ( ! $factory ) {
30                        $factory = new WP_UnitTest_Factory();
31                }
32                return $factory;
33        }
34
35        public static function get_called_class() {
36                if ( function_exists( 'get_called_class' ) ) {
37                        return get_called_class();
38                }
39
40                // PHP 5.2 only
41                $backtrace = debug_backtrace();
42                // [0] WP_UnitTestCase::get_called_class()
43                // [1] WP_UnitTestCase::setUpBeforeClass()
44                if ( 'call_user_func' ===  $backtrace[2]['function'] ) {
45                        return $backtrace[2]['args'][0][0];
46                }
47                return $backtrace[2]['class'];
48        }
49
50        public static function setUpBeforeClass() {
51                parent::setUpBeforeClass();
52
53                $c = self::get_called_class();
54                if ( ! method_exists( $c, 'wpSetUpBeforeClass' ) ) {
55                        return;
56                }
57
58                call_user_func( array( $c, 'wpSetUpBeforeClass' ), self::factory() );
59
60                self::commit_transaction();
61        }
62
63        public static function tearDownAfterClass() {
64                parent::tearDownAfterClass();
65
66                $c = self::get_called_class();
67                if ( ! method_exists( $c, 'wpTearDownAfterClass' ) ) {
68                        return;
69                }
70
71                call_user_func( array( $c, 'wpTearDownAfterClass' ) );
72
73                self::commit_transaction();
74        }
75
76        function setUp() {
77                set_time_limit(0);
78
79                if ( ! self::$ignore_files ) {
80                        self::$ignore_files = $this->scan_user_uploads();
81                }
82
83                if ( ! self::$hooks_saved ) {
84                        $this->_backup_hooks();
85                }
86
87                global $wpdb, $wp_rewrite;
88                $wpdb->suppress_errors = false;
89                $wpdb->show_errors = true;
90                $wpdb->db_connect();
91                ini_set('display_errors', 1 );
92                $this->clean_up_global_scope();
93
94                /*
95                 * When running core tests, ensure that post types and taxonomies
96                 * are reset for each test. We skip this step for non-core tests,
97                 * given the large number of plugins that register post types and
98                 * taxonomies at 'init'.
99                 */
100                if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) {
101                        $this->reset_post_types();
102                        $this->reset_taxonomies();
103                        $this->reset_post_statuses();
104
105                        if ( $wp_rewrite->permalink_structure ) {
106                                $this->set_permalink_structure( '' );
107                        }
108                }
109
110                $this->start_transaction();
111                $this->expectDeprecated();
112                add_filter( 'wp_die_handler', array( $this, 'get_wp_die_handler' ) );
113        }
114
115        /**
116         * Detect post-test failure conditions.
117         *
118         * We use this method to detect expectedDeprecated and expectedIncorrectUsage annotations.
119         *
120         * @since 4.2.0
121         */
122        protected function assertPostConditions() {
123                $this->expectedDeprecated();
124        }
125
126        function tearDown() {
127                global $wpdb, $wp_query, $wp, $post;
128                $wpdb->query( 'ROLLBACK' );
129                if ( is_multisite() ) {
130                        while ( ms_is_switched() ) {
131                                restore_current_blog();
132                        }
133                }
134                $wp_query = new WP_Query();
135                $wp = new WP();
136                $post = null;
137                remove_theme_support( 'html5' );
138                remove_filter( 'query', array( $this, '_create_temporary_tables' ) );
139                remove_filter( 'query', array( $this, '_drop_temporary_tables' ) );
140                remove_filter( 'wp_die_handler', array( $this, 'get_wp_die_handler' ) );
141                $this->_restore_hooks();
142                wp_set_current_user( 0 );
143        }
144
145        function clean_up_global_scope() {
146                $_GET = array();
147                $_POST = array();
148                $this->flush_cache();
149        }
150
151        /**
152         * Unregister existing post types and register defaults.
153         *
154         * Run before each test in order to clean up the global scope, in case
155         * a test forgets to unregister a post type on its own, or fails before
156         * it has a chance to do so.
157         */
158        protected function reset_post_types() {
159                foreach ( get_post_types() as $pt ) {
160                        _unregister_post_type( $pt );
161                }
162                create_initial_post_types();
163        }
164
165        /**
166         * Unregister existing taxonomies and register defaults.
167         *
168         * Run before each test in order to clean up the global scope, in case
169         * a test forgets to unregister a taxonomy on its own, or fails before
170         * it has a chance to do so.
171         */
172        protected function reset_taxonomies() {
173                foreach ( get_taxonomies() as $tax ) {
174                        _unregister_taxonomy( $tax );
175                }
176                create_initial_taxonomies();
177        }
178
179        /**
180         * Unregister non-built-in post statuses.
181         */
182        protected function reset_post_statuses() {
183                foreach ( get_post_stati( array( '_builtin' => false ) ) as $post_status ) {
184                        _unregister_post_status( $post_status );
185                }
186        }
187
188        /**
189         * Saves the action and filter-related globals so they can be restored later.
190         *
191         * Stores $merged_filters, $wp_actions, $wp_current_filter, and $wp_filter
192         * on a class variable so they can be restored on tearDown() using _restore_hooks().
193         *
194         * @global array $merged_filters
195         * @global array $wp_actions
196         * @global array $wp_current_filter
197         * @global array $wp_filter
198         * @return void
199         */
200        protected function _backup_hooks() {
201                $globals = array( 'merged_filters', 'wp_actions', 'wp_current_filter', 'wp_filter' );
202                foreach ( $globals as $key ) {
203                        self::$hooks_saved[ $key ] = $GLOBALS[ $key ];
204                }
205        }
206
207        /**
208         * Restores the hook-related globals to their state at setUp()
209         * so that future tests aren't affected by hooks set during this last test.
210         *
211         * @global array $merged_filters
212         * @global array $wp_actions
213         * @global array $wp_current_filter
214         * @global array $wp_filter
215         * @return void
216         */
217        protected function _restore_hooks() {
218                $globals = array( 'merged_filters', 'wp_actions', 'wp_current_filter', 'wp_filter' );
219                foreach ( $globals as $key ) {
220                        if ( isset( self::$hooks_saved[ $key ] ) ) {
221                                $GLOBALS[ $key ] = self::$hooks_saved[ $key ];
222                        }
223                }
224        }
225
226        function flush_cache() {
227                global $wp_object_cache;
228                $wp_object_cache->group_ops = array();
229                $wp_object_cache->stats = array();
230                $wp_object_cache->memcache_debug = array();
231                $wp_object_cache->cache = array();
232                if ( method_exists( $wp_object_cache, '__remoteset' ) ) {
233                        $wp_object_cache->__remoteset();
234                }
235                wp_cache_flush();
236                wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) );
237                wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
238        }
239
240        function start_transaction() {
241                global $wpdb;
242                $wpdb->query( 'SET autocommit = 0;' );
243                $wpdb->query( 'START TRANSACTION;' );
244                add_filter( 'query', array( $this, '_create_temporary_tables' ) );
245                add_filter( 'query', array( $this, '_drop_temporary_tables' ) );
246        }
247
248        /**
249         * Commit the queries in a transaction.
250         *
251         * @since 4.1.0
252         */
253        public static function commit_transaction() {
254                global $wpdb;
255                $wpdb->query( 'COMMIT;' );
256        }
257
258        function _create_temporary_tables( $query ) {
259                if ( 'CREATE TABLE' === substr( trim( $query ), 0, 12 ) )
260                        return substr_replace( trim( $query ), 'CREATE TEMPORARY TABLE', 0, 12 );
261                return $query;
262        }
263
264        function _drop_temporary_tables( $query ) {
265                if ( 'DROP TABLE' === substr( trim( $query ), 0, 10 ) )
266                        return substr_replace( trim( $query ), 'DROP TEMPORARY TABLE', 0, 10 );
267                return $query;
268        }
269
270        function get_wp_die_handler( $handler ) {
271                return array( $this, 'wp_die_handler' );
272        }
273
274        function wp_die_handler( $message ) {
275                throw new WPDieException( $message );
276        }
277
278        function expectDeprecated() {
279                $annotations = $this->getAnnotations();
280                foreach ( array( 'class', 'method' ) as $depth ) {
281                        if ( ! empty( $annotations[ $depth ]['expectedDeprecated'] ) )
282                                $this->expected_deprecated = array_merge( $this->expected_deprecated, $annotations[ $depth ]['expectedDeprecated'] );
283                        if ( ! empty( $annotations[ $depth ]['expectedIncorrectUsage'] ) )
284                                $this->expected_doing_it_wrong = array_merge( $this->expected_doing_it_wrong, $annotations[ $depth ]['expectedIncorrectUsage'] );
285                }
286                add_action( 'deprecated_function_run', array( $this, 'deprecated_function_run' ) );
287                add_action( 'deprecated_argument_run', array( $this, 'deprecated_function_run' ) );
288                add_action( 'doing_it_wrong_run', array( $this, 'doing_it_wrong_run' ) );
289                add_action( 'deprecated_function_trigger_error', '__return_false' );
290                add_action( 'deprecated_argument_trigger_error', '__return_false' );
291                add_action( 'doing_it_wrong_trigger_error',      '__return_false' );
292        }
293
294        function expectedDeprecated() {
295                $errors = array();
296
297                $not_caught_deprecated = array_diff( $this->expected_deprecated, $this->caught_deprecated );
298                foreach ( $not_caught_deprecated as $not_caught ) {
299                        $errors[] = "Failed to assert that $not_caught triggered a deprecated notice";
300                }
301
302                $unexpected_deprecated = array_diff( $this->caught_deprecated, $this->expected_deprecated );
303                foreach ( $unexpected_deprecated as $unexpected ) {
304                        $errors[] = "Unexpected deprecated notice for $unexpected";
305                }
306
307                $not_caught_doing_it_wrong = array_diff( $this->expected_doing_it_wrong, $this->caught_doing_it_wrong );
308                foreach ( $not_caught_doing_it_wrong as $not_caught ) {
309                        $errors[] = "Failed to assert that $not_caught triggered an incorrect usage notice";
310                }
311
312                $unexpected_doing_it_wrong = array_diff( $this->caught_doing_it_wrong, $this->expected_doing_it_wrong );
313                foreach ( $unexpected_doing_it_wrong as $unexpected ) {
314                        $errors[] = "Unexpected incorrect usage notice for $unexpected";
315                }
316
317                if ( ! empty( $errors ) ) {
318                        $this->fail( implode( "\n", $errors ) );
319                }
320        }
321
322        /**
323         * Declare an expected `_deprecated_function()` or `_deprecated_argument()` call from within a test.
324         *
325         * @since 4.2.0
326         *
327         * @param string $deprecated Name of the function, method, class, or argument that is deprecated. Must match
328         *                           first parameter of the `_deprecated_function()` or `_deprecated_argument()` call.
329         */
330        public function setExpectedDeprecated( $deprecated ) {
331                array_push( $this->expected_deprecated, $deprecated );
332        }
333
334        /**
335         * Declare an expected `_doing_it_wrong()` call from within a test.
336         *
337         * @since 4.2.0
338         *
339         * @param string $deprecated Name of the function, method, or class that appears in the first argument of the
340         *                           source `_doing_it_wrong()` call.
341         */
342        public function setExpectedIncorrectUsage( $doing_it_wrong ) {
343                array_push( $this->expected_doing_it_wrong, $doing_it_wrong );
344        }
345
346        function deprecated_function_run( $function ) {
347                if ( ! in_array( $function, $this->caught_deprecated ) )
348                        $this->caught_deprecated[] = $function;
349        }
350
351        function doing_it_wrong_run( $function ) {
352                if ( ! in_array( $function, $this->caught_doing_it_wrong ) )
353                        $this->caught_doing_it_wrong[] = $function;
354        }
355
356        function assertWPError( $actual, $message = '' ) {
357                $this->assertInstanceOf( 'WP_Error', $actual, $message );
358        }
359
360        function assertNotWPError( $actual, $message = '' ) {
361                if ( is_wp_error( $actual ) && '' === $message ) {
362                        $message = $actual->get_error_message();
363                }
364                $this->assertNotInstanceOf( 'WP_Error', $actual, $message );
365        }
366
367        function assertEqualFields( $object, $fields ) {
368                foreach( $fields as $field_name => $field_value ) {
369                        if ( $object->$field_name != $field_value ) {
370                                $this->fail();
371                        }
372                }
373        }
374
375        function assertDiscardWhitespace( $expected, $actual ) {
376                $this->assertEquals( preg_replace( '/\s*/', '', $expected ), preg_replace( '/\s*/', '', $actual ) );
377        }
378
379        function assertEqualSets( $expected, $actual ) {
380                sort( $expected );
381                sort( $actual );
382                $this->assertEquals( $expected, $actual );
383        }
384
385        function assertEqualSetsWithIndex( $expected, $actual ) {
386                ksort( $expected );
387                ksort( $actual );
388                $this->assertEquals( $expected, $actual );
389        }
390
391        function go_to( $url ) {
392                // note: the WP and WP_Query classes like to silently fetch parameters
393                // from all over the place (globals, GET, etc), which makes it tricky
394                // to run them more than once without very carefully clearing everything
395                $_GET = $_POST = array();
396                foreach (array('query_string', 'id', 'postdata', 'authordata', 'day', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages', 'pagenow') as $v) {
397                        if ( isset( $GLOBALS[$v] ) ) unset( $GLOBALS[$v] );
398                }
399                $parts = parse_url($url);
400                if (isset($parts['scheme'])) {
401                        $req = isset( $parts['path'] ) ? $parts['path'] : '';
402                        if (isset($parts['query'])) {
403                                $req .= '?' . $parts['query'];
404                                // parse the url query vars into $_GET
405                                parse_str($parts['query'], $_GET);
406                        }
407                } else {
408                        $req = $url;
409                }
410                if ( ! isset( $parts['query'] ) ) {
411                        $parts['query'] = '';
412                }
413
414                $_SERVER['REQUEST_URI'] = $req;
415                unset($_SERVER['PATH_INFO']);
416
417                $this->flush_cache();
418                unset($GLOBALS['wp_query'], $GLOBALS['wp_the_query']);
419                $GLOBALS['wp_the_query'] = new WP_Query();
420                $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
421
422                $public_query_vars  = $GLOBALS['wp']->public_query_vars;
423                $private_query_vars = $GLOBALS['wp']->private_query_vars;
424
425                $GLOBALS['wp'] = new WP();
426                $GLOBALS['wp']->public_query_vars  = $public_query_vars;
427                $GLOBALS['wp']->private_query_vars = $private_query_vars;
428
429                _cleanup_query_vars();
430
431                $GLOBALS['wp']->main($parts['query']);
432        }
433
434        protected function checkRequirements() {
435                parent::checkRequirements();
436
437                // Core tests no longer check against open Trac tickets, but others using WP_UnitTestCase may do so.
438                if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) {
439                        return;
440                }
441
442                if ( WP_TESTS_FORCE_KNOWN_BUGS )
443                        return;
444                $tickets = PHPUnit_Util_Test::getTickets( get_class( $this ), $this->getName( false ) );
445                foreach ( $tickets as $ticket ) {
446                        if ( is_numeric( $ticket ) ) {
447                                $this->knownWPBug( $ticket );
448                        } elseif ( 'UT' == substr( $ticket, 0, 2 ) ) {
449                                $ticket = substr( $ticket, 2 );
450                                if ( $ticket && is_numeric( $ticket ) )
451                                        $this->knownUTBug( $ticket );
452                        } elseif ( 'Plugin' == substr( $ticket, 0, 6 ) ) {
453                                $ticket = substr( $ticket, 6 );
454                                if ( $ticket && is_numeric( $ticket ) )
455                                        $this->knownPluginBug( $ticket );
456                        }
457                }
458        }
459
460        /**
461         * Skips the current test if there is an open WordPress ticket with id $ticket_id
462         */
463        function knownWPBug( $ticket_id ) {
464                if ( WP_TESTS_FORCE_KNOWN_BUGS || in_array( $ticket_id, self::$forced_tickets ) )
465                        return;
466                if ( ! TracTickets::isTracTicketClosed( 'https://core.trac.wordpress.org', $ticket_id ) )
467                        $this->markTestSkipped( sprintf( 'WordPress Ticket #%d is not fixed', $ticket_id ) );
468        }
469
470        /**
471         * Skips the current test if there is an open unit tests ticket with id $ticket_id
472         */
473        function knownUTBug( $ticket_id ) {
474                if ( WP_TESTS_FORCE_KNOWN_BUGS || in_array( 'UT' . $ticket_id, self::$forced_tickets ) )
475                        return;
476                if ( ! TracTickets::isTracTicketClosed( 'https://unit-tests.trac.wordpress.org', $ticket_id ) )
477                        $this->markTestSkipped( sprintf( 'Unit Tests Ticket #%d is not fixed', $ticket_id ) );
478        }
479
480        /**
481         * Skips the current test if there is an open plugin ticket with id $ticket_id
482         */
483        function knownPluginBug( $ticket_id ) {
484                if ( WP_TESTS_FORCE_KNOWN_BUGS || in_array( 'Plugin' . $ticket_id, self::$forced_tickets ) )
485                        return;
486                if ( ! TracTickets::isTracTicketClosed( 'https://plugins.trac.wordpress.org', $ticket_id ) )
487                        $this->markTestSkipped( sprintf( 'WordPress Plugin Ticket #%d is not fixed', $ticket_id ) );
488        }
489
490        public static function forceTicket( $ticket ) {
491                self::$forced_tickets[] = $ticket;
492        }
493
494        /**
495         * Define constants after including files.
496         */
497        function prepareTemplate( Text_Template $template ) {
498                $template->setVar( array( 'constants' => '' ) );
499                $template->setVar( array( 'wp_constants' => PHPUnit_Util_GlobalState::getConstantsAsString() ) );
500                parent::prepareTemplate( $template );
501        }
502
503        /**
504         * Returns the name of a temporary file
505         */
506        function temp_filename() {
507                $tmp_dir = '';
508                $dirs = array( 'TMP', 'TMPDIR', 'TEMP' );
509                foreach( $dirs as $dir )
510                        if ( isset( $_ENV[$dir] ) && !empty( $_ENV[$dir] ) ) {
511                                $tmp_dir = $dir;
512                                break;
513                        }
514                if ( empty( $tmp_dir ) ) {
515                        $tmp_dir = '/tmp';
516                }
517                $tmp_dir = realpath( $tmp_dir );
518                return tempnam( $tmp_dir, 'wpunit' );
519        }
520
521        /**
522         * Check each of the WP_Query is_* functions/properties against expected boolean value.
523         *
524         * Any properties that are listed by name as parameters will be expected to be true; any others are
525         * expected to be false. For example, assertQueryTrue('is_single', 'is_feed') means is_single()
526         * and is_feed() must be true and everything else must be false to pass.
527         *
528         * @param string $prop,... Any number of WP_Query properties that are expected to be true for the current request.
529         */
530        function assertQueryTrue(/* ... */) {
531                global $wp_query;
532                $all = array(
533                        'is_404',
534                        'is_admin',
535                        'is_archive',
536                        'is_attachment',
537                        'is_author',
538                        'is_category',
539                        'is_comment_feed',
540                        'is_comments_popup',
541                        'is_date',
542                        'is_day',
543                        'is_embed',
544                        'is_feed',
545                        'is_home',
546                        'is_month',
547                        'is_page',
548                        'is_paged',
549                        'is_post_type_archive',
550                        'is_posts_page',
551                        'is_preview',
552                        'is_robots',
553                        'is_search',
554                        'is_single',
555                        'is_singular',
556                        'is_tag',
557                        'is_tax',
558                        'is_time',
559                        'is_trackback',
560                        'is_year',
561                );
562                $true = func_get_args();
563
564                $passed = true;
565                $not_false = $not_true = array(); // properties that were not set to expected values
566
567                foreach ( $all as $query_thing ) {
568                        $result = is_callable( $query_thing ) ? call_user_func( $query_thing ) : $wp_query->$query_thing;
569
570                        if ( in_array( $query_thing, $true ) ) {
571                                if ( ! $result ) {
572                                        array_push( $not_true, $query_thing );
573                                        $passed = false;
574                                }
575                        } else if ( $result ) {
576                                array_push( $not_false, $query_thing );
577                                $passed = false;
578                        }
579                }
580
581                $message = '';
582                if ( count($not_true) )
583                        $message .= implode( $not_true, ', ' ) . ' is expected to be true. ';
584                if ( count($not_false) )
585                        $message .= implode( $not_false, ', ' ) . ' is expected to be false.';
586                $this->assertTrue( $passed, $message );
587        }
588
589        function unlink( $file ) {
590                $exists = is_file( $file );
591                if ( $exists && ! in_array( $file, self::$ignore_files ) ) {
592                        //error_log( $file );
593                        unlink( $file );
594                } elseif ( ! $exists ) {
595                        $this->fail( "Trying to delete a file that doesn't exist: $file" );
596                }
597        }
598
599        function rmdir( $path ) {
600                $files = $this->files_in_dir( $path );
601                foreach ( $files as $file ) {
602                        if ( ! in_array( $file, self::$ignore_files ) ) {
603                                $this->unlink( $file );
604                        }
605                }
606        }
607
608        function remove_added_uploads() {
609                // Remove all uploads.
610                $uploads = wp_upload_dir();
611                $this->rmdir( $uploads['basedir'] );
612        }
613
614        function files_in_dir( $dir ) {
615                $files = array();
616
617                $iterator = new RecursiveDirectoryIterator( $dir );
618                $objects = new RecursiveIteratorIterator( $iterator );
619                foreach ( $objects as $name => $object ) {
620                        if ( is_file( $name ) ) {
621                                $files[] = $name;
622                        }
623                }
624
625                return $files;
626        }
627
628        function scan_user_uploads() {
629                static $files = array();
630                if ( ! empty( $files ) ) {
631                        return $files;
632                }
633
634                $uploads = wp_upload_dir();
635                $files = $this->files_in_dir( $uploads['basedir'] );
636                return $files;
637        }
638
639        function delete_folders( $path ) {
640                $this->matched_dirs = array();
641                if ( ! is_dir( $path ) ) {
642                        return;
643                }
644
645                $this->scandir( $path );
646                foreach ( array_reverse( $this->matched_dirs ) as $dir ) {
647                        rmdir( $dir );
648                }
649                rmdir( $path );
650        }
651
652        function scandir( $dir ) {
653                foreach ( scandir( $dir ) as $path ) {
654                        if ( 0 !== strpos( $path, '.' ) && is_dir( $dir . '/' . $path ) ) {
655                                $this->matched_dirs[] = $dir . '/' . $path;
656                                $this->scandir( $dir . '/' . $path );
657                        }
658                }
659        }
660
661        /**
662         * Helper to Convert a microtime string into a float
663         */
664        protected function _microtime_to_float($microtime ){
665                $time_array = explode( ' ', $microtime );
666                return array_sum( $time_array );
667        }
668
669        /**
670         * Multisite-agnostic way to delete a user from the database.
671         *
672         * @since 4.3.0
673         */
674        public static function delete_user( $user_id ) {
675                if ( is_multisite() ) {
676                        return wpmu_delete_user( $user_id );
677                } else {
678                        return wp_delete_user( $user_id );
679                }
680        }
681
682        /**
683         * Utility method that resets permalinks and flushes rewrites.
684         *
685         * @since 4.4.0
686         *
687         * @global WP_Rewrite $wp_rewrite
688         *
689         * @param string $structure Optional. Permalink structure to set. Default empty.
690         */
691        public function set_permalink_structure( $structure = '' ) {
692                global $wp_rewrite;
693
694                $wp_rewrite->init();
695                $wp_rewrite->set_permalink_structure( $structure );
696                $wp_rewrite->flush_rules();
697        }
698
699        function _make_attachment($upload, $parent_post_id = 0) {
700                $type = '';
701                if ( !empty($upload['type']) ) {
702                        $type = $upload['type'];
703                } else {
704                        $mime = wp_check_filetype( $upload['file'] );
705                        if ($mime)
706                                $type = $mime['type'];
707                }
708
709                $attachment = array(
710                        'post_title' => basename( $upload['file'] ),
711                        'post_content' => '',
712                        'post_type' => 'attachment',
713                        'post_parent' => $parent_post_id,
714                        'post_mime_type' => $type,
715                        'guid' => $upload[ 'url' ],
716                );
717
718                // Save the data
719                $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $parent_post_id );
720                wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
721                return $id;
722        }
723}
Note: See TracBrowser for help on using the repository browser.