[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-forums/bbpress/bb-admin/includes/ -> functions.bb-upgrade.php (source)

   1  <?php
   2  function bb_install() {
   3      require_once( BACKPRESS_PATH . 'class.bp-sql-schema-parser.php' );
   4      require_once( BB_PATH . 'bb-admin/includes/defaults.bb-schema.php' );
   5      $alterations = BP_SQL_Schema_Parser::delta( $bbdb, $bb_queries, $bb_schema_ignore );
   6  
   7      bb_update_db_version();
   8  
   9      return array_filter($alterations);
  10  }
  11  
  12  function bb_upgrade_all()
  13  {
  14      if ( !ini_get( 'safe_mode' ) ) {
  15          set_time_limit(600);
  16      }
  17  
  18      $_do_user_operations = true;
  19      if ( bb_get_option( 'wp_table_prefix' ) || ( defined( 'BB_SCHEMA_IGNORE_WP_USERS_TABLES' ) && BB_SCHEMA_IGNORE_WP_USERS_TABLES ) ) {
  20          $_do_user_operations = false;
  21      }
  22  
  23      $bb_upgrade = array();
  24  
  25      // Pre DB Delta
  26      if ( $_do_user_operations ) {
  27          $bb_upgrade['messages'][] = bb_upgrade_160(); // Break blocked users
  28          $bb_upgrade['messages'][] = bb_upgrade_170(); // Escaping in usermeta
  29          $bb_upgrade['messages'][] = bb_upgrade_180(); // Delete users for real
  30      }
  31      $bb_upgrade['messages'][] = bb_upgrade_190(); // Move topic_resolved to topicmeta
  32      $bb_upgrade['messages'][] = bb_upgrade_200(); // Indices
  33      $bb_upgrade['messages'][] = bb_upgrade_210(); // Convert text slugs to varchar slugs
  34      $bb_upgrade['messages'][] = bb_upgrade_220(); // remove bb_tagged primary key, add new column and primary key
  35  
  36      require_once( BACKPRESS_PATH . 'class.bp-sql-schema-parser.php' );
  37      require_once( BB_PATH . 'bb-admin/includes/defaults.bb-schema.php' );
  38      $delta = BP_SQL_Schema_Parser::delta( $bbdb, $bb_queries, $bb_schema_ignore );
  39      if ( is_array( $delta ) ) {
  40          $bb_upgrade['messages'] = array_merge($bb_upgrade['messages'], $delta['messages']);
  41          $bb_upgrade['errors'] = $delta['errors'];
  42      } else {
  43          $bb_upgrade['errors'] = array();
  44      }
  45  
  46      // Post DB Delta
  47      $bb_upgrade['messages'][] = bb_upgrade_1000(); // Make forum and topic slugs
  48      $bb_upgrade['messages'][] = bb_upgrade_1010(); // Make sure all forums have a valid parent
  49      if ( $_do_user_operations ) {
  50          $bb_upgrade['messages'][] = bb_upgrade_1020(); // Add a user_nicename to existing users
  51      }
  52      $bb_upgrade['messages'][] = bb_upgrade_1030(); // Move admin_email option to from_email
  53      $bb_upgrade['messages'][] = bb_upgrade_1040(); // Activate Akismet and bozo plugins and convert active plugins to new convention on upgrade only
  54      $bb_upgrade['messages'][] = bb_upgrade_1050(); // Update active theme if present
  55      $bb_upgrade['messages'][] = bb_upgrade_1070(); // trim whitespace from raw_tag
  56      $bb_upgrade['messages'][] = bb_upgrade_1080(); // Convert tags to taxonomy
  57      if ( $_do_user_operations ) {
  58          $bb_upgrade['messages'][] = bb_upgrade_1090(); // Add display names
  59      }
  60      $bb_upgrade['messages'][] = bb_upgrade_1100(); // Replace forum_stickies index with stickies (#876)
  61      $bb_upgrade['messages'][] = bb_upgrade_1110(); // Create plugin directory (#1083)
  62      $bb_upgrade['messages'][] = bb_upgrade_1120(); // Create theme directory (#1083)
  63      $bb_upgrade['messages'][] = bb_upgrade_1130(); // Add subscriptions option and set it to true (#1268)
  64  
  65      bb_update_db_version();
  66      wp_cache_flush();
  67  
  68      $bb_upgrade['messages'] = array_filter($bb_upgrade['messages']);
  69      $bb_upgrade['errors'] = array_filter($bb_upgrade['errors']);
  70  
  71      return $bb_upgrade;
  72  }
  73  
  74  function bb_upgrade_process_all_slugs() {
  75      global $bbdb;
  76      // Forums
  77  
  78      $forums = (array) $bbdb->get_results("SELECT forum_id, forum_name FROM $bbdb->forums ORDER BY forum_order ASC" );
  79  
  80      $slugs = array();
  81      foreach ( $forums as $forum ) :
  82          $slug = bb_slug_sanitize( wp_specialchars_decode( $forum->forum_name, ENT_QUOTES ) );
  83          $slugs[$slug][] = $forum->forum_id;
  84      endforeach;
  85  
  86      foreach ( $slugs as $slug => $forum_ids ) :
  87          foreach ( $forum_ids as $count => $forum_id ) :
  88              $_slug = $slug;
  89              $count = - $count; // madness
  90              if ( is_numeric($slug) || $count )
  91                  $_slug = bb_slug_increment( $slug, $count );
  92              $bbdb->query("UPDATE $bbdb->forums SET forum_slug = '$_slug' WHERE forum_id = '$forum_id';");
  93          endforeach;
  94      endforeach;
  95      unset($forums, $forum, $slugs, $slug, $_slug, $forum_ids, $forum_id, $count);
  96  
  97      // Topics
  98  
  99      $topics = (array) $bbdb->get_results("SELECT topic_id, topic_title FROM $bbdb->topics ORDER BY topic_start_time ASC" );
 100  
 101      $slugs = array();
 102      foreach ( $topics as $topic) :
 103          $slug = bb_slug_sanitize( wp_specialchars_decode( $topic->topic_title, ENT_QUOTES ) );
 104          $slugs[$slug][] = $topic->topic_id;
 105      endforeach;
 106  
 107      foreach ( $slugs as $slug => $topic_ids ) :
 108          foreach ( $topic_ids as $count => $topic_id ) :
 109              $_slug = $slug;
 110              $count = - $count;
 111              if ( is_numeric($slug) || $count )
 112                  $_slug = bb_slug_increment( $slug, $count );
 113              $bbdb->query("UPDATE $bbdb->topics SET topic_slug = '$_slug' WHERE topic_id = '$topic_id';");
 114          endforeach;
 115      endforeach;
 116      unset($topics, $topic, $slugs, $slug, $_slug, $topic_ids, $topic_id, $count);
 117  }
 118  
 119  // Reversibly break passwords of blocked users.
 120  function bb_upgrade_160() {
 121      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 535 )
 122          return;
 123  
 124      require_once ( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
 125      $blocked = bb_get_ids_by_role( 'blocked' );
 126      foreach ( $blocked as $b )
 127          bb_break_password( $b );
 128      return 'Done reversibly breaking passwords: ' . __FUNCTION__;
 129  }
 130  
 131  function bb_upgrade_170() {
 132      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 536 )
 133          return;
 134  
 135      global $bbdb;
 136      foreach ( (array) $bbdb->get_results("SELECT * FROM $bbdb->usermeta WHERE meta_value LIKE '%&quot;%' OR meta_value LIKE '%&#039;%'") as $meta ) {
 137          $value = str_replace(array('&quot;', '&#039;'), array('"', "'"), $meta->meta_value);
 138          $value = stripslashes($value);
 139          bb_update_usermeta( $meta->user_id, $meta->meta_key, $value);
 140      }
 141      bb_update_option( 'bb_db_version', 536 );
 142      return 'Done updating usermeta: ' . __FUNCTION__;
 143  }
 144  
 145  function bb_upgrade_180() {
 146      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 559 )
 147          return;
 148  
 149      global $bbdb;
 150  
 151      foreach ( (array) $bbdb->get_col("SELECT ID FROM $bbdb->users WHERE user_status = 1") as $user_id )
 152          bb_delete_user( $user_id );
 153      bb_update_option( 'bb_db_version', 559 );
 154      return 'Done clearing deleted users: ' . __FUNCTION__;
 155  }
 156  
 157  function bb_upgrade_190() {
 158      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 630 )
 159          return;
 160  
 161      global $bbdb;
 162  
 163      $exists = false;
 164      foreach ( (array) $bbdb->get_col("DESC $bbdb->topics") as $col )
 165          if ( 'topic_resolved' == $col )
 166              $exists = true;
 167      if ( !$exists )
 168          return;
 169  
 170      $topics = (array) $bbdb->get_results("SELECT topic_id, topic_resolved FROM $bbdb->topics" );
 171      foreach ( $topics  as $topic )
 172          bb_update_topicmeta( $topic->topic_id, 'topic_resolved', $topic->topic_resolved );
 173      unset($topics,$topic);
 174  
 175      $bbdb->query("ALTER TABLE $bbdb->topics DROP topic_resolved");
 176  
 177      bb_update_option( 'bb_db_version', 630 );
 178  
 179      return 'Done converting topic_resolved: ' . __FUNCTION__;
 180  }
 181  
 182  function bb_upgrade_200() {
 183      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 845 )
 184          return;
 185  
 186      global $bbdb;
 187  
 188      $bbdb->hide_errors();
 189      $bbdb->query( "DROP INDEX tag_id_index ON $bbdb->tagged" );
 190      $bbdb->query( "DROP INDEX user_id ON $bbdb->topicmeta" );
 191      $bbdb->query( "DROP INDEX forum_id ON $bbdb->topics" );
 192      $bbdb->query( "DROP INDEX topic_time ON $bbdb->topics" );
 193      $bbdb->query( "DROP INDEX topic_start_time ON $bbdb->topics" );
 194      $bbdb->query( "DROP INDEX tag_id_index ON $bbdb->tagged" );
 195      $bbdb->query( "DROP INDEX topic_id ON $bbdb->posts" );
 196      $bbdb->query( "DROP INDEX poster_id ON $bbdb->posts" );
 197      $bbdb->show_errors();
 198  
 199      bb_update_option( 'bb_db_version', 845 );
 200  
 201      return 'Done removing old indices: ' . __FUNCTION__;
 202  }
 203  
 204  // 210 converts text slugs to varchar(255) width slugs (upgrading from alpha version - fires before dbDelta)
 205  // 1000 Gives new slugs (upgrading from previous release - fires after dbDelta)
 206  function bb_upgrade_210() {
 207      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 846 )
 208          return;
 209  
 210      global $bbdb;
 211  
 212      $bbdb->hide_errors();
 213      if ( !$bbdb->get_var("SELECT forum_slug FROM $bbdb->forums ORDER BY forum_order ASC LIMIT 1" ) )
 214          return; // Wait till after dbDelta
 215      $bbdb->show_errors();
 216  
 217      bb_upgrade_process_all_slugs();
 218  
 219      bb_update_option( 'bb_db_version', 846 );
 220      
 221      return 'Done adding slugs: ' . __FUNCTION__;
 222  }
 223  
 224  function bb_upgrade_220() {
 225      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1051 )
 226          return;
 227  
 228      global $bbdb;
 229  
 230      $bbdb->query( "ALTER TABLE $bbdb->tagged DROP PRIMARY KEY" );
 231      $bbdb->query( "ALTER TABLE $bbdb->tagged ADD tagged_id bigint(20) unsigned NOT NULL auto_increment PRIMARY KEY FIRST" );
 232  
 233      return "Done removing key from $bbdb->tagged: " . __FUNCTION__;
 234  }
 235  
 236  function bb_upgrade_1000() { // Give all topics and forums slugs
 237      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 846 )
 238          return;
 239  
 240      bb_upgrade_process_all_slugs();
 241  
 242      bb_update_option( 'bb_db_version', 846 );
 243      
 244      return 'Done adding slugs: ' . __FUNCTION__;;
 245  }
 246  
 247  // Make sure all forums have a valid parent
 248  function bb_upgrade_1010() {
 249      global $bbdb;
 250      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 952 )
 251          return;
 252  
 253      $forums = (array) $bbdb->get_results( "SELECT forum_id, forum_parent FROM $bbdb->forums" );
 254      $forum_ids = (array) $bbdb->get_col( '', 0 );
 255  
 256      foreach ( $forums as $forum ) {
 257          if ( $forum->forum_parent && !in_array( $forum->forum_parent, $forum_ids ) )
 258              $bbdb->query( "UPDATE $bbdb->forums SET forum_parent = 0 WHERE forum_id = '$forum->forum_id'" );
 259      }
 260  
 261      bb_update_option( 'bb_db_version', 952 );
 262      
 263      return 'Done re-parenting orphaned forums: ' . __FUNCTION__;
 264  }
 265  
 266  // Add a nicename for existing users if they don't have one already
 267  function bb_upgrade_1020() {
 268      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 977 )
 269          return;
 270      
 271      global $bbdb;
 272      
 273      $users = $bbdb->get_results( "SELECT ID, user_login, user_nicename FROM $bbdb->users WHERE user_nicename IS NULL OR user_nicename = ''" );
 274      
 275      if ( $users ) {
 276          foreach ( $users as $user ) {
 277              $user_nicename = $_user_nicename = bb_user_nicename_sanitize( $user->user_login );
 278              while ( is_numeric($user_nicename) || $existing_user = bb_get_user_by_nicename( $user_nicename ) )
 279                  $user_nicename = bb_slug_increment($_user_nicename, $existing_user->user_nicename, 50);
 280              
 281              $bbdb->query( "UPDATE $bbdb->users SET user_nicename = '$user_nicename' WHERE ID = $user->ID;" );
 282          }
 283      }
 284      
 285      bb_update_option( 'bb_db_version', 977 );
 286      
 287      return 'Done adding nice-names to existing users: ' . __FUNCTION__;
 288  }
 289  
 290  // Move admin_email option to from_email
 291  function bb_upgrade_1030() {
 292      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1058 )
 293          return;
 294      
 295      $admin_email = bb_get_option('admin_email');
 296      if ($admin_email) {
 297          bb_update_option('from_email', $admin_email);
 298      }
 299      bb_delete_option('admin_email');
 300      
 301      bb_update_option( 'bb_db_version', 1058 );
 302      
 303      return 'Done moving admin_email to from_email: ' . __FUNCTION__;
 304  }
 305  
 306  // Activate Akismet and bozo plugins and convert active plugins to new convention on upgrade only
 307  function bb_upgrade_1040() {
 308      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1230 )
 309          return;
 310      
 311      // Only do this when upgrading
 312      if ( defined( 'BB_UPGRADING' ) && BB_UPGRADING ) {
 313          $plugins = bb_get_option('active_plugins');
 314          if ( bb_get_option('akismet_key') && !in_array('core#akismet.php', $plugins) ) {
 315              $plugins[] = 'core#akismet.php';
 316          }
 317          if ( !in_array('core#bozo.php', $plugins) ) {
 318              $plugins[] = 'core#bozo.php';
 319          }
 320          
 321          $new_plugins = array();
 322          foreach ($plugins as $plugin) {
 323              if (substr($plugin, 0, 5) != 'core#') {
 324                  if ($plugin != 'akismet.php' && $plugin != 'bozo.php') {
 325                      $new_plugins[] = 'user#' . $plugin;
 326                  }
 327              } else {
 328                  $new_plugins[] = $plugin;
 329              }
 330          }
 331          
 332          bb_update_option( 'active_plugins', $new_plugins );
 333      }
 334      
 335      bb_update_option( 'bb_db_version', 1230 );
 336      
 337      return 'Done activating Akismet and Bozo plugins and converting active plugins to new convention on upgrade only: ' . __FUNCTION__;
 338  }
 339  
 340  // Update active theme if present
 341  function bb_upgrade_1050() {
 342      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1234 )
 343          return;
 344      
 345      // Only do this when upgrading
 346      if ( defined( 'BB_UPGRADING' ) && BB_UPGRADING ) {
 347          if ( $theme = bb_get_option( 'bb_active_theme' ) ) {
 348              bb_update_option( 'bb_active_theme', bb_theme_basename( $theme ) );
 349          }
 350      }
 351      
 352      bb_update_option( 'bb_db_version', 1234 );
 353      
 354      return 'Done updating active theme if present: ' . __FUNCTION__;
 355  }
 356  
 357  function bb_upgrade_1070() {
 358      global $bbdb;
 359      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1467 )
 360          return;
 361  
 362      $bbdb->query( "UPDATE `$bbdb->tags` SET `raw_tag` = TRIM(`raw_tag`)" );
 363  
 364      bb_update_option( 'bb_db_version', 1467 );
 365  
 366      return 'Whitespace trimmed from raw_tag: ' . __FUNCTION__;
 367  }
 368  
 369  function bb_upgrade_1080() {
 370      global $bbdb, $wp_taxonomy_object;
 371      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1526 )
 372          return;
 373  
 374      $offset = 0;
 375      while ( $tags = (array) $bbdb->get_results( "SELECT * FROM $bbdb->tags LIMIT $offset, 100" ) ) {
 376          if ( !ini_get('safe_mode') ) set_time_limit(600);
 377          $wp_taxonomy_object->defer_term_counting(true);
 378          for ( $i = 0; isset($tags[$i]); $i++ ) {
 379              $bbdb->insert( $bbdb->terms, array( 
 380                  'name' => $tags[$i]->raw_tag,
 381                  'slug' => $tags[$i]->tag
 382              ) );
 383              $term_id = $bbdb->insert_id;
 384              $bbdb->insert( $bbdb->term_taxonomy, array(
 385                  'term_id' => $term_id,
 386                  'taxonomy' => 'bb_topic_tag',
 387                  'description' => ''
 388              ) );
 389              $term_taxonomy_id = $bbdb->insert_id;
 390              $topics = (array) $bbdb->get_results( $bbdb->prepare( "SELECT user_id, topic_id FROM $bbdb->tagged WHERE tag_id = %d", $tags[$i]->tag_id ) );
 391              for ( $j = 0; isset($topics[$j]); $j++ ) {
 392                  $bbdb->insert( $bbdb->term_relationships, array(
 393                      'object_id' => $topics[$j]->topic_id,
 394                      'term_taxonomy_id' => $term_taxonomy_id,
 395                      'user_id' => $topics[$j]->user_id
 396                  ) );
 397              }
 398              $wp_taxonomy_object->update_term_count( array( $term_taxonomy_id ), 'bb_topic_tag' );
 399          }
 400          $wp_taxonomy_object->defer_term_counting(false);
 401          $offset += 100;
 402      }
 403  
 404      bb_update_option( 'bb_db_version', 1526 );
 405  
 406      return 'Tags copied to taxonomy tables: ' . __FUNCTION__;
 407  }
 408  
 409  function bb_upgrade_1090() {
 410      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1589 )
 411          return;
 412  
 413      global $bbdb;
 414  
 415      $users = (array) $bbdb->get_results( "SELECT `ID`, `user_login` FROM $bbdb->users WHERE `display_name` = '' OR `display_name` IS NULL;" );
 416  
 417      if ($users) {
 418          foreach ($users as $user) {
 419              $bbdb->query( "UPDATE $bbdb->users SET `display_name` = '" . $user->user_login . "' WHERE ID = " . $user->ID . ";" );
 420          }
 421          unset($user, $users);
 422      }
 423  
 424      bb_update_option( 'bb_db_version', 1589 );
 425  
 426      return 'Display names populated: ' . __FUNCTION__;
 427  }
 428  
 429  function bb_upgrade_1100() {
 430      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 1638 )
 431          return;
 432  
 433      global $bbdb;
 434  
 435      $bbdb->query( "DROP INDEX forum_stickies ON $bbdb->topics" );
 436  
 437      bb_update_option( 'bb_db_version', 1638 );
 438  
 439      return 'Index forum_stickies dropped: ' . __FUNCTION__;
 440  }
 441  
 442  function bb_upgrade_1110() {
 443      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 2077 )
 444          return;
 445  
 446      // No matter what happens, update the db version
 447      bb_update_option( 'bb_db_version', 2077 );
 448  
 449      if ( !defined( 'BB_PLUGIN_DIR' ) ) {
 450          return;
 451      }
 452  
 453      if ( !BB_PLUGIN_DIR ) {
 454          return;
 455      }
 456  
 457      if ( file_exists( BB_PLUGIN_DIR ) ) {
 458          return;
 459      }
 460  
 461      // Just suppress errors as this is not critical
 462      if ( @mkdir( BB_PLUGIN_DIR, 0755 ) ) {
 463          return 'Making plugin directory at ' . BB_PLUGIN_DIR . ': ' . __FUNCTION__;
 464      }
 465  
 466      return;
 467  }
 468  
 469  function bb_upgrade_1120() {
 470      if ( ( $dbv = bb_get_option_from_db( 'bb_db_version' ) ) && $dbv >= 2078 ) {
 471          return;
 472      }
 473  
 474      // No matter what happens, update the db version
 475      bb_update_option( 'bb_db_version', 2078 );
 476  
 477      if ( !defined( 'BB_THEME_DIR' ) ) {
 478          return;
 479      }
 480  
 481      if ( !BB_THEME_DIR ) {
 482          return;
 483      }
 484  
 485      if ( file_exists( BB_THEME_DIR ) ) {
 486          return;
 487      }
 488  
 489      // Just suppress errors as this is not critical
 490      if ( @mkdir( BB_THEME_DIR, 0755 ) ) {
 491          return 'Making theme directory at ' . BB_THEME_DIR . ': ' . __FUNCTION__;
 492      }
 493  
 494      return;
 495  }
 496  
 497  // Subscription Option
 498  function bb_upgrade_1130() {
 499      if ( $dbv = bb_get_option_from_db( 'bb_db_version' ) && $dbv >= 2471 )
 500          return;
 501      
 502      // If the option is already there, then return
 503      if ( bb_get_option( 'enable_subscriptions' ) )
 504          return;
 505      
 506      bb_update_option( 'enable_subscriptions', 1 );
 507      
 508      bb_update_option( 'bb_db_version', 2471 );
 509      
 510      return 'Added subscriptions option and set its value to true: ' . __FUNCTION__;
 511  }
 512  
 513  function bb_deslash($content) {
 514      // Note: \\\ inside a regex denotes a single backslash.
 515  
 516      // Replace one or more backslashes followed by a single quote with
 517      // a single quote.
 518      $content = preg_replace("/\\\+'/", "'", $content);
 519  
 520      // Replace one or more backslashes followed by a double quote with
 521      // a double quote.
 522      $content = preg_replace('/\\\+"/', '"', $content);
 523  
 524      // Replace one or more backslashes with one backslash.
 525      $content = preg_replace("/\\\+/", "\\", $content);
 526  
 527      return $content;
 528  }
 529  
 530  function bb_update_db_version() {
 531      bb_update_option( 'bb_db_version', bb_get_option( 'bb_db_version' ) );
 532  }
 533  ?>


Generated: Thu Dec 7 01:01:35 2017 Cross-referenced by PHPXref 0.7.1