Guest User

Untitled

a guest
Apr 27th, 2012
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 55.40 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Main WordPress API
  4.  *
  5.  * @package WordPress
  6.  */
  7.  
  8. /**
  9.  * Converts MySQL DATETIME field to user specified date format.
  10.  *
  11.  * If $dateformatstring has 'G' value, then gmmktime() function will be used to
  12.  * make the time. If $dateformatstring is set to 'U', then mktime() function
  13.  * will be used to make the time.
  14.  *
  15.  * The $translate will only be used, if it is set to true and it is by default
  16.  * and if the $wp_locale object has the month and weekday set.
  17.  *
  18.  * @since 0.71
  19.  *
  20.  * @param string $dateformatstring Either 'G', 'U', or php date format.
  21.  * @param string $mysqlstring Time from mysql DATETIME field.
  22.  * @param bool $translate Optional. Default is true. Will switch format to locale.
  23.  * @return string Date formated by $dateformatstring or locale (if available).
  24.  */
  25. function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
  26.     $m = $mysqlstring;
  27.     if ( empty( $m ) )
  28.         return false;
  29.  
  30.     if ( 'G' == $dateformatstring )
  31.         return strtotime( $m . ' +0000' );
  32.  
  33.     $i = strtotime( $m );
  34.  
  35.     if ( 'U' == $dateformatstring )
  36.         return $i;
  37.  
  38.     if ( $translate )
  39.         return date_i18n( $dateformatstring, $i );
  40.     else
  41.         return date( $dateformatstring, $i );
  42. }
  43.  
  44. /**
  45.  * Retrieve the current time based on specified type.
  46.  *
  47.  * The 'mysql' type will return the time in the format for MySQL DATETIME field.
  48.  * The 'timestamp' type will return the current timestamp.
  49.  *
  50.  * If $gmt is set to either '1' or 'true', then both types will use GMT time.
  51.  * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option.
  52.  *
  53.  * @since 1.0.0
  54.  *
  55.  * @param string $type Either 'mysql' or 'timestamp'.
  56.  * @param int|bool $gmt Optional. Whether to use GMT timezone. Default is false.
  57.  * @return int|string String if $type is 'gmt', int if $type is 'timestamp'.
  58.  */
  59. function current_time( $type, $gmt = 0 ) {
  60.     switch ( $type ) {
  61.         case 'mysql':
  62.             return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * 3600 ) ) );
  63.             break;
  64.         case 'timestamp':
  65.             return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * 3600 );
  66.             break;
  67.     }
  68. }
  69.  
  70. /**
  71.  * Retrieve the date in localized format, based on timestamp.
  72.  *
  73.  * If the locale specifies the locale month and weekday, then the locale will
  74.  * take over the format for the date. If it isn't, then the date format string
  75.  * will be used instead.
  76.  *
  77.  * @since 0.71
  78.  *
  79.  * @param string $dateformatstring Format to display the date.
  80.  * @param int $unixtimestamp Optional. Unix timestamp.
  81.  * @param bool $gmt Optional, default is false. Whether to convert to GMT for time.
  82.  * @return string The date, translated if locale specifies it.
  83.  */
  84. function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
  85.     global $wp_locale;
  86.     $i = $unixtimestamp;
  87.     // Sanity check for PHP 5.1.0-
  88.     if ( false === $i || intval($i) < 0 ) {
  89.         if ( ! $gmt )
  90.             $i = current_time( 'timestamp' );
  91.         else
  92.             $i = time();
  93.         // we should not let date() interfere with our
  94.         // specially computed timestamp
  95.         $gmt = true;
  96.     }
  97.  
  98.     // store original value for language with untypical grammars
  99.     // see http://core.trac.wordpress.org/ticket/9396
  100.     $req_format = $dateformatstring;
  101.  
  102.     $datefunc = $gmt? 'gmdate' : 'date';
  103.  
  104.     if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
  105.         $datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
  106.         $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
  107.         $dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
  108.         $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
  109.         $datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
  110.         $datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
  111.         $dateformatstring = ' '.$dateformatstring;
  112.         $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
  113.         $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
  114.         $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
  115.         $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
  116.         $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
  117.         $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
  118.  
  119.         $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
  120.     }
  121.     $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
  122.     $timezone_formats_re = implode( '|', $timezone_formats );
  123.     if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) && wp_timezone_supported() ) {
  124.         $timezone_string = get_option( 'timezone_string' );
  125.         if ( $timezone_string ) {
  126.             $timezone_object = timezone_open( $timezone_string );
  127.             $date_object = date_create( null, $timezone_object );
  128.             foreach( $timezone_formats as $timezone_format ) {
  129.                 if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
  130.                     $formatted = date_format( $date_object, $timezone_format );
  131.                     $dateformatstring = ' '.$dateformatstring;
  132.                     $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
  133.                     $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
  134.                 }
  135.             }
  136.         }
  137.     }
  138.     $j = @$datefunc( $dateformatstring, $i );
  139.     // allow plugins to redo this entirely for languages with untypical grammars
  140.     $j = apply_filters('date_i18n', $j, $req_format, $i, $gmt);
  141.     return $j;
  142. }
  143.  
  144. /**
  145.  * Convert integer number to format based on the locale.
  146.  *
  147.  * @since 2.3.0
  148.  *
  149.  * @param int $number The number to convert based on locale.
  150.  * @param int $decimals Precision of the number of decimal places.
  151.  * @return string Converted number in string format.
  152.  */
  153. function number_format_i18n( $number, $decimals = 0 ) {
  154.     global $wp_locale;
  155.     $formatted = number_format( $number, absint( $decimals ), $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] );
  156.     return apply_filters( 'number_format_i18n', $formatted );
  157. }
  158.  
  159. /**
  160.  * Convert number of bytes largest unit bytes will fit into.
  161.  *
  162.  * It is easier to read 1kB than 1024 bytes and 1MB than 1048576 bytes. Converts
  163.  * number of bytes to human readable number by taking the number of that unit
  164.  * that the bytes will go into it. Supports TB value.
  165.  *
  166.  * Please note that integers in PHP are limited to 32 bits, unless they are on
  167.  * 64 bit architecture, then they have 64 bit size. If you need to place the
  168.  * larger size then what PHP integer type will hold, then use a string. It will
  169.  * be converted to a double, which should always have 64 bit length.
  170.  *
  171.  * Technically the correct unit names for powers of 1024 are KiB, MiB etc.
  172.  * @link http://en.wikipedia.org/wiki/Byte
  173.  *
  174.  * @since 2.3.0
  175.  *
  176.  * @param int|string $bytes Number of bytes. Note max integer size for integers.
  177.  * @param int $decimals Precision of number of decimal places. Deprecated.
  178.  * @return bool|string False on failure. Number string on success.
  179.  */
  180. function size_format( $bytes, $decimals = 0 ) {
  181.     $quant = array(
  182.         // ========================= Origin ====
  183.         'TB' => 1099511627776,  // pow( 1024, 4)
  184.         'GB' => 1073741824,     // pow( 1024, 3)
  185.         'MB' => 1048576,        // pow( 1024, 2)
  186.         'kB' => 1024,           // pow( 1024, 1)
  187.         'B ' => 1,              // pow( 1024, 0)
  188.     );
  189.     foreach ( $quant as $unit => $mag )
  190.         if ( doubleval($bytes) >= $mag )
  191.             return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit;
  192.  
  193.     return false;
  194. }
  195.  
  196. /**
  197.  * Get the week start and end from the datetime or date string from mysql.
  198.  *
  199.  * @since 0.71
  200.  *
  201.  * @param string $mysqlstring Date or datetime field type from mysql.
  202.  * @param int $start_of_week Optional. Start of the week as an integer.
  203.  * @return array Keys are 'start' and 'end'.
  204.  */
  205. function get_weekstartend( $mysqlstring, $start_of_week = '' ) {
  206.     $my = substr( $mysqlstring, 0, 4 ); // Mysql string Year
  207.     $mm = substr( $mysqlstring, 8, 2 ); // Mysql string Month
  208.     $md = substr( $mysqlstring, 5, 2 ); // Mysql string day
  209.     $day = mktime( 0, 0, 0, $md, $mm, $my ); // The timestamp for mysqlstring day.
  210.     $weekday = date( 'w', $day ); // The day of the week from the timestamp
  211.     if ( !is_numeric($start_of_week) )
  212.         $start_of_week = get_option( 'start_of_week' );
  213.  
  214.     if ( $weekday < $start_of_week )
  215.         $weekday += 7;
  216.  
  217.     $start = $day - 86400 * ( $weekday - $start_of_week ); // The most recent week start day on or before $day
  218.     $end = $start + 604799; // $start + 7 days - 1 second
  219.     return compact( 'start', 'end' );
  220. }
  221.  
  222. /**
  223.  * Unserialize value only if it was serialized.
  224.  *
  225.  * @since 2.0.0
  226.  *
  227.  * @param string $original Maybe unserialized original, if is needed.
  228.  * @return mixed Unserialized data can be any type.
  229.  */
  230. function maybe_unserialize( $original ) {
  231.     if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
  232.         return @unserialize( $original );
  233.     return $original;
  234. }
  235.  
  236. /**
  237.  * Check value to find if it was serialized.
  238.  *
  239.  * If $data is not an string, then returned value will always be false.
  240.  * Serialized data is always a string.
  241.  *
  242.  * @since 2.0.5
  243.  *
  244.  * @param mixed $data Value to check to see if was serialized.
  245.  * @return bool False if not serialized and true if it was.
  246.  */
  247. function is_serialized( $data ) {
  248.     // if it isn't a string, it isn't serialized
  249.     if ( ! is_string( $data ) )
  250.         return false;
  251.     $data = trim( $data );
  252.     if ( 'N;' == $data )
  253.         return true;
  254.     $length = strlen( $data );
  255.     if ( $length < 4 )
  256.         return false;
  257.     if ( ':' !== $data[1] )
  258.         return false;
  259.     $lastc = $data[$length-1];
  260.     if ( ';' !== $lastc && '}' !== $lastc )
  261.         return false;
  262.     $token = $data[0];
  263.     switch ( $token ) {
  264.         case 's' :
  265.             if ( '"' !== $data[$length-2] )
  266.                 return false;
  267.         case 'a' :
  268.         case 'O' :
  269.             return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
  270.         case 'b' :
  271.         case 'i' :
  272.         case 'd' :
  273.             return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data );
  274.     }
  275.     return false;
  276. }
  277.  
  278. /**
  279.  * Check whether serialized data is of string type.
  280.  *
  281.  * @since 2.0.5
  282.  *
  283.  * @param mixed $data Serialized data
  284.  * @return bool False if not a serialized string, true if it is.
  285.  */
  286. function is_serialized_string( $data ) {
  287.     // if it isn't a string, it isn't a serialized string
  288.     if ( !is_string( $data ) )
  289.         return false;
  290.     $data = trim( $data );
  291.     if ( preg_match( '/^s:[0-9]+:.*;$/s', $data ) ) // this should fetch all serialized strings
  292.         return true;
  293.     return false;
  294. }
  295.  
  296. /**
  297.  * Retrieve option value based on name of option.
  298.  *
  299.  * If the option does not exist or does not have a value, then the return value
  300.  * will be false. This is useful to check whether you need to install an option
  301.  * and is commonly used during installation of plugin options and to test
  302.  * whether upgrading is required.
  303.  *
  304.  * If the option was serialized then it will be unserialized when it is returned.
  305.  *
  306.  * @since 1.5.0
  307.  * @package WordPress
  308.  * @subpackage Option
  309.  * @uses apply_filters() Calls 'pre_option_$option' before checking the option.
  310.  *  Any value other than false will "short-circuit" the retrieval of the option
  311.  *  and return the returned value. You should not try to override special options,
  312.  *  but you will not be prevented from doing so.
  313.  * @uses apply_filters() Calls 'option_$option', after checking the option, with
  314.  *  the option value.
  315.  *
  316.  * @param string $option Name of option to retrieve. Expected to not be SQL-escaped.
  317.  * @return mixed Value set for the option.
  318.  */
  319. function get_option( $option, $default = false ) {
  320.     global $wpdb;
  321.  
  322.     // Allow plugins to short-circuit options.
  323.     $pre = apply_filters( 'pre_option_' . $option, false );
  324.     if ( false !== $pre )
  325.         return $pre;
  326.  
  327.     $option = trim($option);
  328.     if ( empty($option) )
  329.         return false;
  330.  
  331.     if ( defined( 'WP_SETUP_CONFIG' ) )
  332.         return false;
  333.  
  334.     if ( ! defined( 'WP_INSTALLING' ) ) {
  335.         // prevent non-existent options from triggering multiple queries
  336.         $notoptions = wp_cache_get( 'notoptions', 'options' );
  337.         if ( isset( $notoptions[$option] ) )
  338.             return $default;
  339.  
  340.         $alloptions = wp_load_alloptions();
  341.  
  342.         if ( isset( $alloptions[$option] ) ) {
  343.             $value = $alloptions[$option];
  344.         } else {
  345.             $value = wp_cache_get( $option, 'options' );
  346.  
  347.             if ( false === $value ) {
  348.                 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
  349.  
  350.                 // Has to be get_row instead of get_var because of funkiness with 0, false, null values
  351.                 if ( is_object( $row ) ) {
  352.                     $value = $row->option_value;
  353.                     wp_cache_add( $option, $value, 'options' );
  354.                 } else { // option does not exist, so we must cache its non-existence
  355.                     $notoptions[$option] = true;
  356.                     wp_cache_set( 'notoptions', $notoptions, 'options' );
  357.                     return $default;
  358.                 }
  359.             }
  360.         }
  361.     } else {
  362.         $suppress = $wpdb->suppress_errors();
  363.         $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
  364.         $wpdb->suppress_errors( $suppress );
  365.         if ( is_object( $row ) )
  366.             $value = $row->option_value;
  367.         else
  368.             return $default;
  369.     }
  370.  
  371.     // If home is not set use siteurl.
  372.     if ( 'home' == $option && '' == $value )
  373.         return get_option( 'siteurl' );
  374.  
  375.     if ( in_array( $option, array('siteurl', 'home', 'category_base', 'tag_base') ) )
  376.         $value = untrailingslashit( $value );
  377.  
  378.     return apply_filters( 'option_' . $option, maybe_unserialize( $value ) );
  379. }
  380.  
  381. /**
  382.  * Protect WordPress special option from being modified.
  383.  *
  384.  * Will die if $option is in protected list. Protected options are 'alloptions'
  385.  * and 'notoptions' options.
  386.  *
  387.  * @since 2.2.0
  388.  * @package WordPress
  389.  * @subpackage Option
  390.  *
  391.  * @param string $option Option name.
  392.  */
  393. function wp_protect_special_option( $option ) {
  394.     $protected = array( 'alloptions', 'notoptions' );
  395.     if ( in_array( $option, $protected ) )
  396.         wp_die( sprintf( __( '%s is a protected WP option and may not be modified' ), esc_html( $option ) ) );
  397. }
  398.  
  399. /**
  400.  * Print option value after sanitizing for forms.
  401.  *
  402.  * @uses attr Sanitizes value.
  403.  * @since 1.5.0
  404.  * @package WordPress
  405.  * @subpackage Option
  406.  *
  407.  * @param string $option Option name.
  408.  */
  409. function form_option( $option ) {
  410.     echo esc_attr( get_option( $option ) );
  411. }
  412.  
  413. /**
  414.  * Loads and caches all autoloaded options, if available or all options.
  415.  *
  416.  * @since 2.2.0
  417.  * @package WordPress
  418.  * @subpackage Option
  419.  *
  420.  * @return array List of all options.
  421.  */
  422. function wp_load_alloptions() {
  423.     global $wpdb;
  424.  
  425.     if ( !defined( 'WP_INSTALLING' ) || !is_multisite() )
  426.         $alloptions = wp_cache_get( 'alloptions', 'options' );
  427.     else
  428.         $alloptions = false;
  429.  
  430.     if ( !$alloptions ) {
  431.         $suppress = $wpdb->suppress_errors();
  432.         if ( !$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) )
  433.             $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
  434.         $wpdb->suppress_errors($suppress);
  435.         $alloptions = array();
  436.         foreach ( (array) $alloptions_db as $o ) {
  437.             $alloptions[$o->option_name] = $o->option_value;
  438.         }
  439.         if ( !defined( 'WP_INSTALLING' ) || !is_multisite() )
  440.             wp_cache_add( 'alloptions', $alloptions, 'options' );
  441.     }
  442.  
  443.     return $alloptions;
  444. }
  445.  
  446. /**
  447.  * Loads and caches certain often requested site options if is_multisite() and a peristent cache is not being used.
  448.  *
  449.  * @since 3.0.0
  450.  * @package WordPress
  451.  * @subpackage Option
  452.  *
  453.  * @param int $site_id Optional site ID for which to query the options. Defaults to the current site.
  454.  */
  455. function wp_load_core_site_options( $site_id = null ) {
  456.     global $wpdb, $_wp_using_ext_object_cache;
  457.  
  458.     if ( !is_multisite() || $_wp_using_ext_object_cache || defined( 'WP_INSTALLING' ) )
  459.         return;
  460.  
  461.     if ( empty($site_id) )
  462.         $site_id = $wpdb->siteid;
  463.  
  464.     $core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled' );
  465.  
  466.     $core_options_in = "'" . implode("', '", $core_options) . "'";
  467.     $options = $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d", $site_id) );
  468.  
  469.     foreach ( $options as $option ) {
  470.         $key = $option->meta_key;
  471.         $cache_key = "{$site_id}:$key";
  472.         $option->meta_value = maybe_unserialize( $option->meta_value );
  473.  
  474.         wp_cache_set( $cache_key, $option->meta_value, 'site-options' );
  475.     }
  476. }
  477.  
  478. /**
  479.  * Update the value of an option that was already added.
  480.  *
  481.  * You do not need to serialize values. If the value needs to be serialized, then
  482.  * it will be serialized before it is inserted into the database. Remember,
  483.  * resources can not be serialized or added as an option.
  484.  *
  485.  * If the option does not exist, then the option will be added with the option
  486.  * value, but you will not be able to set whether it is autoloaded. If you want
  487.  * to set whether an option is autoloaded, then you need to use the add_option().
  488.  *
  489.  * @since 1.0.0
  490.  * @package WordPress
  491.  * @subpackage Option
  492.  *
  493.  * @uses apply_filters() Calls 'pre_update_option_$option' hook to allow overwriting the
  494.  *  option value to be stored.
  495.  * @uses do_action() Calls 'update_option' hook before updating the option.
  496.  * @uses do_action() Calls 'update_option_$option' and 'updated_option' hooks on success.
  497.  *
  498.  * @param string $option Option name. Expected to not be SQL-escaped.
  499.  * @param mixed $newvalue Option value. Expected to not be SQL-escaped.
  500.  * @return bool False if value was not updated and true if value was updated.
  501.  */
  502. function update_option( $option, $newvalue ) {
  503.     global $wpdb;
  504.  
  505.     $option = trim($option);
  506.     if ( empty($option) )
  507.         return false;
  508.  
  509.     wp_protect_special_option( $option );
  510.  
  511.     if ( is_object($newvalue) )
  512.         $newvalue = wp_clone($newvalue);
  513.  
  514.     $newvalue = sanitize_option( $option, $newvalue );
  515.     $oldvalue = get_option( $option );
  516.     $newvalue = apply_filters( 'pre_update_option_' . $option, $newvalue, $oldvalue );
  517.  
  518.     // If the new and old values are the same, no need to update.
  519.     if ( $newvalue === $oldvalue )
  520.         return false;
  521.  
  522.     if ( false === $oldvalue )
  523.         return add_option( $option, $newvalue );
  524.  
  525.     $notoptions = wp_cache_get( 'notoptions', 'options' );
  526.     if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
  527.         unset( $notoptions[$option] );
  528.         wp_cache_set( 'notoptions', $notoptions, 'options' );
  529.     }
  530.  
  531.     $_newvalue = $newvalue;
  532.     $newvalue = maybe_serialize( $newvalue );
  533.  
  534.     do_action( 'update_option', $option, $oldvalue, $_newvalue );
  535.     if ( ! defined( 'WP_INSTALLING' ) ) {
  536.         $alloptions = wp_load_alloptions();
  537.         if ( isset( $alloptions[$option] ) ) {
  538.             $alloptions[$option] = $_newvalue;
  539.             wp_cache_set( 'alloptions', $alloptions, 'options' );
  540.         } else {
  541.             wp_cache_set( $option, $_newvalue, 'options' );
  542.         }
  543.     }
  544.  
  545.     $result = $wpdb->update( $wpdb->options, array( 'option_value' => $newvalue ), array( 'option_name' => $option ) );
  546.  
  547.     if ( $result ) {
  548.         do_action( "update_option_{$option}", $oldvalue, $_newvalue );
  549.         do_action( 'updated_option', $option, $oldvalue, $_newvalue );
  550.         return true;
  551.     }
  552.     return false;
  553. }
  554.  
  555. /**
  556.  * Add a new option.
  557.  *
  558.  * You do not need to serialize values. If the value needs to be serialized, then
  559.  * it will be serialized before it is inserted into the database. Remember,
  560.  * resources can not be serialized or added as an option.
  561.  *
  562.  * You can create options without values and then add values later. Does not
  563.  * check whether the option has already been added, but does check that you
  564.  * aren't adding a protected WordPress option. Care should be taken to not name
  565.  * options the same as the ones which are protected and to not add options
  566.  * that were already added.
  567.  *
  568.  * @package WordPress
  569.  * @subpackage Option
  570.  * @since 1.0.0
  571.  *
  572.  * @uses do_action() Calls 'add_option' hook before adding the option.
  573.  * @uses do_action() Calls 'add_option_$option' and 'added_option' hooks on success.
  574.  *
  575.  * @param string $option Name of option to add. Expected to not be SQL-escaped.
  576.  * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped.
  577.  * @param mixed $deprecated Optional. Description. Not used anymore.
  578.  * @param bool $autoload Optional. Default is enabled. Whether to load the option when WordPress starts up.
  579.  * @return null returns when finished.
  580.  */
  581. function add_option( $option, $value = '', $deprecated = '', $autoload = 'yes' ) {
  582.     global $wpdb;
  583.  
  584.     if ( !empty( $deprecated ) )
  585.         _deprecated_argument( __FUNCTION__, '2.3' );
  586.  
  587.     $option = trim($option);
  588.     if ( empty($option) )
  589.         return false;
  590.  
  591.     wp_protect_special_option( $option );
  592.  
  593.     if ( is_object($value) )
  594.         $value = wp_clone($value);
  595.  
  596.     $value = sanitize_option( $option, $value );
  597.  
  598.     // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query
  599.     $notoptions = wp_cache_get( 'notoptions', 'options' );
  600.     if ( !is_array( $notoptions ) || !isset( $notoptions[$option] ) )
  601.         if ( false !== get_option( $option ) )
  602.             return;
  603.  
  604.     $_value = $value;
  605.     $value = maybe_serialize( $value );
  606.     $autoload = ( 'no' === $autoload ) ? 'no' : 'yes';
  607.     do_action( 'add_option', $option, $_value );
  608.     if ( ! defined( 'WP_INSTALLING' ) ) {
  609.         if ( 'yes' == $autoload ) {
  610.             $alloptions = wp_load_alloptions();
  611.             $alloptions[$option] = $value;
  612.             wp_cache_set( 'alloptions', $alloptions, 'options' );
  613.         } else {
  614.             wp_cache_set( $option, $value, 'options' );
  615.         }
  616.     }
  617.  
  618.     // This option exists now
  619.     $notoptions = wp_cache_get( 'notoptions', 'options' ); // yes, again... we need it to be fresh
  620.     if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
  621.         unset( $notoptions[$option] );
  622.         wp_cache_set( 'notoptions', $notoptions, 'options' );
  623.     }
  624.  
  625.     $result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $value, $autoload ) );
  626.  
  627.     if ( $result ) {
  628.         do_action( "add_option_{$option}", $option, $_value );
  629.         do_action( 'added_option', $option, $_value );
  630.         return true;
  631.     }
  632.     return false;
  633. }
  634.  
  635. /**
  636.  * Removes option by name. Prevents removal of protected WordPress options.
  637.  *
  638.  * @package WordPress
  639.  * @subpackage Option
  640.  * @since 1.2.0
  641.  *
  642.  * @uses do_action() Calls 'delete_option' hook before option is deleted.
  643.  * @uses do_action() Calls 'deleted_option' and 'delete_option_$option' hooks on success.
  644.  *
  645.  * @param string $option Name of option to remove. Expected to not be SQL-escaped.
  646.  * @return bool True, if option is successfully deleted. False on failure.
  647.  */
  648. function delete_option( $option ) {
  649.     global $wpdb;
  650.  
  651.     wp_protect_special_option( $option );
  652.  
  653.     // Get the ID, if no ID then return
  654.     $row = $wpdb->get_row( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option ) );
  655.     if ( is_null( $row ) )
  656.         return false;
  657.     do_action( 'delete_option', $option );
  658.     $result = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->options WHERE option_name = %s", $option) );
  659.     if ( ! defined( 'WP_INSTALLING' ) ) {
  660.         if ( 'yes' == $row->autoload ) {
  661.             $alloptions = wp_load_alloptions();
  662.             if ( is_array( $alloptions ) && isset( $alloptions[$option] ) ) {
  663.                 unset( $alloptions[$option] );
  664.                 wp_cache_set( 'alloptions', $alloptions, 'options' );
  665.             }
  666.         } else {
  667.             wp_cache_delete( $option, 'options' );
  668.         }
  669.     }
  670.     if ( $result ) {
  671.         do_action( "delete_option_$option", $option );
  672.         do_action( 'deleted_option', $option );
  673.         return true;
  674.     }
  675.     return false;
  676. }
  677.  
  678. /**
  679.  * Delete a transient
  680.  *
  681.  * @since 2.8.0
  682.  * @package WordPress
  683.  * @subpackage Transient
  684.  *
  685.  * @uses do_action() Calls 'delete_transient_$transient' hook before transient is deleted.
  686.  * @uses do_action() Calls 'deleted_transient' hook on success.
  687.  *
  688.  * @param string $transient Transient name. Expected to not be SQL-escaped.
  689.  * @return bool true if successful, false otherwise
  690.  */
  691. function delete_transient( $transient ) {
  692.     global $_wp_using_ext_object_cache;
  693.  
  694.     do_action( 'delete_transient_' . $transient, $transient );
  695.  
  696.     if ( $_wp_using_ext_object_cache ) {
  697.         $result = wp_cache_delete( $transient, 'transient' );
  698.     } else {
  699.         $option_timeout = '_transient_timeout_' . $transient;
  700.         $option = '_transient_' . $transient;
  701.         $result = delete_option( $option );
  702.         if ( $result )
  703.             delete_option( $option_timeout );
  704.     }
  705.  
  706.     if ( $result )
  707.         do_action( 'deleted_transient', $transient );
  708.     return $result;
  709. }
  710.  
  711. /**
  712.  * Get the value of a transient
  713.  *
  714.  * If the transient does not exist or does not have a value, then the return value
  715.  * will be false.
  716.  *
  717.  * @uses apply_filters() Calls 'pre_transient_$transient' hook before checking the transient.
  718.  *  Any value other than false will "short-circuit" the retrieval of the transient
  719.  *  and return the returned value.
  720.  * @uses apply_filters() Calls 'transient_$option' hook, after checking the transient, with
  721.  *  the transient value.
  722.  *
  723.  * @since 2.8.0
  724.  * @package WordPress
  725.  * @subpackage Transient
  726.  *
  727.  * @param string $transient Transient name. Expected to not be SQL-escaped
  728.  * @return mixed Value of transient
  729.  */
  730. function get_transient( $transient ) {
  731.     global $_wp_using_ext_object_cache;
  732.  
  733.     $pre = apply_filters( 'pre_transient_' . $transient, false );
  734.     if ( false !== $pre )
  735.         return $pre;
  736.  
  737.     if ( $_wp_using_ext_object_cache ) {
  738.         $value = wp_cache_get( $transient, 'transient' );
  739.     } else {
  740.         $transient_option = '_transient_' . $transient;
  741.         if ( ! defined( 'WP_INSTALLING' ) ) {
  742.             // If option is not in alloptions, it is not autoloaded and thus has a timeout
  743.             $alloptions = wp_load_alloptions();
  744.             if ( !isset( $alloptions[$transient_option] ) ) {
  745.                 $transient_timeout = '_transient_timeout_' . $transient;
  746.                 if ( get_option( $transient_timeout ) < time() ) {
  747.                     delete_option( $transient_option  );
  748.                     delete_option( $transient_timeout );
  749.                     return false;
  750.                 }
  751.             }
  752.         }
  753.  
  754.         $value = get_option( $transient_option );
  755.     }
  756.  
  757.     return apply_filters( 'transient_' . $transient, $value );
  758. }
  759.  
  760. /**
  761.  * Set/update the value of a transient
  762.  *
  763.  * You do not need to serialize values. If the value needs to be serialized, then
  764.  * it will be serialized before it is set.
  765.  *
  766.  * @since 2.8.0
  767.  * @package WordPress
  768.  * @subpackage Transient
  769.  *
  770.  * @uses apply_filters() Calls 'pre_set_transient_$transient' hook to allow overwriting the
  771.  *  transient value to be stored.
  772.  * @uses do_action() Calls 'set_transient_$transient' and 'setted_transient' hooks on success.
  773.  *
  774.  * @param string $transient Transient name. Expected to not be SQL-escaped.
  775.  * @param mixed $value Transient value. Expected to not be SQL-escaped.
  776.  * @param int $expiration Time until expiration in seconds, default 0
  777.  * @return bool False if value was not set and true if value was set.
  778.  */
  779. function set_transient( $transient, $value, $expiration = 0 ) {
  780.     global $_wp_using_ext_object_cache;
  781.  
  782.     $value = apply_filters( 'pre_set_transient_' . $transient, $value );
  783.  
  784.     if ( $_wp_using_ext_object_cache ) {
  785.         $result = wp_cache_set( $transient, $value, 'transient', $expiration );
  786.     } else {
  787.         $transient_timeout = '_transient_timeout_' . $transient;
  788.         $transient = '_transient_' . $transient;
  789.         if ( false === get_option( $transient ) ) {
  790.             $autoload = 'yes';
  791.             if ( $expiration ) {
  792.                 $autoload = 'no';
  793.                 add_option( $transient_timeout, time() + $expiration, '', 'no' );
  794.             }
  795.             $result = add_option( $transient, $value, '', $autoload );
  796.         } else {
  797.             if ( $expiration )
  798.                 update_option( $transient_timeout, time() + $expiration );
  799.             $result = update_option( $transient, $value );
  800.         }
  801.     }
  802.     if ( $result ) {
  803.         do_action( 'set_transient_' . $transient );
  804.         do_action( 'setted_transient', $transient );
  805.     }
  806.     return $result;
  807. }
  808.  
  809. /**
  810.  * Saves and restores user interface settings stored in a cookie.
  811.  *
  812.  * Checks if the current user-settings cookie is updated and stores it. When no
  813.  * cookie exists (different browser used), adds the last saved cookie restoring
  814.  * the settings.
  815.  *
  816.  * @package WordPress
  817.  * @subpackage Option
  818.  * @since 2.7.0
  819.  */
  820. function wp_user_settings() {
  821.  
  822.     if ( ! is_admin() )
  823.         return;
  824.  
  825.     if ( defined('DOING_AJAX') )
  826.         return;
  827.  
  828.     if ( ! $user = wp_get_current_user() )
  829.         return;
  830.  
  831.     $settings = get_user_option( 'user-settings', $user->ID );
  832.  
  833.     if ( isset( $_COOKIE['wp-settings-' . $user->ID] ) ) {
  834.         $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] );
  835.  
  836.         if ( ! empty( $cookie ) && strpos( $cookie, '=' ) ) {
  837.             if ( $cookie == $settings )
  838.                 return;
  839.  
  840.             $last_time = (int) get_user_option( 'user-settings-time', $user->ID );
  841.             $saved = isset( $_COOKIE['wp-settings-time-' . $user->ID]) ? preg_replace( '/[^0-9]/', '', $_COOKIE['wp-settings-time-' . $user->ID] ) : 0;
  842.  
  843.             if ( $saved > $last_time ) {
  844.                 update_user_option( $user->ID, 'user-settings', $cookie, false );
  845.                 update_user_option( $user->ID, 'user-settings-time', time() - 5, false );
  846.                 return;
  847.             }
  848.         }
  849.     }
  850.  
  851.     setcookie( 'wp-settings-' . $user->ID, $settings, time() + 31536000, SITECOOKIEPATH );
  852.     setcookie( 'wp-settings-time-' . $user->ID, time(), time() + 31536000, SITECOOKIEPATH );
  853.     $_COOKIE['wp-settings-' . $user->ID] = $settings;
  854. }
  855.  
  856. /**
  857.  * Retrieve user interface setting value based on setting name.
  858.  *
  859.  * @package WordPress
  860.  * @subpackage Option
  861.  * @since 2.7.0
  862.  *
  863.  * @param string $name The name of the setting.
  864.  * @param string $default Optional default value to return when $name is not set.
  865.  * @return mixed the last saved user setting or the default value/false if it doesn't exist.
  866.  */
  867. function get_user_setting( $name, $default = false ) {
  868.  
  869.     $all = get_all_user_settings();
  870.  
  871.     return isset($all[$name]) ? $all[$name] : $default;
  872. }
  873.  
  874. /**
  875.  * Add or update user interface setting.
  876.  *
  877.  * Both $name and $value can contain only ASCII letters, numbers and underscores.
  878.  * This function has to be used before any output has started as it calls setcookie().
  879.  *
  880.  * @package WordPress
  881.  * @subpackage Option
  882.  * @since 2.8.0
  883.  *
  884.  * @param string $name The name of the setting.
  885.  * @param string $value The value for the setting.
  886.  * @return bool true if set successfully/false if not.
  887.  */
  888. function set_user_setting( $name, $value ) {
  889.  
  890.     if ( headers_sent() )
  891.         return false;
  892.  
  893.     $all = get_all_user_settings();
  894.     $name = preg_replace( '/[^A-Za-z0-9_]+/', '', $name );
  895.  
  896.     if ( empty($name) )
  897.         return false;
  898.  
  899.     $all[$name] = $value;
  900.  
  901.     return wp_set_all_user_settings($all);
  902. }
  903.  
  904. /**
  905.  * Delete user interface settings.
  906.  *
  907.  * Deleting settings would reset them to the defaults.
  908.  * This function has to be used before any output has started as it calls setcookie().
  909.  *
  910.  * @package WordPress
  911.  * @subpackage Option
  912.  * @since 2.7.0
  913.  *
  914.  * @param mixed $names The name or array of names of the setting to be deleted.
  915.  * @return bool true if deleted successfully/false if not.
  916.  */
  917. function delete_user_setting( $names ) {
  918.  
  919.     if ( headers_sent() )
  920.         return false;
  921.  
  922.     $all = get_all_user_settings();
  923.     $names = (array) $names;
  924.  
  925.     foreach ( $names as $name ) {
  926.         if ( isset($all[$name]) ) {
  927.             unset($all[$name]);
  928.             $deleted = true;
  929.         }
  930.     }
  931.  
  932.     if ( isset($deleted) )
  933.         return wp_set_all_user_settings($all);
  934.  
  935.     return false;
  936. }
  937.  
  938. /**
  939.  * Retrieve all user interface settings.
  940.  *
  941.  * @package WordPress
  942.  * @subpackage Option
  943.  * @since 2.7.0
  944.  *
  945.  * @return array the last saved user settings or empty array.
  946.  */
  947. function get_all_user_settings() {
  948.     global $_updated_user_settings;
  949.  
  950.     if ( ! $user = wp_get_current_user() )
  951.         return array();
  952.  
  953.     if ( isset($_updated_user_settings) && is_array($_updated_user_settings) )
  954.         return $_updated_user_settings;
  955.  
  956.     $all = array();
  957.     if ( isset($_COOKIE['wp-settings-' . $user->ID]) ) {
  958.         $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] );
  959.  
  960.         if ( $cookie && strpos($cookie, '=') ) // the '=' cannot be 1st char
  961.             parse_str($cookie, $all);
  962.  
  963.     } else {
  964.         $option = get_user_option('user-settings', $user->ID);
  965.         if ( $option && is_string($option) )
  966.             parse_str( $option, $all );
  967.     }
  968.  
  969.     return $all;
  970. }
  971.  
  972. /**
  973.  * Private. Set all user interface settings.
  974.  *
  975.  * @package WordPress
  976.  * @subpackage Option
  977.  * @since 2.8.0
  978.  *
  979.  * @param unknown $all
  980.  * @return bool
  981.  */
  982. function wp_set_all_user_settings($all) {
  983.     global $_updated_user_settings;
  984.  
  985.     if ( ! $user = wp_get_current_user() )
  986.         return false;
  987.  
  988.     $_updated_user_settings = $all;
  989.     $settings = '';
  990.     foreach ( $all as $k => $v ) {
  991.         $v = preg_replace( '/[^A-Za-z0-9_]+/', '', $v );
  992.         $settings .= $k . '=' . $v . '&';
  993.     }
  994.  
  995.     $settings = rtrim($settings, '&');
  996.  
  997.     update_user_option( $user->ID, 'user-settings', $settings, false );
  998.     update_user_option( $user->ID, 'user-settings-time', time(), false );
  999.  
  1000.     return true;
  1001. }
  1002.  
  1003. /**
  1004.  * Delete the user settings of the current user.
  1005.  *
  1006.  * @package WordPress
  1007.  * @subpackage Option
  1008.  * @since 2.7.0
  1009.  */
  1010. function delete_all_user_settings() {
  1011.     if ( ! $user = wp_get_current_user() )
  1012.         return;
  1013.  
  1014.     update_user_option( $user->ID, 'user-settings', '', false );
  1015.     setcookie('wp-settings-' . $user->ID, ' ', time() - 31536000, SITECOOKIEPATH);
  1016. }
  1017.  
  1018. /**
  1019.  * Serialize data, if needed.
  1020.  *
  1021.  * @since 2.0.5
  1022.  *
  1023.  * @param mixed $data Data that might be serialized.
  1024.  * @return mixed A scalar data
  1025.  */
  1026. function maybe_serialize( $data ) {
  1027.     if ( is_array( $data ) || is_object( $data ) )
  1028.         return serialize( $data );
  1029.  
  1030.     if ( is_serialized( $data ) )
  1031.         return serialize( $data );
  1032.  
  1033.     return $data;
  1034. }
  1035.  
  1036. /**
  1037.  * Retrieve post title from XMLRPC XML.
  1038.  *
  1039.  * If the title element is not part of the XML, then the default post title from
  1040.  * the $post_default_title will be used instead.
  1041.  *
  1042.  * @package WordPress
  1043.  * @subpackage XMLRPC
  1044.  * @since 0.71
  1045.  *
  1046.  * @global string $post_default_title Default XMLRPC post title.
  1047.  *
  1048.  * @param string $content XMLRPC XML Request content
  1049.  * @return string Post title
  1050.  */
  1051. function xmlrpc_getposttitle( $content ) {
  1052.     global $post_default_title;
  1053.     if ( preg_match( '/<title>(.+?)<\/title>/is', $content, $matchtitle ) ) {
  1054.         $post_title = $matchtitle[1];
  1055.     } else {
  1056.         $post_title = $post_default_title;
  1057.     }
  1058.     return $post_title;
  1059. }
  1060.  
  1061. /**
  1062.  * Retrieve the post category or categories from XMLRPC XML.
  1063.  *
  1064.  * If the category element is not found, then the default post category will be
  1065.  * used. The return type then would be what $post_default_category. If the
  1066.  * category is found, then it will always be an array.
  1067.  *
  1068.  * @package WordPress
  1069.  * @subpackage XMLRPC
  1070.  * @since 0.71
  1071.  *
  1072.  * @global string $post_default_category Default XMLRPC post category.
  1073.  *
  1074.  * @param string $content XMLRPC XML Request content
  1075.  * @return string|array List of categories or category name.
  1076.  */
  1077. function xmlrpc_getpostcategory( $content ) {
  1078.     global $post_default_category;
  1079.     if ( preg_match( '/<category>(.+?)<\/category>/is', $content, $matchcat ) ) {
  1080.         $post_category = trim( $matchcat[1], ',' );
  1081.         $post_category = explode( ',', $post_category );
  1082.     } else {
  1083.         $post_category = $post_default_category;
  1084.     }
  1085.     return $post_category;
  1086. }
  1087.  
  1088. /**
  1089.  * XMLRPC XML content without title and category elements.
  1090.  *
  1091.  * @package WordPress
  1092.  * @subpackage XMLRPC
  1093.  * @since 0.71
  1094.  *
  1095.  * @param string $content XMLRPC XML Request content
  1096.  * @return string XMLRPC XML Request content without title and category elements.
  1097.  */
  1098. function xmlrpc_removepostdata( $content ) {
  1099.     $content = preg_replace( '/<title>(.+?)<\/title>/si', '', $content );
  1100.     $content = preg_replace( '/<category>(.+?)<\/category>/si', '', $content );
  1101.     $content = trim( $content );
  1102.     return $content;
  1103. }
  1104.  
  1105. /**
  1106.  * Open the file handle for debugging.
  1107.  *
  1108.  * This function is used for XMLRPC feature, but it is general purpose enough
  1109.  * to be used in anywhere.
  1110.  *
  1111.  * @see fopen() for mode options.
  1112.  * @package WordPress
  1113.  * @subpackage Debug
  1114.  * @since 0.71
  1115.  * @uses $debug Used for whether debugging is enabled.
  1116.  *
  1117.  * @param string $filename File path to debug file.
  1118.  * @param string $mode Same as fopen() mode parameter.
  1119.  * @return bool|resource File handle. False on failure.
  1120.  */
  1121. function debug_fopen( $filename, $mode ) {
  1122.     global $debug;
  1123.     if ( 1 == $debug ) {
  1124.         $fp = fopen( $filename, $mode );
  1125.         return $fp;
  1126.     } else {
  1127.         return false;
  1128.     }
  1129. }
  1130.  
  1131. /**
  1132.  * Write contents to the file used for debugging.
  1133.  *
  1134.  * Technically, this can be used to write to any file handle when the global
  1135.  * $debug is set to 1 or true.
  1136.  *
  1137.  * @package WordPress
  1138.  * @subpackage Debug
  1139.  * @since 0.71
  1140.  * @uses $debug Used for whether debugging is enabled.
  1141.  *
  1142.  * @param resource $fp File handle for debugging file.
  1143.  * @param string $string Content to write to debug file.
  1144.  */
  1145. function debug_fwrite( $fp, $string ) {
  1146.     global $debug;
  1147.     if ( 1 == $debug )
  1148.         fwrite( $fp, $string );
  1149. }
  1150.  
  1151. /**
  1152.  * Close the debugging file handle.
  1153.  *
  1154.  * Technically, this can be used to close any file handle when the global $debug
  1155.  * is set to 1 or true.
  1156.  *
  1157.  * @package WordPress
  1158.  * @subpackage Debug
  1159.  * @since 0.71
  1160.  * @uses $debug Used for whether debugging is enabled.
  1161.  *
  1162.  * @param resource $fp Debug File handle.
  1163.  */
  1164. function debug_fclose( $fp ) {
  1165.     global $debug;
  1166.     if ( 1 == $debug )
  1167.         fclose( $fp );
  1168. }
  1169.  
  1170. /**
  1171.  * Check content for video and audio links to add as enclosures.
  1172.  *
  1173.  * Will not add enclosures that have already been added and will
  1174.  * remove enclosures that are no longer in the post. This is called as
  1175.  * pingbacks and trackbacks.
  1176.  *
  1177.  * @package WordPress
  1178.  * @since 1.5.0
  1179.  *
  1180.  * @uses $wpdb
  1181.  *
  1182.  * @param string $content Post Content
  1183.  * @param int $post_ID Post ID
  1184.  */
  1185. function do_enclose( $content, $post_ID ) {
  1186.     global $wpdb;
  1187.  
  1188.     //TODO: Tidy this ghetto code up and make the debug code optional
  1189.     include_once( ABSPATH . WPINC . '/class-IXR.php' );
  1190.  
  1191.     $log = debug_fopen( ABSPATH . 'enclosures.log', 'a' );
  1192.     $post_links = array();
  1193.     debug_fwrite( $log, 'BEGIN ' . date( 'YmdHis', time() ) . "\n" );
  1194.  
  1195.     $pung = get_enclosed( $post_ID );
  1196.  
  1197.     $ltrs = '\w';
  1198.     $gunk = '/#~:.?+=&%@!\-';
  1199.     $punc = '.:?\-';
  1200.     $any = $ltrs . $gunk . $punc;
  1201.  
  1202.     preg_match_all( "{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp );
  1203.  
  1204.     debug_fwrite( $log, 'Post contents:' );
  1205.     debug_fwrite( $log, $content . "\n" );
  1206.  
  1207.     foreach ( $pung as $link_test ) {
  1208.         if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
  1209.             $mid = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
  1210.             do_action( 'delete_postmeta', $mid );
  1211.             $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id IN(%s)", implode( ',', $mid ) ) );
  1212.             do_action( 'deleted_postmeta', $mid );
  1213.         }
  1214.     }
  1215.  
  1216.     foreach ( (array) $post_links_temp[0] as $link_test ) {
  1217.         if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
  1218.             $test = @parse_url( $link_test );
  1219.             if ( false === $test )
  1220.                 continue;
  1221.             if ( isset( $test['query'] ) )
  1222.                 $post_links[] = $link_test;
  1223.             elseif ( isset($test['path']) && ( $test['path'] != '/' ) &&  ($test['path'] != '' ) )
  1224.                 $post_links[] = $link_test;
  1225.         }
  1226.     }
  1227.  
  1228.     foreach ( (array) $post_links as $url ) {
  1229.         if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ) . '%' ) ) ) {
  1230.  
  1231.             if ( $headers = wp_get_http_headers( $url) ) {
  1232.                 $len = (int) $headers['content-length'];
  1233.                 $type = $headers['content-type'];
  1234.                 $allowed_types = array( 'video', 'audio' );
  1235.  
  1236.                 // Check to see if we can figure out the mime type from
  1237.                 // the extension
  1238.                 $url_parts = @parse_url( $url );
  1239.                 if ( false !== $url_parts ) {
  1240.                     $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
  1241.                     if ( !empty( $extension ) ) {
  1242.                         foreach ( get_allowed_mime_types( ) as $exts => $mime ) {
  1243.                             if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
  1244.                                 $type = $mime;
  1245.                                 break;
  1246.                             }
  1247.                         }
  1248.                     }
  1249.                 }
  1250.  
  1251.                 if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
  1252.                     $meta_value = "$url\n$len\n$type\n";
  1253.                     $wpdb->insert($wpdb->postmeta, array('post_id' => $post_ID, 'meta_key' => 'enclosure', 'meta_value' => $meta_value) );
  1254.                     do_action( 'added_postmeta', $wpdb->insert_id, $post_ID, 'enclosure', $meta_value );
  1255.                 }
  1256.             }
  1257.         }
  1258.     }
  1259. }
  1260.  
  1261. /**
  1262.  * Perform a HTTP HEAD or GET request.
  1263.  *
  1264.  * If $file_path is a writable filename, this will do a GET request and write
  1265.  * the file to that path.
  1266.  *
  1267.  * @since 2.5.0
  1268.  *
  1269.  * @param string $url URL to fetch.
  1270.  * @param string|bool $file_path Optional. File path to write request to.
  1271.  * @param int $red (private) The number of Redirects followed, Upon 5 being hit, returns false.
  1272.  * @return bool|string False on failure and string of headers if HEAD request.
  1273.  */
  1274. function wp_get_http( $url, $file_path = false, $red = 1 ) {
  1275.     @set_time_limit( 60 );
  1276.  
  1277.     if ( $red > 5 )
  1278.         return false;
  1279.  
  1280.     $options = array();
  1281.     $options['redirection'] = 5;
  1282.  
  1283.     if ( false == $file_path )
  1284.         $options['method'] = 'HEAD';
  1285.     else
  1286.         $options['method'] = 'GET';
  1287.  
  1288.     $response = wp_remote_request($url, $options);
  1289.  
  1290.     if ( is_wp_error( $response ) )
  1291.         return false;
  1292.  
  1293.     $headers = wp_remote_retrieve_headers( $response );
  1294.     $headers['response'] = $response['response']['code'];
  1295.  
  1296.     // WP_HTTP no longer follows redirects for HEAD requests.
  1297.     if ( 'HEAD' == $options['method'] && in_array($headers['response'], array(301, 302)) && isset( $headers['location'] ) ) {
  1298.         return wp_get_http( $headers['location'], $file_path, ++$red );
  1299.     }
  1300.  
  1301.     if ( false == $file_path )
  1302.         return $headers;
  1303.  
  1304.     // GET request - write it to the supplied filename
  1305.     $out_fp = fopen($file_path, 'w');
  1306.     if ( !$out_fp )
  1307.         return $headers;
  1308.  
  1309.     fwrite( $out_fp,  $response['body']);
  1310.     fclose($out_fp);
  1311.     clearstatcache();
  1312.  
  1313.     return $headers;
  1314. }
  1315.  
  1316. /**
  1317.  * Retrieve HTTP Headers from URL.
  1318.  *
  1319.  * @since 1.5.1
  1320.  *
  1321.  * @param string $url
  1322.  * @param bool $deprecated Not Used.
  1323.  * @return bool|string False on failure, headers on success.
  1324.  */
  1325. function wp_get_http_headers( $url, $deprecated = false ) {
  1326.     if ( !empty( $deprecated ) )
  1327.         _deprecated_argument( __FUNCTION__, '2.7' );
  1328.  
  1329.     $response = wp_remote_head( $url );
  1330.  
  1331.     if ( is_wp_error( $response ) )
  1332.         return false;
  1333.  
  1334.     return wp_remote_retrieve_headers( $response );
  1335. }
  1336.  
  1337. /**
  1338.  * Whether today is a new day.
  1339.  *
  1340.  * @since 0.71
  1341.  * @uses $day Today
  1342.  * @uses $previousday Previous day
  1343.  *
  1344.  * @return int 1 when new day, 0 if not a new day.
  1345.  */
  1346. function is_new_day() {
  1347.     global $currentday, $previousday;
  1348.     if ( $currentday != $previousday )
  1349.         return 1;
  1350.     else
  1351.         return 0;
  1352. }
  1353.  
  1354. /**
  1355.  * Build URL query based on an associative and, or indexed array.
  1356.  *
  1357.  * This is a convenient function for easily building url queries. It sets the
  1358.  * separator to '&' and uses _http_build_query() function.
  1359.  *
  1360.  * @see _http_build_query() Used to build the query
  1361.  * @link http://us2.php.net/manual/en/function.http-build-query.php more on what
  1362.  *      http_build_query() does.
  1363.  *
  1364.  * @since 2.3.0
  1365.  *
  1366.  * @param array $data URL-encode key/value pairs.
  1367.  * @return string URL encoded string
  1368.  */
  1369. function build_query( $data ) {
  1370.     return _http_build_query( $data, null, '&', '', false );
  1371. }
  1372.  
  1373. /**
  1374.  * Retrieve a modified URL query string.
  1375.  *
  1376.  * You can rebuild the URL and append a new query variable to the URL query by
  1377.  * using this function. You can also retrieve the full URL with query data.
  1378.  *
  1379.  * Adding a single key & value or an associative array. Setting a key value to
  1380.  * emptystring removes the key. Omitting oldquery_or_uri uses the $_SERVER
  1381.  * value.
  1382.  *
  1383.  * @since 1.5.0
  1384.  *
  1385.  * @param mixed $param1 Either newkey or an associative_array
  1386.  * @param mixed $param2 Either newvalue or oldquery or uri
  1387.  * @param mixed $param3 Optional. Old query or uri
  1388.  * @return string New URL query string.
  1389.  */
  1390. function add_query_arg() {
  1391.     $ret = '';
  1392.     if ( is_array( func_get_arg(0) ) ) {
  1393.         if ( @func_num_args() < 2 || false === @func_get_arg( 1 ) )
  1394.             $uri = $_SERVER['REQUEST_URI'];
  1395.         else
  1396.             $uri = @func_get_arg( 1 );
  1397.     } else {
  1398.         if ( @func_num_args() < 3 || false === @func_get_arg( 2 ) )
  1399.             $uri = $_SERVER['REQUEST_URI'];
  1400.         else
  1401.             $uri = @func_get_arg( 2 );
  1402.     }
  1403.  
  1404.     if ( $frag = strstr( $uri, '#' ) )
  1405.         $uri = substr( $uri, 0, -strlen( $frag ) );
  1406.     else
  1407.         $frag = '';
  1408.  
  1409.     if ( preg_match( '|^https?://|i', $uri, $matches ) ) {
  1410.         $protocol = $matches[0];
  1411.         $uri = substr( $uri, strlen( $protocol ) );
  1412.     } else {
  1413.         $protocol = '';
  1414.     }
  1415.  
  1416.     if ( strpos( $uri, '?' ) !== false ) {
  1417.         $parts = explode( '?', $uri, 2 );
  1418.         if ( 1 == count( $parts ) ) {
  1419.             $base = '?';
  1420.             $query = $parts[0];
  1421.         } else {
  1422.             $base = $parts[0] . '?';
  1423.             $query = $parts[1];
  1424.         }
  1425.     } elseif ( !empty( $protocol ) || strpos( $uri, '=' ) === false ) {
  1426.         $base = $uri . '?';
  1427.         $query = '';
  1428.     } else {
  1429.         $base = '';
  1430.         $query = $uri;
  1431.     }
  1432.  
  1433.     wp_parse_str( $query, $qs );
  1434.     $qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
  1435.     if ( is_array( func_get_arg( 0 ) ) ) {
  1436.         $kayvees = func_get_arg( 0 );
  1437.         $qs = array_merge( $qs, $kayvees );
  1438.     } else {
  1439.         $qs[func_get_arg( 0 )] = func_get_arg( 1 );
  1440.     }
  1441.  
  1442.     foreach ( (array) $qs as $k => $v ) {
  1443.         if ( $v === false )
  1444.             unset( $qs[$k] );
  1445.     }
  1446.  
  1447.     $ret = build_query( $qs );
  1448.     $ret = trim( $ret, '?' );
  1449.     $ret = preg_replace( '#=(&|$)#', '$1', $ret );
  1450.     $ret = $protocol . $base . $ret . $frag;
  1451.     $ret = rtrim( $ret, '?' );
  1452.     return $ret;
  1453. }
  1454.  
  1455. /**
  1456.  * Removes an item or list from the query string.
  1457.  *
  1458.  * @since 1.5.0
  1459.  *
  1460.  * @param string|array $key Query key or keys to remove.
  1461.  * @param bool $query When false uses the $_SERVER value.
  1462.  * @return string New URL query string.
  1463.  */
  1464. function remove_query_arg( $key, $query=false ) {
  1465.     if ( is_array( $key ) ) { // removing multiple keys
  1466.         foreach ( $key as $k )
  1467.             $query = add_query_arg( $k, false, $query );
  1468.         return $query;
  1469.     }
  1470.     return add_query_arg( $key, false, $query );
  1471. }
  1472.  
  1473. /**
  1474.  * Walks the array while sanitizing the contents.
  1475.  *
  1476.  * @since 0.71
  1477.  *
  1478.  * @param array $array Array to used to walk while sanitizing contents.
  1479.  * @return array Sanitized $array.
  1480.  */
  1481. function add_magic_quotes( $array ) {
  1482.     foreach ( (array) $array as $k => $v ) {
  1483.         if ( is_array( $v ) ) {
  1484.             $array[$k] = add_magic_quotes( $v );
  1485.         } else {
  1486.             $array[$k] = addslashes( $v );
  1487.         }
  1488.     }
  1489.     return $array;
  1490. }
  1491.  
  1492. /**
  1493.  * HTTP request for URI to retrieve content.
  1494.  *
  1495.  * @since 1.5.1
  1496.  * @uses wp_remote_get()
  1497.  *
  1498.  * @param string $uri URI/URL of web page to retrieve.
  1499.  * @return bool|string HTTP content. False on failure.
  1500.  */
  1501. function wp_remote_fopen( $uri ) {
  1502.     $parsed_url = @parse_url( $uri );
  1503.  
  1504.     if ( !$parsed_url || !is_array( $parsed_url ) )
  1505.         return false;
  1506.  
  1507.     $options = array();
  1508.     $options['timeout'] = 10;
  1509.  
  1510.     $response = wp_remote_get( $uri, $options );
  1511.  
  1512.     if ( is_wp_error( $response ) )
  1513.         return false;
  1514.  
  1515.     return $response['body'];
  1516. }
  1517.  
  1518. /**
  1519.  * Set up the WordPress query.
  1520.  *
  1521.  * @since 2.0.0
  1522.  *
  1523.  * @param string $query_vars Default WP_Query arguments.
  1524.  */
  1525. function wp( $query_vars = '' ) {
  1526.     global $wp, $wp_query, $wp_the_query;
  1527.     $wp->main( $query_vars );
  1528.  
  1529.     if ( !isset($wp_the_query) )
  1530.         $wp_the_query = $wp_query;
  1531. }
  1532.  
  1533. /**
  1534.  * Retrieve the description for the HTTP status.
  1535.  *
  1536.  * @since 2.3.0
  1537.  *
  1538.  * @param int $code HTTP status code.
  1539.  * @return string Empty string if not found, or description if found.
  1540.  */
  1541. function get_status_header_desc( $code ) {
  1542.     global $wp_header_to_desc;
  1543.  
  1544.     $code = absint( $code );
  1545.  
  1546.     if ( !isset( $wp_header_to_desc ) ) {
  1547.         $wp_header_to_desc = array(
  1548.             100 => 'Continue',
  1549.             101 => 'Switching Protocols',
  1550.             102 => 'Processing',
  1551.  
  1552.             200 => 'OK',
  1553.             201 => 'Created',
  1554.             202 => 'Accepted',
  1555.             203 => 'Non-Authoritative Information',
  1556.             204 => 'No Content',
  1557.             205 => 'Reset Content',
  1558.             206 => 'Partial Content',
  1559.             207 => 'Multi-Status',
  1560.             226 => 'IM Used',
  1561.  
  1562.             300 => 'Multiple Choices',
  1563.             301 => 'Moved Permanently',
  1564.             302 => 'Found',
  1565.             303 => 'See Other',
  1566.             304 => 'Not Modified',
  1567.             305 => 'Use Proxy',
  1568.             306 => 'Reserved',
  1569.             307 => 'Temporary Redirect',
  1570.  
  1571.             400 => 'Bad Request',
  1572.             401 => 'Unauthorized',
  1573.             402 => 'Payment Required',
  1574.             403 => 'Forbidden',
  1575.             404 => 'Not Found',
  1576.             405 => 'Method Not Allowed',
  1577.             406 => 'Not Acceptable',
  1578.             407 => 'Proxy Authentication Required',
  1579.             408 => 'Request Timeout',
  1580.             409 => 'Conflict',
  1581.             410 => 'Gone',
  1582.             411 => 'Length Required',
  1583.             412 => 'Precondition Failed',
  1584.             413 => 'Request Entity Too Large',
  1585.             414 => 'Request-URI Too Long',
  1586.             415 => 'Unsupported Media Type',
  1587.             416 => 'Requested Range Not Satisfiable',
  1588.             417 => 'Expectation Failed',
  1589.             422 => 'Unprocessable Entity',
  1590.             423 => 'Locked',
  1591.             424 => 'Failed Dependency',
  1592.             426 => 'Upgrade Required',
  1593.  
  1594.             500 => 'Internal Server Error',
  1595.             501 => 'Not Implemented',
  1596.             502 => 'Bad Gateway',
  1597.             503 => 'Service Unavailable',
  1598.             504 => 'Gateway Timeout',
  1599.             505 => 'HTTP Version Not Supported',
  1600.             506 => 'Variant Also Negotiates',
  1601.             507 => 'Insufficient Storage',
  1602.             510 => 'Not Extended'
  1603.         );
  1604.     }
  1605.  
  1606.     if ( isset( $wp_header_to_desc[$code] ) )
  1607.         return $wp_header_to_desc[$code];
  1608.     else
  1609.         return '';
  1610. }
  1611.  
  1612. /**
  1613.  * Set HTTP status header.
  1614.  *
  1615.  * @since 2.0.0
  1616.  * @uses apply_filters() Calls 'status_header' on status header string, HTTP
  1617.  *      HTTP code, HTTP code description, and protocol string as separate
  1618.  *      parameters.
  1619.  *
  1620.  * @param int $header HTTP status code
  1621.  * @return unknown
  1622.  */
  1623. function status_header( $header ) {
  1624.     $text = get_status_header_desc( $header );
  1625.  
  1626.     if ( empty( $text ) )
  1627.         return false;
  1628.  
  1629.     $protocol = $_SERVER["SERVER_PROTOCOL"];
  1630.     if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
  1631.         $protocol = 'HTTP/1.0';
  1632.     $status_header = "$protocol $header $text";
  1633.     if ( function_exists( 'apply_filters' ) )
  1634.         $status_header = apply_filters( 'status_header', $status_header, $header, $text, $protocol );
  1635.  
  1636.     return @header( $status_header, true, $header );
  1637. }
  1638.  
  1639. /**
  1640.  * Gets the header information to prevent caching.
  1641.  *
  1642.  * The several different headers cover the different ways cache prevention is handled
  1643.  * by different browsers
  1644.  *
  1645.  * @since 2.8.0
  1646.  *
  1647.  * @uses apply_filters()
  1648.  * @return array The associative array of header names and field values.
  1649.  */
  1650. function wp_get_nocache_headers() {
  1651.     $headers = array(
  1652.         'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
  1653.         'Last-Modified' => gmdate( 'D, d M Y H:i:s' ) . ' GMT',
  1654.         'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
  1655.         'Pragma' => 'no-cache',
  1656.     );
  1657.  
  1658.     if ( function_exists('apply_filters') ) {
  1659.         $headers = (array) apply_filters('nocache_headers', $headers);
  1660.     }
  1661.     return $headers;
  1662. }
  1663.  
  1664. /**
  1665.  * Sets the headers to prevent caching for the different browsers.
  1666.  *
  1667.  * Different browsers support different nocache headers, so several headers must
  1668.  * be sent so that all of them get the point that no caching should occur.
  1669.  *
  1670.  * @since 2.0.0
  1671.  * @uses wp_get_nocache_headers()
  1672.  */
  1673. function nocache_headers() {
  1674.     $headers = wp_get_nocache_headers();
  1675.     foreach( $headers as $name => $field_value )
  1676.         @header("{$name}: {$field_value}");
  1677. }
  1678.  
  1679. /**
  1680.  * Set the headers for caching for 10 days with JavaScript content type.
  1681.  *
  1682.  * @since 2.1.0
  1683.  */
  1684. function cache_javascript_headers() {
  1685.     $expiresOffset = 864000; // 10 days
  1686.     header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );
  1687.     header( "Vary: Accept-Encoding" ); // Handle proxies
  1688.     header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );
  1689. }
  1690.  
  1691. /**
  1692.  * Retrieve the number of database queries during the WordPress execution.
  1693.  *
  1694.  * @since 2.0.0
  1695.  *
  1696.  * @return int Number of database queries
  1697.  */
  1698. function get_num_queries() {
  1699.     global $wpdb;
  1700.     return $wpdb->num_queries;
  1701. }
  1702.  
  1703. /**
  1704.  * Whether input is yes or no. Must be 'y' to be true.
  1705.  *
  1706.  * @since 1.0.0
  1707.  *
  1708.  * @param string $yn Character string containing either 'y' or 'n'
  1709.  * @return bool True if yes, false on anything else
  1710.  */
  1711. function bool_from_yn( $yn ) {
  1712.     return ( strtolower( $yn ) == 'y' );
  1713. }
  1714.  
  1715. /**
  1716.  * Loads the feed template from the use of an action hook.
  1717.  *
  1718.  * If the feed action does not have a hook, then the function will die with a
  1719.  * message telling the visitor that the feed is not valid.
  1720.  *
  1721.  * It is better to only have one hook for each feed.
  1722.  *
  1723.  * @since 2.1.0
  1724.  * @uses $wp_query Used to tell if the use a comment feed.
  1725.  * @uses do_action() Calls 'do_feed_$feed' hook, if a hook exists for the feed.
  1726.  */
  1727. function do_feed() {
  1728.     global $wp_query;
  1729.  
  1730.     $feed = get_query_var( 'feed' );
  1731.  
  1732.     // Remove the pad, if present.
  1733.     $feed = preg_replace( '/^_+/', '', $feed );
  1734.  
  1735.     if ( $feed == '' || $feed == 'feed' )
  1736.         $feed = get_default_feed();
  1737.  
  1738.     $hook = 'do_feed_' . $feed;
  1739.     if ( !has_action($hook) ) {
  1740.         $message = sprintf( __( 'ERROR: %s is not a valid feed template.' ), esc_html($feed));
  1741.         wp_die( $message, '', array( 'response' => 404 ) );
  1742.     }
  1743.  
  1744.     do_action( $hook, $wp_query->is_comment_feed );
  1745. }
  1746.  
  1747. /**
  1748.  * Load the RDF RSS 0.91 Feed template.
  1749.  *
  1750.  * @since 2.1.0
  1751.  */
  1752. function do_feed_rdf() {
  1753.     load_template( ABSPATH . WPINC . '/feed-rdf.php' );
  1754. }
  1755.  
  1756. /**
  1757.  * Load the RSS 1.0 Feed Template
  1758.  *
  1759.  * @since 2.1.0
  1760.  */
  1761. function do_feed_rss() {
  1762.     load_template( ABSPATH . WPINC . '/feed-rss.php' );
  1763. }
  1764.  
  1765. /**
  1766.  * Load either the RSS2 comment feed or the RSS2 posts feed.
  1767.  *
  1768.  * @since 2.1.0
  1769.  *
  1770.  * @param bool $for_comments True for the comment feed, false for normal feed.
  1771.  */
  1772. function do_feed_rss2( $for_comments ) {
  1773.     if ( $for_comments )
  1774.         load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
  1775.     else
  1776.         load_template( ABSPATH . WPINC . '/feed-rss2.php' );
  1777. }
  1778.  
  1779. /**
  1780.  * Load either Atom comment feed or Atom posts feed.
  1781.  *
  1782.  * @since 2.1.0
  1783.  *
  1784.  * @param bool $for_comments True for the comment feed, false for normal feed.
  1785.  */
  1786. function do_feed_atom( $for_comments ) {
  1787.     if ($for_comments)
  1788.         load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
  1789.     else
  1790.         load_template( ABSPATH . WPINC . '/feed-atom.php' );
  1791. }
  1792.  
  1793. /**
  1794.  * Display the robot.txt file content.
  1795.  *
  1796.  * The echo content should be with usage of the permalinks or for creating the
  1797.  * robot.txt file.
  1798.  *
  1799.  * @since 2.1.0
  1800.  * @uses do_action() Calls 'do_robotstxt' hook for displaying robot.txt rules.
  1801.  */
  1802. function do_robots() {
  1803.     header( 'Content-Type: text/plain; charset=utf-8' );
  1804.  
  1805.     do_action( 'do_robotstxt' );
  1806.  
  1807.     $output = '';
  1808.     $public = get_option( 'blog_public' );
  1809.     if ( '0' ==  $public ) {
  1810.         $output .= "User-agent: *\n";
  1811.         $output .= "Disallow: /\n";
  1812.     } else {
  1813.         $output .= "User-agent: *\n";
  1814.         $output .= "Disallow:\n";
  1815.     }
  1816.  
  1817.     echo apply_filters('robots_txt', $output, $public);
  1818. }
  1819.  
  1820. /**
  1821.  * Test whether blog is already installed.
  1822.  *
  1823.  * The cache will be checked first. If you have a cache plugin, which saves the
  1824.  * cache values, then this will work. If you use the default WordPress cache,
  1825.  * and the database goes away, then you might have problems.
  1826.  *
  1827.  * Checks for the option siteurl for whether WordPress is installed.
  1828.  *
  1829.  * @since 2.1.0
  1830.  * @uses $wpdb
  1831.  *
  1832.  * @return bool Whether blog is already installed.
  1833.  */
  1834. function is_blog_installed() {
  1835.     global $wpdb;
  1836.  
  1837.     // Check cache first. If options table goes away and we have true cached, oh well.
  1838.     if ( wp_cache_get( 'is_blog_installed' ) )
  1839.         return true;
  1840.  
  1841.     $suppress = $wpdb->suppress_errors();
  1842.     if ( ! defined( 'WP_INSTALLING' ) ) {
  1843.         $alloptions = wp_load_alloptions();
  1844.     }
  1845.     // If siteurl is not set to autoload, check it specifically
  1846.     if ( !isset( $alloptions['siteurl'] ) )
  1847.         $installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1848.     else
  1849.         $installed = $alloptions['siteurl'];
  1850.     $wpdb->suppress_errors( $suppress
  1851.  
  1852. ;?>
Advertisement
Add Comment
Please, Sign In to add comment