/**
     * Assign new random question for current IP address
     *
     * @return object Question row from DB table "questions"
     */
    function CaptchaQuestionNew()
    {
        global $DB, $Session;
        $IP = ip2int($_SERVER['REMOTE_ADDR']);
        // Get new random question from DB
        $SQL = new SQL();
        $SQL->SELECT('*');
        $SQL->FROM($this->get_sql_table('questions'));
        $SQL->ORDER_BY('RAND()');
        $SQL->LIMIT(1);
        $question = $DB->get_row($SQL->get());
        // Insert a record for current IP address with assigned question ID
        $DB->query('INSERT INTO ' . $this->get_sql_table('ip_question') . '
			( cptip_IP, cptip_cptq_ID ) VALUES
			( ' . $DB->quote($IP) . ', ' . $DB->quote($question->cptq_ID) . ' )');
        // Save the assigned question ID in the session
        $Session->set('captcha_qstn_' . $this->ID . '_ID', $question->cptq_ID);
        $Session->dbsave();
        $this->question_ID = $question->cptq_ID;
        return $question;
    }
Esempio n. 2
0
 /**
  * Run Query: GET DATA ROWS *** HEAVY ***
  */
 function query()
 {
     global $DB, $Session, $localtimenow;
     if (!is_null($this->rows)) {
         // Query has already executed:
         return;
     }
     // INIT THE QUERY:
     $this->query_init();
     // We are going to proceed in two steps (we simulate a subquery)
     // 1) we get the IDs we need
     // 2) we get all the other fields matching these IDs
     // This is more efficient than manipulating all fields at once.
     // *** STEP 1 ***
     $user_IDs = isset($this->filters['users']) ? $this->filters['users'] : array();
     if ($this->refresh_query || $localtimenow - $Session->get($this->filterset_name . '_refresh_time') > 7200) {
         // We should create new list of user IDs
         global $Timer;
         $Timer->start('Users_IDs', false);
         $step1_SQL = new SQL();
         $step1_SQL->SELECT('T_users.user_ID, IF( user_avatar_file_ID IS NOT NULL, 1, 0 ) as has_picture, COUNT( DISTINCT blog_ID ) AS nb_blogs');
         if (!empty($this->filters['reported']) && $this->filters['reported']) {
             // Filter is set to 'Reported users'
             $step1_SQL->SELECT_add(', COUNT( DISTINCT urep_reporter_ID ) AS user_rep');
         }
         $step1_SQL->FROM($this->UserQuery->get_from(''));
         $step1_SQL->WHERE($this->UserQuery->get_where(''));
         $step1_SQL->GROUP_BY($this->UserQuery->get_group_by(''));
         $step1_SQL->ORDER_BY($this->UserQuery->get_order_by(''));
         $step1_SQL->LIMIT(0);
         // Get list of the IDs we need:
         $user_IDs = $DB->get_col($step1_SQL->get(), 0, 'UserList::Query() Step 1: Get ID list');
         // Update filter with user IDs
         $this->filters['users'] = $user_IDs;
         $this->save_filterset();
         $Timer->stop('Users_IDs');
     }
     // GET TOTAL ROW COUNT:
     parent::count_total_rows(count($user_IDs));
     // Pagination, Get user IDs from array for current page
     $user_IDs_paged = array_slice($user_IDs, ($this->page - 1) * $this->limit, $this->limit);
     // *** STEP 2 ***
     $step2_SQL = $this->UserQuery;
     if (!empty($user_IDs_paged)) {
         // Init sql query to get users by IDs
         $step2_SQL->WHERE($this->Cache->dbIDname . ' IN (' . implode(',', $user_IDs_paged) . ') ');
         $step2_SQL->ORDER_BY('FIND_IN_SET( user_ID, "' . implode(',', $user_IDs_paged) . '" )');
     } else {
         // No users
         $step2_SQL->WHERE('user_ID IS NULL');
     }
     $this->sql = $step2_SQL->get();
     // ATTENTION: we skip the parent on purpose here!! fp> refactor
     DataObjectList2::query(false, false, false, 'UserList::Query() Step 2');
 }
Esempio n. 3
0
 /**
  * Get messaging possibilities between current user and $this user
  *
  * @param object Current User (the one trying to send the PM)
  * @param string Type of contact method to check first: 'PM' > 'email'  
  * @return NULL|string allowed messaging possibility: PM > email > login > NULL
  */
 function get_msgform_possibility($current_User = NULL, $check_level = 'PM')
 {
     global $DB;
     $check_owner_SQL = new SQL();
     $check_owner_SQL->SELECT('blog_ID');
     $check_owner_SQL->FROM('T_blogs');
     $check_owner_SQL->WHERE('blog_owner_user_ID = ' . $DB->quote($this->ID));
     $check_owner_SQL->LIMIT('1');
     if ($DB->get_var($check_owner_SQL->get())) {
         // Always allow to contact this user because he is owner of at least one collection:
         $is_collection_owner = true;
     } else {
         $is_collection_owner = false;
     }
     if (!$is_collection_owner && !$this->check_status('can_receive_any_message')) {
         // In case of a closed account:
         return NULL;
     }
     if (is_logged_in()) {
         // current User is a registered user
         if ($current_User == NULL) {
             global $current_User;
         }
         if (!$is_collection_owner && has_cross_country_restriction('contact') && (empty($current_User->ctry_ID) || $current_User->ctry_ID !== $this->ctry_ID)) {
             // Contat to this user is not enabled
             return NULL;
         }
         if ($check_level == 'PM' && $this->accepts_pm() && $current_User->accepts_pm() && $this->ID != $current_User->ID) {
             // both user has permission to send or receive private message and not the same user
             // check if current_User is allowed to create a new conversation with this user.
             $blocked_contact = check_blocked_contacts(array($this->ID));
             if (empty($blocked_contact) && !$current_User->must_accept_terms()) {
                 // user is allowed to send pm to this user, and he didn't reached his new thread limit yet
                 return 'PM';
             }
         }
         if ($is_collection_owner || $this->accepts_email()) {
             // This User allows email => send email OR Force to allow to contact with this user because he is owner of the selected collection:
             return 'email';
         }
     } else {
         // current User is not logged in
         if ($is_collection_owner || $this->accepts_email()) {
             // This User allows email => send email OR Force to allow to contact with this user because he is owner of the selected collection:
             return 'email';
         }
         if ($this->accepts_pm()) {
             // no email option - try to log in and send private message (only registered users can send PM)
             return 'login';
         }
     }
     // no messaging option between current_User and this user
     return NULL;
 }
Esempio n. 4
0
             $group_perms_SQL->SELECT('user_login');
             $group_perms_SQL->FROM('T_users');
             $group_perms_SQL->FROM_add('INNER JOIN T_coll_group_perms ON user_grp_ID = bloggroup_group_ID');
             $group_perms_SQL->WHERE('user_login LIKE "' . $DB->escape($text) . '%"');
             $group_perms_SQL->WHERE_and('bloggroup_blog_ID = ' . $DB->quote($blog_ID));
             $group_perms_SQL->WHERE_and('bloggroup_can_be_assignee <> 0');
             // Union two sql queries to execute one query and save an order as one list
             $users_sql = '( ' . $user_perms_SQL->get() . ' )' . ' UNION ' . '( ' . $group_perms_SQL->get() . ' )' . ' ORDER BY user_login' . ' LIMIT 10';
             break;
         default:
             // Get all users:
             $SQL = new SQL();
             $SQL->SELECT('user_login');
             $SQL->FROM('T_users');
             $SQL->WHERE('user_login LIKE "' . $DB->escape($text) . '%"');
             $SQL->LIMIT('10');
             $SQL->ORDER_BY('user_login');
             $users_sql = $SQL->get();
             break;
     }
     $user_logins = $DB->get_col($users_sql);
     if ($data_type == 'json') {
         // Return data in JSON format
         echo evo_json_encode($user_logins);
         exit(0);
         // Exit here to don't break JSON data by following debug data
     } else {
         // Return data as multilines
         echo implode("\n", $user_logins);
     }
 }
    /**
     * Display the widget!
     *
     * @param array MUST contain at least the basic display params
     */
    function display($params)
    {
        $this->init_display($params);
        $UserCache =& get_UserCache();
        $UserList = new DataObjectList2($UserCache);
        switch ($this->disp_params['order_by']) {
            case 'regdate':
                $sql_order = 'user_created_datetime DESC';
                break;
            case 'moddate':
                $sql_order = 'user_profileupdate_date DESC';
                break;
            case 'random':
            default:
                $sql_order = 'RAND()';
                break;
        }
        // Query list of users with picture and not closed:
        $SQL = new SQL();
        $SQL->SELECT('*');
        $SQL->FROM('T_users');
        $SQL->WHERE('user_avatar_file_ID IS NOT NULL');
        $SQL->WHERE_and('user_status <> "closed"');
        if (is_logged_in()) {
            // Add filters
            global $current_User, $DB;
            switch ($this->disp_params['gender']) {
                // Filter by gender
                case 'same':
                    $SQL->WHERE_and('user_gender = "' . $current_User->gender . '"');
                    break;
                case 'opposite':
                    $SQL->WHERE_and('user_gender != "' . $current_User->gender . '"');
                    break;
            }
            switch ($this->disp_params['location']) {
                // Filter by location
                case 'city':
                    $SQL->WHERE_and('user_city_ID ' . (empty($current_User->city_ID) ? 'IS NULL' : '= "' . $current_User->city_ID . '"'));
                case 'subregion':
                    $SQL->WHERE_and('user_subrg_ID ' . (empty($current_User->subrg_ID) ? 'IS NULL' : '= "' . $current_User->subrg_ID . '"'));
                case 'region':
                    $SQL->WHERE_and('user_rgn_ID ' . (empty($current_User->rgn_ID) ? 'IS NULL' : '= "' . $current_User->rgn_ID . '"'));
                case 'country':
                    $SQL->WHERE_and('user_ctry_ID ' . (empty($current_User->ctry_ID) ? 'IS NULL' : '= "' . $current_User->ctry_ID . '"'));
                    break;
                case 'closest':
                    if (!empty($current_User->city_ID)) {
                        // Check if users exist with same city
                        $user_exists = $DB->get_var('SELECT user_ID
							 FROM T_users
							WHERE user_city_ID ="' . $current_User->city_ID . '"
							  AND user_ID != "' . $current_User->ID . '"
							LIMIT 1');
                        if (!empty($user_exists)) {
                            $SQL->WHERE_and('user_city_ID = "' . $current_User->city_ID . '"');
                            $SQL->WHERE_and('user_subrg_ID = "' . $current_User->subrg_ID . '"');
                            $SQL->WHERE_and('user_rgn_ID = "' . $current_User->rgn_ID . '"');
                            $SQL->WHERE_and('user_ctry_ID = "' . $current_User->ctry_ID . '"');
                            break;
                        }
                    }
                    if (!empty($current_User->subrg_ID) && empty($user_exists)) {
                        // Check if users exist with same sub-region
                        $user_exists = $DB->get_var('SELECT user_ID
							 FROM T_users
							WHERE user_subrg_ID ="' . $current_User->subrg_ID . '"
							  AND user_ID != "' . $current_User->ID . '"
							LIMIT 1');
                        if (!empty($user_exists)) {
                            $SQL->WHERE_and('user_subrg_ID = "' . $current_User->subrg_ID . '"');
                            $SQL->WHERE_and('user_rgn_ID = "' . $current_User->rgn_ID . '"');
                            $SQL->WHERE_and('user_ctry_ID = "' . $current_User->ctry_ID . '"');
                            break;
                        }
                    }
                    if (!empty($current_User->rgn_ID) && empty($user_exists)) {
                        // Check if users exist with same region
                        $user_exists = $DB->get_var('SELECT user_ID
							 FROM T_users
							WHERE user_rgn_ID ="' . $current_User->rgn_ID . '"
							  AND user_ID != "' . $current_User->ID . '"
							LIMIT 1');
                        if (!empty($user_exists)) {
                            $SQL->WHERE_and('user_rgn_ID = "' . $current_User->rgn_ID . '"');
                            $SQL->WHERE_and('user_ctry_ID = "' . $current_User->ctry_ID . '"');
                            break;
                        }
                    }
                    if (!empty($current_User->ctry_ID) && empty($user_exists)) {
                        // Check if users exist with same country
                        $user_exists = $DB->get_var('SELECT user_ID
							 FROM T_users
							WHERE user_ctry_ID ="' . $current_User->ctry_ID . '"
							  AND user_ID != "' . $current_User->ID . '"
							LIMIT 1');
                        if (!empty($user_exists)) {
                            $SQL->WHERE_and('user_ctry_ID = "' . $current_User->ctry_ID . '"');
                        }
                    }
                    break;
            }
        }
        $SQL->ORDER_BY($sql_order);
        $SQL->LIMIT(intval($this->disp_params['limit']));
        $UserList->sql = $SQL->get();
        $UserList->query(false, false, false, 'User avatars widget');
        $avatar_link_attrs = '';
        if ($this->disp_params['style'] == 'badges') {
            // Remove borders of <td> elements
            $this->disp_params['grid_cellstart'] = str_replace('>', ' style="border:none">', $this->disp_params['grid_cellstart']);
            $avatar_link_attrs = ' class="avatar_rounded"';
        }
        $layout = $this->disp_params['thumb_layout'];
        $nb_cols = intval($this->disp_params['grid_nb_cols']);
        $count = 0;
        $r = '';
        /**
         * @var User
         */
        while ($User =& $UserList->get_next()) {
            if ($layout == 'grid') {
                // Grid layout
                if ($count % $nb_cols == 0) {
                    $r .= $this->disp_params['grid_colstart'];
                }
                $r .= $this->disp_params['grid_cellstart'];
            } elseif ($layout == 'flow') {
                // Flow block layout
                $r .= $this->disp_params['flow_block_start'];
            } else {
                // List layout
                $r .= $this->disp_params['item_start'];
            }
            $identity_url = get_user_identity_url($User->ID);
            $avatar_tag = $User->get_avatar_imgtag($this->disp_params['thumb_size']);
            if ($this->disp_params['bubbletip'] == '1') {
                // Bubbletip is enabled
                $bubbletip_param = ' rel="bubbletip_user_' . $User->ID . '"';
                $avatar_tag = str_replace('<img ', '<img ' . $bubbletip_param . ' ', $avatar_tag);
            }
            if (!empty($identity_url)) {
                $r .= '<a href="' . $identity_url . '"' . $avatar_link_attrs . '>';
                $r .= $avatar_tag;
                if ($this->disp_params['style'] == 'badges') {
                    // Add user login after picture
                    $r .= '<br >' . $User->get_colored_login();
                }
                $r .= '</a>';
            } else {
                $r .= $avatar_tag;
            }
            ++$count;
            if ($layout == 'grid') {
                // Grid layout
                $r .= $this->disp_params['grid_cellend'];
                if ($count % $nb_cols == 0) {
                    $r .= $this->disp_params['grid_colend'];
                }
            } elseif ($layout == 'flow') {
                // Flow block layout
                $r .= $this->disp_params['flow_block_end'];
            } else {
                // List layout
                $r .= $this->disp_params['item_end'];
            }
        }
        // Exit if no files found
        if (empty($r)) {
            return;
        }
        echo $this->disp_params['block_start'];
        // Display title if requested
        $this->disp_title();
        echo $this->disp_params['block_body_start'];
        if ($layout == 'grid') {
            echo $this->disp_params['grid_start'];
        } elseif ($layout == 'flow') {
            // Flow block layout
            echo $this->disp_params['flow_start'];
        } else {
            echo $this->disp_params['list_start'];
        }
        echo $r;
        if ($layout == 'grid') {
            if ($count && $count % $nb_cols != 0) {
                echo $this->disp_params['grid_colend'];
            }
            echo $this->disp_params['grid_end'];
        } elseif ($layout == 'flow') {
            // Flow block layout
            echo $this->disp_params['flow_end'];
        } else {
            echo $this->disp_params['list_end'];
        }
        echo $this->disp_params['block_body_end'];
        echo $this->disp_params['block_end'];
        return true;
    }
    /**
     * Display the widget!
     *
     * @param array MUST contain at least the basic display params
     */
    function display($params)
    {
        global $localtimenow;
        $this->init_display($params);
        if ($this->disp_params['order_by'] == 'RAND' && isset($this->BlockCache)) {
            // Do NOT cache if display order is random
            $this->BlockCache->abort_collect();
        }
        global $Blog;
        $list_blogs = $this->disp_params['blog_ID'] ? $this->disp_params['blog_ID'] : $Blog->ID;
        //pre_dump( $list_blogs );
        // Display photos:
        // TODO: permissions, complete statuses...
        // TODO: A FileList object based on ItemListLight but adding File data into the query?
        //          overriding ItemListLigth::query() for starters ;)
        $FileCache =& get_FileCache();
        $FileList = new DataObjectList2($FileCache);
        // Query list of files:
        $SQL = new SQL();
        $SQL->SELECT('post_ID, post_datestart, post_datemodified, post_main_cat_ID, post_urltitle, post_canonical_slug_ID,
									post_tiny_slug_ID, post_ptyp_ID, post_title, post_excerpt, post_url, file_ID,
									file_title, file_root_type, file_root_ID, file_path, file_alt, file_desc');
        $SQL->FROM('T_categories INNER JOIN T_postcats ON cat_ID = postcat_cat_ID
									INNER JOIN T_items__item ON postcat_post_ID = post_ID
									INNER JOIN T_links ON post_ID = link_itm_ID
									INNER JOIN T_files ON link_file_ID = file_ID');
        $SQL->WHERE('cat_blog_ID IN (' . $list_blogs . ')');
        // fp> TODO: want to restrict on images :]
        $SQL->WHERE_and('post_status = "published"');
        // TODO: this is a dirty hack. More should be shown.
        $SQL->WHERE_and('post_datestart <= \'' . remove_seconds($localtimenow) . '\'');
        if (!empty($this->disp_params['item_type'])) {
            // Get items only with specified type
            $SQL->WHERE_and('post_ptyp_ID = ' . intval($this->disp_params['item_type']));
        }
        $SQL->GROUP_BY('link_ID');
        $SQL->LIMIT($this->disp_params['limit'] * 4);
        // fp> TODO: because we have no way of getting images only, we get 4 times more data than requested and hope that 25% at least will be images :/
        $SQL->ORDER_BY(gen_order_clause($this->disp_params['order_by'], $this->disp_params['order_dir'], 'post_', 'post_ID ' . $this->disp_params['order_dir'] . ', link_ID'));
        $FileList->sql = $SQL->get();
        $FileList->query(false, false, false, 'Media index widget');
        $layout = $this->disp_params['thumb_layout'];
        $nb_cols = $this->disp_params['grid_nb_cols'];
        $count = 0;
        $r = '';
        /**
         * @var File
         */
        while ($File =& $FileList->get_next()) {
            if ($count >= $this->disp_params['limit']) {
                // We have enough images already!
                break;
            }
            if (!$File->is_image()) {
                // Skip anything that is not an image
                // fp> TODO: maybe this property should be stored in link_ltype_ID or in the files table
                continue;
            }
            if ($layout == 'grid') {
                if ($count % $nb_cols == 0) {
                    $r .= $this->disp_params['grid_colstart'];
                }
                $r .= $this->disp_params['grid_cellstart'];
            } else {
                $r .= $this->disp_params['item_start'];
            }
            // 1/ Hack a dirty permalink( will redirect to canonical):
            // $link = url_add_param( $Blog->get('url'), 'p='.$post_ID );
            // 2/ Hack a link to the right "page". Very daring!!
            // $link = url_add_param( $Blog->get('url'), 'paged='.$count );
            // 3/ Instantiate a light object in order to get permamnent url:
            $ItemLight = new ItemLight($FileList->get_row_by_idx($FileList->current_idx - 1));
            // index had already been incremented
            $r .= '<a href="' . $ItemLight->get_permanent_url() . '">';
            // Generate the IMG THUMBNAIL tag with all the alt, title and desc if available
            $r .= $File->get_thumb_imgtag($this->disp_params['thumb_size'], '', '', $ItemLight->title);
            $r .= '</a>';
            if ($this->disp_params['disp_image_title']) {
                $title = $File->get('title') ? $this->get('title') : $ItemLight->title;
                $r .= '<span class="note">' . $title . '</span>';
            }
            ++$count;
            if ($layout == 'grid') {
                $r .= $this->disp_params['grid_cellend'];
                if ($count % $nb_cols == 0) {
                    $r .= $this->disp_params['grid_colend'];
                }
            } else {
                $r .= $this->disp_params['item_end'];
            }
        }
        // Exit if no files found
        if (empty($r)) {
            return;
        }
        echo $this->disp_params['block_start'];
        // Display title if requested
        $this->disp_title();
        if ($layout == 'grid') {
            echo $this->disp_params['grid_start'];
        } else {
            echo $this->disp_params['list_start'];
        }
        echo $r;
        if ($layout == 'grid') {
            if ($count && $count % $nb_cols != 0) {
                echo $this->disp_params['grid_colend'];
            }
            echo $this->disp_params['grid_end'];
        } else {
            echo $this->disp_params['list_end'];
        }
        echo $this->disp_params['block_end'];
        return true;
    }
Esempio n. 7
0
/**
 * Create links between users and image files from the users profile_pictures folder
 */
function create_profile_picture_links()
{
    global $DB;
    load_class('files/model/_filelist.class.php', 'Filelist');
    load_class('files/model/_fileroot.class.php', 'FileRoot');
    $path = 'profile_pictures';
    $FileRootCache =& get_FileRootCache();
    $UserCache =& get_UserCache();
    // SQL query to get all users and limit by page below
    $users_SQL = new SQL();
    $users_SQL->SELECT('*');
    $users_SQL->FROM('T_users');
    $users_SQL->ORDER_BY('user_ID');
    $page = 0;
    $page_size = 100;
    while (count($UserCache->cache) > 0 || $page == 0) {
        // Load users by 100 at one time to avoid errors about memory exhausting
        $users_SQL->LIMIT($page * $page_size . ', ' . $page_size);
        $UserCache->clear();
        $UserCache->load_by_sql($users_SQL);
        while (($iterator_User =& $UserCache->get_next()) != NULL) {
            // Iterate through UserCache)
            $FileRootCache->clear();
            $user_FileRoot =& $FileRootCache->get_by_type_and_ID('user', $iterator_User->ID);
            if (!$user_FileRoot) {
                // User FileRoot doesn't exist
                continue;
            }
            $ads_list_path = get_canonical_path($user_FileRoot->ads_path . $path);
            // Previously uploaded avatars
            if (!is_dir($ads_list_path)) {
                // profile_picture folder doesn't exists in the user root dir
                continue;
            }
            $user_avatar_Filelist = new Filelist($user_FileRoot, $ads_list_path);
            $user_avatar_Filelist->load();
            if ($user_avatar_Filelist->count() > 0) {
                // profile_pictures folder is not empty
                $info_content = '';
                $LinkOwner = new LinkUser($iterator_User);
                while ($lFile =& $user_avatar_Filelist->get_next()) {
                    // Loop through all Files:
                    $fileName = $lFile->get_name();
                    if (process_filename($fileName)) {
                        // The file has invalid file name, don't create in the database
                        // TODO: asimo> we should collect each invalid file name here, and send an email to the admin
                        continue;
                    }
                    $lFile->load_meta(true);
                    if ($lFile->is_image()) {
                        $lFile->link_to_Object($LinkOwner);
                    }
                }
            }
        }
        // Increase page number to get next portion of users
        $page++;
    }
    // Clear cache data
    $UserCache->clear();
    $FileRootCache->clear();
}
Esempio n. 8
0
/**
 * Create sample comments and display a process of creating
 *
 * @param integer Blog ID
 * @param integer Number of comments
 * @param integer Number of posts
 */
function tool_create_sample_comments($blog_ID, $num_comments, $num_posts)
{
    global $DB, $posttypes_specialtypes, $localtimenow, $Hit, $Messages, $Debuglog;
    $BlogCache =& get_BlogCache();
    $selected_Blog = $BlogCache->get_by_ID($blog_ID, false, false);
    if ($selected_Blog == NULL) {
        // Incorrect blog ID, Exit here
        return;
    }
    echo T_('Creating of the sample comments...');
    evo_flush();
    /**
     * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
     */
    $DB->log_queries = false;
    $curr_orderby = $selected_Blog->get_setting('orderby');
    if ($curr_orderby == 'RAND') {
        $curr_orderby .= '()';
    } else {
        $curr_orderby = 'post_' . $curr_orderby;
    }
    $curr_orderdir = $selected_Blog->get_setting('orderdir');
    // find the $num_posts latest posts in blog
    $SQL = new SQL();
    $SQL->SELECT('post_ID');
    $SQL->FROM('T_items__item');
    $SQL->FROM_add('INNER JOIN T_categories ON post_main_cat_ID = cat_ID');
    $SQL->WHERE('cat_blog_ID = ' . $DB->quote($blog_ID));
    $SQL->WHERE_and('post_status = ' . $DB->quote('published'));
    // Set condition to not create sample comments for special posts
    $SQL->WHERE_and('post_ptyp_ID NOT IN ( ' . $DB->quote($posttypes_specialtypes) . ' )');
    $SQL->ORDER_BY($curr_orderby . ' ' . $curr_orderdir . ', post_ID ' . $curr_orderdir);
    $SQL->LIMIT($num_posts);
    $items_result = $DB->get_results($SQL->get(), ARRAY_A, 'Find the x latest posts in blog');
    $count = 1;
    $fix_content = 'This is an auto generated comment for testing the moderation features.
					http://www.test.com/test_comment_';
    // go through on selected items
    foreach ($items_result as $row) {
        $item_ID = $row['post_ID'];
        $ItemCache =& get_ItemCache();
        $commented_Item =& $ItemCache->get_by_ID($item_ID);
        // create $num_comments comments for each item
        for ($i = 0; $i < $num_comments; $i++) {
            $author = 'Test ' . $count;
            $email = 'test_' . $count . '@test.com';
            $url = 'http://www.test-' . rand(1, 3) . '.com/test_comment_' . $count;
            $content = $fix_content . $count;
            for ($j = 0; $j < 50; $j++) {
                // create 50 random word
                $length = rand(1, 15);
                $word = generate_random_key($length, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
                $content = $content . ' ' . $word;
            }
            // create and save a new comment
            $Comment = new Comment();
            $Comment->set_Item($commented_Item);
            $Comment->set('status', 'draft');
            $Comment->set('author', $author);
            $Comment->set('author_email', $email);
            $Comment->set('author_url', $url);
            $Comment->set('content', $content);
            $Comment->set('date', date('Y-m-d H:i:s', $localtimenow));
            $Comment->set('author_IP', $Hit->IP);
            $Comment->dbsave();
            $count++;
            if ($count % 100 == 0) {
                // Display a process of creating by one dot for 100 comments
                echo ' .';
                evo_flush();
            }
            // Clear all debug messages, To avoid an error about full memory
            $Debuglog->clear('all');
        }
    }
    echo ' OK.';
    $Messages->add(sprintf(T_('Created %d comments.'), $count - 1), 'success');
}
Esempio n. 9
0
/**
 * Retrieves all tags from published posts
 *
 * @param integer the id of the blog or array of blog ids. Set NULL to use current blog
 * @param integer maximum number of returned tags
 * @param string a comma separated list of tags to ignore/exclude
 * @param bool true to skip tags from pages, intro posts and sidebar stuff
 * @return array of tags
 */
function get_tags($blog_ids, $limit = 0, $filter_list = NULL, $skip_intro_posts = false)
{
    global $DB, $localtimenow, $posttypes_specialtypes;
    $BlogCache =& get_BlogCache();
    if (is_null($blog_ids)) {
        global $blog;
        $blog_ids = $blog;
    }
    if (is_array($blog_ids)) {
        // Get quoted ID list
        $where_cat_clause = 'cat_blog_ID IN ( ' . $DB->quote($blog_ids) . ' )';
    } else {
        // Get list of relevant blogs
        $Blog =& $BlogCache->get_by_ID($blog_ids);
        $where_cat_clause = trim($Blog->get_sql_where_aggregate_coll_IDs('cat_blog_ID'));
    }
    // Build query to get the tags:
    $tags_SQL = new SQL();
    $tags_SQL->SELECT('tag_name, COUNT( DISTINCT itag_itm_ID ) AS tag_count, tag_ID, cat_blog_ID');
    $tags_SQL->FROM('T_items__tag');
    $tags_SQL->FROM_add('INNER JOIN T_items__itemtag ON itag_tag_ID = tag_ID');
    $tags_SQL->FROM_add('INNER JOIN T_items__item ON itag_itm_ID = post_ID');
    $tags_SQL->FROM_add('INNER JOIN T_postcats ON itag_itm_ID = postcat_post_ID');
    $tags_SQL->FROM_add('INNER JOIN T_categories ON postcat_cat_ID = cat_ID');
    $tags_SQL->WHERE($where_cat_clause);
    $tags_SQL->WHERE_and('post_status = "published"');
    $tags_SQL->WHERE_and('post_datestart < ' . $DB->quote(remove_seconds($localtimenow)));
    if ($skip_intro_posts) {
        // Skip "Intro" posts
        $tags_SQL->WHERE_and('post_ityp_ID NOT IN ( ' . implode(', ', $posttypes_specialtypes) . ' )');
    }
    if (!empty($filter_list)) {
        // Filter tags
        $tags_SQL->WHERE_and('tag_name NOT IN ( ' . $DB->quote(explode(', ', $filter_list)) . ' )');
    }
    $tags_SQL->GROUP_BY('tag_name');
    $tags_SQL->ORDER_BY('tag_count DESC');
    if (!empty($limit)) {
        // Limit
        $tags_SQL->LIMIT($limit);
    }
    return $DB->get_results($tags_SQL->get(), OBJECT, 'Get tags');
}
Esempio n. 10
0
/**
 * Find and delete orphan File objects with no matching file on disk
 */
function dbm_delete_orphan_files()
{
    global $DB, $admin_url;
    $FileCache =& get_FileCache();
    $FileCache->clear();
    echo T_('Deleting of the orphan File objects from the database...');
    evo_flush();
    $files_SQL = new SQL();
    $files_SQL->SELECT('*');
    $files_SQL->FROM('T_files');
    $files_SQL->ORDER_BY('file_ID');
    $count_files_valid = 0;
    $count_files_invalid = 0;
    $count_files_deleted = 0;
    $page_size = 100;
    $current_page = 0;
    // Search the files by page to save memory
    $files_SQL->LIMIT('0, ' . $page_size);
    while ($loaded_Files = $FileCache->load_by_sql($files_SQL)) {
        // Check all loaded files
        foreach ($loaded_Files as $File) {
            if (is_null($File)) {
                // The File object couldn't be created because the db entry is invalid
                $count_files_invalid++;
                continue;
            }
            if ($File->exists()) {
                // File exists on the disk
                $count_files_valid++;
            } else {
                // File doesn't exist on the disk, Remove it from DB
                $File->dbdelete();
                $count_files_deleted++;
            }
        }
        echo ' .';
        evo_flush();
        // Clear cache after each page to save memory
        $FileCache->clear();
        $current_page++;
        $files_SQL->LIMIT($current_page * $page_size . ', ' . $page_size);
    }
    echo 'OK<p>';
    echo sprintf(T_('Number of deleted orphan File objects: %d.'), $count_files_deleted) . '<br />';
    echo sprintf(T_('Number of valid File objects in the database: %d.'), $count_files_valid) . '</p>';
    if ($count_files_invalid) {
        // There are invalid files in the database
        // Display warning to show that the 'Remove orphan file roots' tool should be also called
        $remove_orphan_file_roots = 'href="' . $admin_url . 'ctrl=tools&amp;action=delete_orphan_file_roots&amp;' . url_crumb('tools') . '"';
        $invalid_files_note = $count_files_invalid == 1 ? T_('An invalid File object was found in the database.') : sprintf(T_('%d invalid File objects were found in the database.'), $count_files_invalid);
        echo '<p class="warning">' . $invalid_files_note . "<br/>" . sprintf(T_('It is strongly recommended to also execute the &lt;<a %s>Remove orphan file roots</a>&gt; tool to remove invalid files from the database and from the disk as well!'), $remove_orphan_file_roots) . '</p>';
    }
}
Esempio n. 11
0
/**
 * Recreate posts autogenerated excerpts
 * Only those posts excerpt will be recreated which are visible in the front office
 *
 * Note: This process can be very very slow if there are many items in the database
 *
 * @param string the url to call if the process needs to be paused becuase of the max execution time
 * @param boolean set true to start from the beginning, false otherwise
 * @param boolean set to true to display recreated/all information or leave it on false to display only dots
 */
function recreate_autogenerated_excerpts($continue_url, $remove_all = true, $detailed_progress_log = false)
{
    global $DB, $localtimenow;
    $start_time = time();
    $max_exec_time = ini_get('max_execution_time');
    $load_limit = 50;
    $progress_log_id = 'progress_log';
    // The timestamp when the process was started
    $process_start_ts = param('start_ts', 'string', $localtimenow);
    // Update only those posts which may be visible in the front office
    $where_condition = '( post_excerpt_autogenerated = 1 OR post_excerpt_autogenerated IS NULL ) AND post_status IN ( \'' . implode('\',\' ', get_inskin_statuses(NULL, 'post')) . '\' )';
    // Update only those posts which were already created when the recreate process was started
    $where_condition .= ' AND post_datecreated < ' . $DB->quote(date2mysql($process_start_ts));
    if ($remove_all) {
        // We are in the beginning of the process and first we set all autogenerated excerpts values to NULL
        if ($detailed_progress_log) {
            // Display detailed progess information
            echo '<span id="' . $progress_log_id . '">' . T_('Clearing autogenerated excerpt values') . '</span>';
            evo_flush();
        }
        // Set all autogenerated excerpt values to NULL
        $query = 'UPDATE T_items__item SET post_excerpt = NULL WHERE ' . $where_condition;
        $DB->query($query, 'Remove all autogenerated excerpts');
        // Count all autogenerated excerpt which value is NULL ( Note: Maybe some of them was already NULL before we have started this process )
        $all_excerpt = $DB->get_var('SELECT count(*) FROM T_items__item WHERE post_excerpt IS NULL AND ' . $where_condition);
        $recreated_excerpts = 0;
    } else {
        // Init params with a previously started process status
        echo '<span id="progress_log"></span>';
        $all_excerpt = param('all_excerpt', 'integer', 0);
        $recreated_excerpts = param('recreated_excerpts', 'integer', 0);
    }
    // Display the current state of the process or a '.' character to indicate the ongoing process
    if ($detailed_progress_log) {
        echo_progress_log_update($progress_log_id, $recreated_excerpts, $all_excerpt);
    } else {
        echo ' .';
    }
    evo_flush();
    $load_SQL = new SQL();
    $load_SQL->SELECT('*');
    $load_SQL->FROM('T_items__item');
    $load_SQL->WHERE($where_condition . ' AND post_excerpt IS NULL');
    $load_SQL->LIMIT($load_limit);
    $ItemCache =& get_ItemCache();
    while (count($ItemCache->load_by_sql($load_SQL)) > 0) {
        // New portion of items was loaded
        $processed_items = 0;
        while (($iterator_Item =& $ItemCache->get_next()) != NULL) {
            // Create new autogenerated excerpt and save it in the database
            $excerpt = $iterator_Item->get_autogenerated_excerpt();
            // Update excerpt without Item->dbupdate() call to make it faster
            $DB->query('UPDATE T_items__item SET post_excerpt = ' . $DB->quote($excerpt) . ' WHERE post_ID = ' . $DB->quote($iterator_Item->ID));
            $processed_items++;
            if ($detailed_progress_log && $processed_items % 3 == 0) {
                // Update progress info after every 3 recreated excerpt when detailed progress log was requested
                echo_progress_log_update($progress_log_id, $recreated_excerpts + $processed_items, $all_excerpt);
                evo_flush();
            }
        }
        // Increase the number recreated excerpts
        $recreated_excerpts += $processed_items;
        // Clear already process items from the cache
        $ItemCache->clear();
        // Display progress log
        if ($detailed_progress_log) {
            echo_progress_log_update($progress_log_id, $recreated_excerpts, $all_excerpt);
        } else {
            echo ' .';
        }
        evo_flush();
        if ($max_exec_time != 0 && $recreated_excerpts < $all_excerpt) {
            // a max execution time limit is set and there are more excerpts to create
            $elapsed_time = time() - $start_time;
            if ($elapsed_time > $max_exec_time - 10) {
                // Increase the time limit in case if less than 10 seconds remained
                $max_exec_time = $max_exec_time + 100;
                if (!set_max_execution_time($max_exec_time)) {
                    $continue_url = url_add_param($continue_url, 'all_excerpt=' . $all_excerpt . '&amp;recreated_excerpts=' . $recreated_excerpts . '&amp;start_ts=' . $process_start_ts, '&amp;');
                    echo '<br />' . 'We are reaching the time limit for this script. Please click <a href="' . $continue_url . '">continue</a>...';
                    evo_flush();
                    exit(0);
                }
            }
        }
    }
    // Check if the recreated exceprts number match with the total number of autogenerated excerpts
    if ($detailed_progress_log && $recreated_excerpts < $all_excerpt) {
        // This means that we are in the end of the process but some post excerpt was updated outside of this process
        // Here we increase the recreated excerpts value because all excerpts were recreated, however some of them not during this process
        echo_progress_log_update($progress_log_id, $all_excerpt, $all_excerpt);
        if ($all_excerpt == $recreated_excerpts + 1) {
            echo '<br />' . T_('Note: One excerpt was re-created in another simultaneous process!');
        } else {
            echo '<br />' . sprintf(T_('Note: %d excerpts were re-created in another simultaneous process!'), $all_excerpt - $recreated_excerpts);
        }
    }
}
Esempio n. 12
0
 /**
  * Get list of attached Links
  *
  * @param integer Limit max result
  * @param string Restrict to files/images linked to a specific position.
  *               Position can be 'teaser'|'aftermore'|'inline'
  *               Use comma as separator
  * @param string File type: 'image', 'audio', 'other'; NULL - to select all
  * @param array Params
  * @return DataObjectList2 on success or NULL if no linked files found
  */
 function get_attachment_LinkList($limit = 1000, $position = NULL, $file_type = NULL, $params = array())
 {
     if (!isset($GLOBALS['files_Module'])) {
         return NULL;
     }
     $params = array_merge(array('sql_select_add' => '', 'sql_order_by' => 'link_order'), $params);
     global $DB;
     load_class('_core/model/dataobjects/_dataobjectlist2.class.php', 'DataObjectList2');
     $LinkCache =& get_LinkCache();
     $LinkList = new DataObjectList2($LinkCache);
     // IN FUNC
     $SQL = new SQL();
     $SQL->SELECT('l.*');
     $SQL->SELECT_add($params['sql_select_add']);
     $SQL->FROM('T_links AS l');
     $SQL->WHERE($this->get_where_condition());
     if (!empty($position)) {
         $position = explode(',', $position);
         $SQL->WHERE_and('link_position IN ( ' . $DB->quote($position) . ' )');
     }
     $SQL->ORDER_BY($params['sql_order_by']);
     $SQL->LIMIT($limit);
     if (!is_null($file_type)) {
         // Restrict the Links by File type
         $SQL->FROM_add('INNER JOIN T_files ON link_file_ID = file_ID');
         $SQL->WHERE_and('file_type = ' . $DB->quote($file_type) . ' OR file_type IS NULL');
     }
     $LinkList->sql = $SQL->get();
     $LinkList->query(false, false, false, 'get_attachment_LinkList');
     if ($LinkList->result_num_rows == 0) {
         // Nothing found
         $LinkList = NULL;
     }
     return $LinkList;
 }
Esempio n. 13
0
 /**
  * Display the widget!
  *
  * @param array MUST contain at least the basic display params
  */
 function display($params)
 {
     $this->init_display($params);
     $UserCache =& get_UserCache();
     $UserList = new DataObjectList2($UserCache);
     switch ($this->disp_params['order_by']) {
         case 'regdate':
             $sql_order = 'user_created_datetime DESC';
             break;
         case 'moddate':
             $sql_order = 'user_profileupdate_date DESC';
             break;
         case 'random':
         default:
             $sql_order = 'RAND()';
             break;
     }
     // Query list of files:
     $SQL = new SQL();
     $SQL->SELECT('*');
     $SQL->FROM('T_users');
     $SQL->WHERE('user_avatar_file_ID IS NOT NULL');
     $SQL->ORDER_BY($sql_order);
     $SQL->LIMIT($this->disp_params['limit']);
     $UserList->sql = $SQL->get();
     $UserList->query(false, false, false, 'User avatars widget');
     $layout = $this->disp_params['thumb_layout'];
     $nb_cols = $this->disp_params['grid_nb_cols'];
     $count = 0;
     $r = '';
     /**
      * @var User
      */
     while ($User =& $UserList->get_next()) {
         if ($layout == 'grid') {
             if ($count % $nb_cols == 0) {
                 $r .= $this->disp_params['grid_colstart'];
             }
             $r .= $this->disp_params['grid_cellstart'];
         } else {
             $r .= $this->disp_params['item_start'];
         }
         $identity_url = get_user_identity_url($User->ID);
         $avatar_tag = $User->get_avatar_imgtag($this->disp_params['thumb_size']);
         if ($this->disp_params['bubbletip'] == '1') {
             // Bubbletip is enabled
             $bubbletip_param = ' rel="bubbletip_user_' . $User->ID . '"';
             $avatar_tag = str_replace('<img ', '<img ' . $bubbletip_param . ' ', $avatar_tag);
         }
         if (!empty($identity_url)) {
             $r .= '<a href="' . $identity_url . '">' . $avatar_tag . '</a>';
         } else {
             $r .= $avatar_tag;
         }
         ++$count;
         if ($layout == 'grid') {
             $r .= $this->disp_params['grid_cellend'];
             if ($count % $nb_cols == 0) {
                 $r .= $this->disp_params['grid_colend'];
             }
         } else {
             $r .= $this->disp_params['item_end'];
         }
     }
     // Exit if no files found
     if (empty($r)) {
         return;
     }
     echo $this->disp_params['block_start'];
     // Display title if requested
     $this->disp_title();
     if ($layout == 'grid') {
         echo $this->disp_params['grid_start'];
     } else {
         echo $this->disp_params['list_start'];
     }
     echo $r;
     if ($layout == 'grid') {
         if ($count && $count % $nb_cols != 0) {
             echo $this->disp_params['grid_colend'];
         }
         echo $this->disp_params['grid_end'];
     } else {
         echo $this->disp_params['list_end'];
     }
     echo $this->disp_params['block_end'];
     return true;
 }
Esempio n. 14
0
 /**
  * Get list of attached files
  * 
  * INNER JOIN on files ensures we only get back file links
  * 
  * @param integer Limit max result
  * @param string Restrict to files/images linked to a specific position.
  *               Position can be 'teaser'|'aftermore'|'inline'
  *               Use comma as separator
  * @param string order by
  * @return DataObjectList2 on success or NULL if no linked files found
  */
 function get_attachment_FileList($limit = 1000, $position = NULL, $order = 'link_ID')
 {
     if (!isset($GLOBALS['files_Module'])) {
         return NULL;
     }
     load_class('_core/model/dataobjects/_dataobjectlist2.class.php', 'DataObjectList2');
     $FileCache =& get_FileCache();
     $FileList = new DataObjectList2($FileCache);
     // IN FUNC
     $SQL = new SQL();
     $SQL->SELECT('file_ID, file_title, file_root_type, file_root_ID, file_path, file_alt, file_desc, link_ID');
     $SQL->FROM('T_links INNER JOIN T_files ON link_file_ID = file_ID');
     $SQL->WHERE($this->get_where_condition());
     if (!empty($position)) {
         global $DB;
         $position = explode(',', $position);
         $SQL->WHERE_and('link_position IN ( ' . $DB->quote($position) . ' )');
     }
     //$SQL->ORDER_BY( $order );
     $SQL->ORDER_BY('link_order');
     $SQL->LIMIT($limit);
     $FileList->sql = $SQL->get();
     $FileList->query(false, false, false, 'get_attachment_FileList');
     if ($FileList->result_num_rows == 0) {
         // Nothing found
         $FileList = NULL;
     }
     return $FileList;
 }
Esempio n. 15
0
/**
 * Find and delete orphan File objects with no matching file on disk
 */
function dbm_delete_orphan_files()
{
    global $DB;
    $FileCache =& get_FileCache();
    echo T_('Deleting of the orphan File objects from the database...');
    evo_flush();
    $files_SQL = new SQL();
    $files_SQL->SELECT('file_ID');
    $files_SQL->FROM('T_files');
    $files_SQL->ORDER_BY('file_ID');
    $count_files_valid = 0;
    $count_files_deleted = 0;
    $page_size = 100;
    $current_page = 0;
    while (1) {
        // Search the files by page to save memory
        $files_SQL->LIMIT($current_page * $page_size . ', ' . $page_size);
        $files = $DB->get_col($files_SQL->get());
        if (empty($files)) {
            // All files were verified, Stop here
            break;
        }
        foreach ($files as $file_ID) {
            $File = $FileCache->get_by_ID($file_ID, false, false);
            if ($File->exists()) {
                // File exists on the disk
                $count_files_valid++;
            } else {
                // File doesn't exist on the disk, Remove it from DB
                $File->dbdelete();
                $count_files_deleted++;
            }
        }
        echo ' .';
        evo_flush();
        // Clear cache after each page to save memory
        $FileCache->clear();
        $current_page++;
    }
    echo 'OK<br /><br />';
    echo sprintf(T_('%d File objects have been deleted.'), $count_files_deleted) . '<br />';
    echo sprintf(T_('%d File objects are valid entries.'), $count_files_valid);
}
/**
 * upgrade_b2evo_tables(-)
 *
 * @param string the action param value corresponding the current upgrade process ( evoupgrade, svn_upgrade, auto_upgrade )
 */
function upgrade_b2evo_tables($upgrade_action = 'evoupgrade')
{
    global $db_config, $tableprefix;
    global $baseurl, $old_db_version, $new_db_version;
    global $Group_Admins, $Group_Privileged, $Group_Bloggers, $Group_Users;
    global $locales, $locale;
    global $DB;
    global $admin_url;
    global $Settings, $Plugins;
    // used for defaults, when upgrading to 1.6
    global $use_fileupload, $fileupload_allowedtypes, $fileupload_maxk, $doubleCheckReferers;
    // new DB-delta functionality
    global $schema_queries, $inc_path;
    // used to check script time before starting to create db delta
    global $script_start_time;
    // Create an option which can be turned on if we need to regenerate the autogenerated excerpts in the end of the upgrade script
    global $recreate_autogenerated_excerpts;
    $recreate_autogenerated_excerpts = param('recreate_excerpts', 'boolean', 0);
    // Load DB schema from modules
    load_db_schema();
    // Update the progress bar status
    update_install_progress_bar();
    load_funcs('_core/model/db/_upgrade.funcs.php');
    // Force MySQL strict mode:
    $DB->query('SET sql_mode = ""', 'REMOVE MySQL "strict" mode in order not to worry about missing defaults until the end of the upgrade.');
    echo '<p>' . T_('Checking DB schema version...') . ' ';
    $old_db_version = get_db_version();
    if (empty($old_db_version)) {
        echo '<p><strong>OOPS! b2evolution doesn\'t seem to be installed yet.</strong></p>';
        return false;
    }
    echo $old_db_version, ' : ';
    if ($old_db_version < 8000) {
        debug_die(T_('This version is too old!'));
    }
    if ($old_db_version > $new_db_version) {
        debug_die(T_('This version is too recent! We cannot downgrade to the version you are trying to install...'));
    }
    echo "OK.<br />\n";
    if ($old_db_version < 8010) {
        echo 'Upgrading users table... ';
        $query = "ALTER TABLE T_users\n\t\t\t\t\t\t\tMODIFY COLUMN user_pass CHAR(32) NOT NULL";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading blogs table... ';
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tMODIFY COLUMN blog_lang VARCHAR(20) NOT NULL DEFAULT 'en_US',\n\t\t\t\t\t\t\tMODIFY COLUMN blog_longdesc TEXT NULL DEFAULT NULL";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading categories table... ';
        $query = "ALTER TABLE T_categories\n\t\t\t\t\t\t\tADD COLUMN cat_description VARCHAR(250) NULL DEFAULT NULL,\n\t\t\t\t\t\t\tADD COLUMN cat_longdesc TEXT NULL DEFAULT NULL,\n\t\t\t\t\t\t\tADD COLUMN cat_icon VARCHAR(30) NULL DEFAULT NULL";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading posts table... ';
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tMODIFY COLUMN post_lang VARCHAR(20) NOT NULL DEFAULT 'en_US',\n\t\t\t\t\t\t\tADD COLUMN post_urltitle VARCHAR(50) NULL DEFAULT NULL AFTER post_title,\n\t\t\t\t\t\t\tADD COLUMN post_url VARCHAR(250) NULL DEFAULT NULL AFTER post_urltitle,\n\t\t\t\t\t\t\tADD COLUMN post_comments ENUM('disabled', 'open', 'closed') NOT NULL DEFAULT 'open' AFTER post_wordcount";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Generating wordcounts... ';
        load_funcs('items/model/_item.funcs.php');
        $query = "SELECT ID, post_content FROM {$tableprefix}posts WHERE post_wordcount IS NULL";
        $i = 0;
        foreach ($DB->get_results($query, ARRAY_A) as $row) {
            $query_update_wordcount = "UPDATE {$tableprefix}posts\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSET post_wordcount = " . bpost_count_words($row['post_content']) . "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE ID = " . $row['ID'];
            $DB->query($query_update_wordcount);
            $i++;
        }
        echo "OK. ({$i} rows updated)<br />\n";
        set_upgrade_checkpoint('8010');
    }
    if ($old_db_version < 8020) {
        echo 'Encoding passwords... ';
        $query = "UPDATE T_users\n\t\t\t\t\t\t\tSET user_pass = MD5(user_pass)";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8020');
    }
    if ($old_db_version < 8030) {
        echo 'Deleting unecessary logs... ';
        $query = "DELETE FROM T_hitlog\n\t\t\t\t\t\t\tWHERE hit_ignore = 'badchar'";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Updating blog urls... ';
        $query = "SELECT blog_ID, blog_siteurl FROM T_blogs";
        $i = 0;
        foreach ($DB->get_results($query, ARRAY_A) as $row) {
            $blog_ID = $row['blog_ID'];
            $blog_siteurl = $row['blog_siteurl'];
            // echo $blog_ID.':'.$blog_siteurl;
            if (strpos($blog_siteurl . '/', $baseurl) !== 0) {
                // If not found at position 0
                echo ' <strong>WARNING: please check blog #', $blog_ID, ' manually.</strong><br /> ';
                continue;
            }
            // crop off the baseurl:
            $blog_siteurl = utf8_substr($blog_siteurl . '/', utf8_strlen($baseurl));
            // echo ' -> ', $blog_siteurl,'<br />';
            $query_update_blog = "UPDATE T_blogs SET blog_siteurl = '{$blog_siteurl}' WHERE blog_ID = {$blog_ID}";
            // echo $query_update_blog, '<br />';
            $DB->query($query_update_blog);
            $i++;
        }
        echo "OK. ({$i} rows updated)<br />\n";
        set_upgrade_checkpoint('8030');
    }
    if ($old_db_version < 8040) {
        // upgrade to 0.8.7
        echo 'Creating table for Antispam Blackist... ';
        $query = "CREATE TABLE {$tableprefix}antispam (\n\t\t\taspm_ID bigint(11) NOT NULL auto_increment,\n\t\t\taspm_string varchar(80) NOT NULL,\n\t\t\taspm_source enum( 'local','reported','central' ) NOT NULL default 'reported',\n\t\t\tPRIMARY KEY aspm_ID (aspm_ID),\n\t\t\tUNIQUE aspm_string (aspm_string)\n\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Creating default blacklist entries... ';
        // This string contains antispam information that is obfuscated because some hosting
        // companies prevent uploading PHP files containing "spam" strings.
        // pre_dump(get_antispam_query());
        $query = get_antispam_query();
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading Settings table... ';
        $query = "ALTER TABLE T_settings\n\t\t\t\t\t\t\tADD COLUMN last_antispam_update datetime NOT NULL default '2000-01-01 00:00:00'";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8040');
    }
    if ($old_db_version < 8050) {
        // upgrade to 0.8.9
        echo 'Upgrading blogs table... ';
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tADD COLUMN blog_allowtrackbacks tinyint(1) NOT NULL default 1,\n\t\t\t\t\t\t\tADD COLUMN blog_allowpingbacks tinyint(1) NOT NULL default 0,\n\t\t\t\t\t\t\tADD COLUMN blog_pingb2evonet tinyint(1) NOT NULL default 0,\n\t\t\t\t\t\t\tADD COLUMN blog_pingtechnorati tinyint(1) NOT NULL default 0,\n\t\t\t\t\t\t\tADD COLUMN blog_pingweblogs tinyint(1) NOT NULL default 0,\n\t\t\t\t\t\t\tADD COLUMN blog_pingblodotgs tinyint(1) NOT NULL default 0,\n\t\t\t\t\t\t\tADD COLUMN blog_disp_bloglist tinyint NOT NULL DEFAULT 1";
        $DB->query($query);
        echo "OK.<br />\n";
        // Create User Groups
        global $Group_Admins, $Group_Privileged, $Group_Bloggers, $Group_Users;
        echo 'Creating table for Groups... ';
        $query = "CREATE TABLE T_groups (\n\t\t\tgrp_ID int(11) NOT NULL auto_increment,\n\t\t\tgrp_name varchar(50) NOT NULL default '',\n\t\t\tgrp_perm_admin enum('none','hidden','visible') NOT NULL default 'visible',\n\t\t\tgrp_perm_blogs enum('user','viewall','editall') NOT NULL default 'user',\n\t\t\tgrp_perm_stats enum('none','view','edit') NOT NULL default 'none',\n\t\t\tgrp_perm_spamblacklist enum('none','view','edit') NOT NULL default 'none',\n\t\t\tgrp_perm_options enum('none','view','edit') NOT NULL default 'none',\n\t\t\tgrp_perm_users enum('none','view','edit') NOT NULL default 'none',\n\t\t\tgrp_perm_templates TINYINT NOT NULL DEFAULT 0,\n\t\t\tgrp_perm_files enum('none','view','add','edit','all') NOT NULL default 'none',\n\t\t\tPRIMARY KEY grp_ID (grp_ID)\n\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        // This table needs to be created here for proper group insertion
        task_begin('Creating table for Group Settings... ');
        $DB->query("CREATE TABLE T_groups__groupsettings (\n\t\t\tgset_grp_ID INT(11) UNSIGNED NOT NULL,\n\t\t\tgset_name VARCHAR(30) NOT NULL,\n\t\t\tgset_value VARCHAR(255) NULL,\n\t\t\tPRIMARY KEY (gset_grp_ID, gset_name)\n\t\t) ENGINE = innodb");
        task_end();
        echo 'Creating default groups... ';
        $Group_Admins = new Group();
        // COPY !
        $Group_Admins->set('name', 'Administrators');
        $Group_Admins->set('perm_admin', 'visible');
        $Group_Admins->set('perm_blogs', 'editall');
        $Group_Admins->set('perm_stats', 'edit');
        $Group_Admins->set('perm_spamblacklist', 'edit');
        $Group_Admins->set('perm_files', 'all');
        $Group_Admins->set('perm_options', 'edit');
        $Group_Admins->set('perm_templates', 1);
        $Group_Admins->set('perm_users', 'edit');
        $Group_Admins->dbinsert();
        $Group_Privileged = new Group();
        // COPY !
        $Group_Privileged->set('name', 'Privileged Bloggers');
        $Group_Privileged->set('perm_admin', 'visible');
        $Group_Privileged->set('perm_blogs', 'viewall');
        $Group_Privileged->set('perm_stats', 'view');
        $Group_Privileged->set('perm_spamblacklist', 'edit');
        $Group_Privileged->set('perm_files', 'add');
        $Group_Privileged->set('perm_options', 'view');
        $Group_Privileged->set('perm_templates', 0);
        $Group_Privileged->set('perm_users', 'view');
        $Group_Privileged->dbinsert();
        $Group_Bloggers = new Group();
        // COPY !
        $Group_Bloggers->set('name', 'Bloggers');
        $Group_Bloggers->set('perm_admin', 'visible');
        $Group_Bloggers->set('perm_blogs', 'user');
        $Group_Bloggers->set('perm_stats', 'none');
        $Group_Bloggers->set('perm_spamblacklist', 'view');
        $Group_Bloggers->set('perm_files', 'view');
        $Group_Bloggers->set('perm_options', 'none');
        $Group_Bloggers->set('perm_templates', 0);
        $Group_Bloggers->set('perm_users', 'none');
        $Group_Bloggers->dbinsert();
        $Group_Users = new Group();
        // COPY !
        $Group_Users->set('name', 'Basic Users');
        $Group_Users->set('perm_admin', 'none');
        $Group_Users->set('perm_blogs', 'user');
        $Group_Users->set('perm_stats', 'none');
        $Group_Users->set('perm_spamblacklist', 'none');
        $Group_Users->set('perm_files', 'none');
        $Group_Users->set('perm_options', 'none');
        $Group_Users->set('perm_templates', 0);
        $Group_Users->set('perm_users', 'none');
        $Group_Users->dbinsert();
        echo "OK.<br />\n";
        echo 'Creating table for Blog-User permissions... ';
        $query = "CREATE TABLE T_coll_user_perms (\n\t\t\tbloguser_blog_ID int(11) unsigned NOT NULL default 0,\n\t\t\tbloguser_user_ID int(11) unsigned NOT NULL default 0,\n\t\t\tbloguser_ismember tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_poststatuses set('published','deprecated','protected','private','draft') NOT NULL default '',\n\t\t\tbloguser_perm_delpost tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_comments tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_cats tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_properties tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_media_upload tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_media_browse tinyint NOT NULL default 0,\n\t\t\tbloguser_perm_media_change tinyint NOT NULL default 0,\n\t\t\tPRIMARY KEY bloguser_pk (bloguser_blog_ID,bloguser_user_ID)\n\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        $tablegroups_isuptodate = true;
        $tableblogusers_isuptodate = true;
        echo 'Creating user blog permissions... ';
        // Admin: full rights for all blogs (look 'ma, doing a natural join! :>)
        $query = "INSERT INTO T_coll_user_perms( bloguser_blog_ID, bloguser_user_ID, bloguser_ismember,\n\t\t\t\t\t\t\t\tbloguser_perm_poststatuses, bloguser_perm_delpost, bloguser_perm_comments,\n\t\t\t\t\t\t\t\tbloguser_perm_cats, bloguser_perm_properties)\n\t\t\t\t\t\t\tSELECT blog_ID, ID, 1, 'published,deprecated,protected,private,draft', 1, 1, 1, 1\n\t\t\t\t\t\t\tFROM T_users, T_blogs\n\t\t\t\t\t\t\tWHERE user_level = 10";
        $DB->query($query);
        // Normal users: basic rights for all blogs (can't stop doing joins :P)
        $query = "INSERT INTO T_coll_user_perms( bloguser_blog_ID, bloguser_user_ID, bloguser_ismember,\n\t\t\t\t\t\t\t\tbloguser_perm_poststatuses, bloguser_perm_delpost, bloguser_perm_comments,\n\t\t\t\t\t\t\t\tbloguser_perm_cats, bloguser_perm_properties)\n\t\t\t\t\t\t\tSELECT blog_ID, ID, 1, 'published,protected,private,draft', 0, 1, 0, 0\n\t\t\t\t\t\t\tFROM T_users, T_blogs\n\t\t\t\t\t\t\tWHERE user_level > 0 AND user_level < 10";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading users table... ';
        $DB->query('UPDATE T_users
									  SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE ( dateYMDhour = \'0000-00-00 00:00:00\' OR dateYMDhour = \'2000-00-00 00:00:01\' )');
        $DB->query('ALTER TABLE T_users
							MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $query = "ALTER TABLE T_users\n\t\t\t\t\t\t\tADD COLUMN user_notify tinyint(1) NOT NULL default 1,\n\t\t\t\t\t\t\tADD COLUMN user_grp_ID int(4) NOT NULL default 1,\n\t\t\t\t\t\t\tMODIFY COLUMN user_idmode varchar(20) NOT NULL DEFAULT 'login'";
        $DB->query($query);
        $query = "ALTER TABLE T_users\n\t\t\t\t\t\t\tADD KEY user_grp_ID (user_grp_ID)";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Assigning user groups... ';
        // Default is 1, so admins are already set.
        // Basic Users:
        $query = "UPDATE T_users\n\t\t\t\t\t\t\tSET user_grp_ID = {$Group_Users->ID}\n\t\t\t\t\t\t\tWHERE user_level = 0";
        $DB->query($query);
        // Bloggers:
        $query = "UPDATE T_users\n\t\t\t\t\t\t\tSET user_grp_ID = {$Group_Bloggers->ID}\n\t\t\t\t\t\t\tWHERE user_level > 0 AND user_level < 10";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading settings table... ';
        $query = "ALTER TABLE T_settings\n\t\t\t\t\t\t\tDROP COLUMN time_format,\n\t\t\t\t\t\t\tDROP COLUMN date_format,\n\t\t\t\t\t\t\tADD COLUMN pref_newusers_grp_ID int unsigned DEFAULT 4 NOT NULL,\n\t\t\t\t\t\t\tADD COLUMN pref_newusers_level tinyint unsigned DEFAULT 1 NOT NULL,\n\t\t\t\t\t\t\tADD COLUMN pref_newusers_canregister tinyint unsigned DEFAULT 0 NOT NULL";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8050');
    }
    if ($old_db_version < 8060) {
        // upgrade to 0.9
        // Important check:
        $stub_list = $DB->get_col("\n\t\t\tSELECT blog_stub\n\t\t\t  FROM T_blogs\n\t\t\t GROUP BY blog_stub\n\t\t\tHAVING COUNT(*) > 1");
        if (!empty($stub_list)) {
            echo '<div class="error"><p class="error">';
            printf(T_("It appears that the following blog stub names are used more than once: ['%s']"), implode("','", $stub_list));
            echo '</p><p>';
            printf(T_("I can't upgrade until you make them unique. DB field: [%s]"), $db_config['aliases']['T_blogs'] . '.blog_stub');
            echo '</p></div>';
            return false;
        }
        // Create locales
        echo 'Creating table for Locales... ';
        $query = "CREATE TABLE T_locales (\n\t\t\t\tloc_locale varchar(20) NOT NULL default '',\n\t\t\t\tloc_charset varchar(15) NOT NULL default 'iso-8859-1',\n\t\t\t\tloc_datefmt varchar(10) NOT NULL default 'y-m-d',\n\t\t\t\tloc_timefmt varchar(10) NOT NULL default 'H:i:s',\n\t\t\t\tloc_name varchar(40) NOT NULL default '',\n\t\t\t\tloc_messages varchar(20) NOT NULL default '',\n\t\t\t\tloc_priority tinyint(4) UNSIGNED NOT NULL default '0',\n\t\t\t\tloc_enabled tinyint(4) NOT NULL default '1',\n\t\t\t\tPRIMARY KEY loc_locale( loc_locale )\n\t\t\t) COMMENT='saves available locales'";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading posts table... ';
        $query = "UPDATE {$tableprefix}posts\n\t\t\t\t\t\t\tSET post_urltitle = NULL";
        $DB->query($query);
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tCHANGE COLUMN post_date post_issue_date datetime NOT NULL default '1000-01-01 00:00:00',\n\t\t\t\t\t\t\tADD COLUMN post_mod_date datetime NOT NULL default '1000-01-01 00:00:00'\n\t\t\t\t\t\t\t\t\t\tAFTER post_issue_date,\n\t\t\t\t\t\t\tCHANGE COLUMN post_lang post_locale varchar(20) NOT NULL default 'en-EU',\n\t\t\t\t\t\t\tDROP COLUMN post_url,\n\t\t\t\t\t\t\tCHANGE COLUMN post_trackbacks post_url varchar(250) NULL default NULL,\n\t\t\t\t\t\t\tADD COLUMN post_renderers VARCHAR(179) NOT NULL default 'default'";
        $DB->query($query);
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tADD INDEX post_issue_date( post_issue_date ),\n\t\t\t\t\t\t\tADD UNIQUE post_urltitle( post_urltitle )";
        $DB->query($query);
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\tDROP INDEX post_date";
        $DB->query($query);
        $query = "UPDATE {$tableprefix}posts\n\t\t\t\t\t\t\tSET post_mod_date = post_issue_date";
        $DB->query($query);
        echo "OK.<br />\n";
        // convert given languages to locales
        convert_lang_to_locale("{$tableprefix}posts", 'post_locale', 'ID');
        echo 'Upgrading blogs table... ';
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tCHANGE blog_lang blog_locale varchar(20) NOT NULL default 'en-EU',\n\t\t\t\t\t\t\tCHANGE blog_roll blog_notes TEXT NULL,\n\t\t\t\t\t\t\tMODIFY COLUMN blog_default_skin VARCHAR(30) NOT NULL DEFAULT 'custom',\n\t\t\t\t\t\t\tDROP COLUMN blog_filename,\n\t\t\t\t\t\t\tADD COLUMN blog_access_type VARCHAR(10) NOT NULL DEFAULT 'index.php' AFTER blog_locale,\n\t\t\t\t\t\t\tADD COLUMN blog_force_skin tinyint(1) NOT NULL default 0 AFTER blog_default_skin,\n\t\t\t\t\t\t\tADD COLUMN blog_in_bloglist tinyint(1) NOT NULL DEFAULT 1 AFTER blog_disp_bloglist,\n\t\t\t\t\t\t\tADD COLUMN blog_links_blog_ID INT(4) NOT NULL DEFAULT 0,\n\t\t\t\t\t\t\tADD UNIQUE KEY blog_stub (blog_stub)";
        $DB->query($query);
        $query = "UPDATE T_blogs\n\t\t\t\t\t\t\tSET blog_access_type = 'stub',\n\t\t\t\t\t\t\t\t\tblog_default_skin = 'custom'";
        $DB->query($query);
        echo "OK.<br />\n";
        // convert given languages to locales
        convert_lang_to_locale('T_blogs', 'blog_locale', 'blog_ID');
        echo 'Converting settings table... ';
        // get old settings
        $query = 'SELECT * FROM T_settings';
        $row = $DB->get_row($query, ARRAY_A);
        #echo 'oldrow:<br />'; pre_dump($row);
        $transform = array('posts_per_page' => array(5), 'what_to_show' => array('posts'), 'archive_mode' => array('monthly'), 'time_difference' => array(0), 'AutoBR' => array(0), 'last_antispam_update' => array('2000-01-01 00:00:00', 'antispam_last_update'), 'pref_newusers_grp_ID' => array($Group_Users->ID, 'newusers_grp_ID'), 'pref_newusers_level' => array(1, 'newusers_level'), 'pref_newusers_canregister' => array(0, 'newusers_canregister'));
        $_trans = array();
        foreach ($transform as $oldkey => $newarr) {
            $newname = isset($newarr[1]) ? $newarr[1] : $oldkey;
            if (!isset($row[$oldkey])) {
                echo '&nbsp;&middot;Setting ' . $oldkey . ' not found, using defaults.<br />';
                $_trans[$newname] = $newarr[0];
            } else {
                $_trans[$newname] = $row[$oldkey];
            }
        }
        // drop old table
        $DB->query('DROP TABLE IF EXISTS T_settings');
        // create new table
        $DB->query('CREATE TABLE T_settings (
				set_name VARCHAR( 30 ) NOT NULL ,
				set_value VARCHAR( 255 ) NULL ,
				PRIMARY KEY ( set_name )
			)');
        // insert defaults and use transformed settings
        create_default_settings($_trans);
        if (!isset($tableblogusers_isuptodate)) {
            echo 'Upgrading Blog-User permissions table... ';
            $query = "ALTER TABLE T_coll_user_perms\n\t\t\t\t\t\t\t\tADD COLUMN bloguser_ismember tinyint NOT NULL default 0 AFTER bloguser_user_ID";
            $DB->query($query);
            // Any row that is created holds at least one permission,
            // minimum permsission is to be a member, so we add that one too, to all existing rows.
            $DB->query("UPDATE T_coll_user_perms\n\t\t\t\t\t\t\t\t\t\t\tSET bloguser_ismember = 1");
            echo "OK.<br />\n";
        }
        echo 'Upgrading Comments table... ';
        $DB->query('UPDATE T_comments
									  SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'');
        $DB->query('ALTER TABLE T_comments
							MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $query = "ALTER TABLE T_comments\n\t\t\t\t\t\t\tADD COLUMN comment_author_ID int unsigned NULL default NULL AFTER comment_status,\n\t\t\t\t\t\t\tMODIFY COLUMN comment_author varchar(100) NULL,\n\t\t\t\t\t\t\tMODIFY COLUMN comment_author_email varchar(100) NULL,\n\t\t\t\t\t\t\tMODIFY COLUMN comment_author_url varchar(100) NULL,\n\t\t\t\t\t\t\tMODIFY COLUMN comment_author_IP varchar(23) NOT NULL default ''";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading Users table... ';
        $query = "ALTER TABLE T_users ADD user_locale VARCHAR( 20 ) DEFAULT 'en-EU' NOT NULL AFTER user_yim";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8060');
    }
    if ($old_db_version < 8062) {
        // upgrade to 0.9.0.4
        echo "Checking for extra quote escaping in posts... ";
        $query = "SELECT ID, post_title, post_content\n\t\t\t\t\t\t\t\tFROM {$tableprefix}posts\n\t\t\t\t\t\t\t WHERE post_title LIKE '%\\\\\\\\\\'%'\n\t\t\t\t\t\t\t\t\tOR post_title LIKE '%\\\\\\\\\"%'\n\t\t\t\t\t\t\t\t\tOR post_content LIKE '%\\\\\\\\\\'%'\n\t\t\t\t\t\t\t\t\tOR post_content LIKE '%\\\\\\\\\"%' ";
        /* FP: the above looks overkill, but MySQL is really full of surprises...
        			tested on 4.0.14-nt */
        // echo $query;
        $rows = $DB->get_results($query, ARRAY_A);
        if ($DB->num_rows) {
            echo 'Updating ' . $DB->num_rows . ' posts... ';
            foreach ($rows as $row) {
                // echo '<br />'.$row['post_title'];
                $query = "UPDATE {$tableprefix}posts\n\t\t\t\t\t\t\t\t\tSET post_title = " . $DB->quote(stripslashes($row['post_title'])) . ",\n\t\t\t\t\t\t\t\t\t\t\tpost_content = " . $DB->quote(stripslashes($row['post_content'])) . "\n\t\t\t\t\t\t\t\t\tWHERE ID = " . $row['ID'];
                // echo '<br />'.$query;
                $DB->query($query);
            }
        }
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8062');
    }
    if ($old_db_version < 8064) {
        // upgrade to 0.9.0.6
        cleanup_comment_quotes();
        set_upgrade_checkpoint('8064');
    }
    if ($old_db_version < 8066) {
        // upgrade to 0.9.1
        echo 'Adding catpost index... ';
        $DB->query('ALTER TABLE T_postcats ADD UNIQUE catpost ( postcat_cat_ID, postcat_post_ID )');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8066');
    }
    if ($old_db_version < 8800) {
        // ---------------------------------- upgrade to 1.6 "phoenix ALPHA"
        echo 'Dropping old Hitlog table... ';
        $DB->query('DROP TABLE IF EXISTS T_hitlog');
        echo "OK.<br />\n";
        // New tables:
        echo 'Creating table for active sessions... ';
        $DB->query("CREATE TABLE T_sessions (\n\t\t\t\t\t\t\t\t\t\t\tsess_ID        INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\t\tsess_key       CHAR(32) NULL,\n\t\t\t\t\t\t\t\t\t\t\tsess_lastseen  DATETIME NOT NULL,\n\t\t\t\t\t\t\t\t\t\t\tsess_ipaddress VARCHAR(15) NOT NULL DEFAULT '',\n\t\t\t\t\t\t\t\t\t\t\tsess_user_ID   INT(10) DEFAULT NULL,\n\t\t\t\t\t\t\t\t\t\t\tsess_agnt_ID   INT UNSIGNED NULL,\n\t\t\t\t\t\t\t\t\t\t\tsess_data      TEXT DEFAULT NULL,\n\t\t\t\t\t\t\t\t\t\t\tPRIMARY KEY( sess_ID )\n\t\t\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating user settings table... ';
        $DB->query("CREATE TABLE {$tableprefix}usersettings (\n\t\t\t\t\t\t\t\t\t\t\tuset_user_ID INT(11) UNSIGNED NOT NULL,\n\t\t\t\t\t\t\t\t\t\t\tuset_name    VARCHAR( 30 ) NOT NULL,\n\t\t\t\t\t\t\t\t\t\t\tuset_value   VARCHAR( 255 ) NULL,\n\t\t\t\t\t\t\t\t\t\t\tPRIMARY KEY ( uset_user_ID, uset_name )\n\t\t\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating plugins table... ';
        $DB->query("CREATE TABLE T_plugins (\n\t\t\t\t\t\t\t\t\t\t\tplug_ID        INT(11) UNSIGNED NOT NULL auto_increment,\n\t\t\t\t\t\t\t\t\t\t\tplug_priority  INT(11) NOT NULL default 50,\n\t\t\t\t\t\t\t\t\t\t\tplug_classname VARCHAR(40) NOT NULL default '',\n\t\t\t\t\t\t\t\t\t\t\tPRIMARY KEY ( plug_ID )\n\t\t\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating table for Post Statuses... ';
        $query = "CREATE TABLE {$tableprefix}poststatuses (\n\t\t\t\t\t\t\t\t\t\t\tpst_ID   int(11) unsigned not null AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\t\tpst_name varchar(30)      not null,\n\t\t\t\t\t\t\t\t\t\t\tprimary key ( pst_ID )\n\t\t\t\t\t\t\t\t\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Creating table for Post Types... ';
        $query = "CREATE TABLE {$tableprefix}posttypes (\n\t\t\t\t\t\t\t\t\t\t\tptyp_ID   int(11) unsigned not null AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\t\tptyp_name varchar(30)      not null,\n\t\t\t\t\t\t\t\t\t\t\tprimary key (ptyp_ID)\n\t\t\t\t\t\t\t\t\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Creating table for File Meta Data... ';
        $DB->query("CREATE TABLE T_files (\n\t\t\t\t\t\t\t\t\t\t file_ID        int(11) unsigned  not null AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\t file_root_type enum('absolute','user','group','collection') not null default 'absolute',\n\t\t\t\t\t\t\t\t\t\t file_root_ID   int(11) unsigned  not null default 0,\n\t\t\t\t\t\t\t\t\t\t file_path      varchar(255)      not null default '',\n\t\t\t\t\t\t\t\t\t\t file_title     varchar(255),\n\t\t\t\t\t\t\t\t\t\t file_alt       varchar(255),\n\t\t\t\t\t\t\t\t\t\t file_desc      text,\n\t\t\t\t\t\t\t\t\t\t primary key (file_ID),\n\t\t\t\t\t\t\t\t\t\t unique file (file_root_type, file_root_ID, file_path)\n\t\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating table for base domains... ';
        $DB->query("CREATE TABLE T_basedomains (\n\t\t\t\t\t\t\t\t\t\tdom_ID     INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\tdom_name   VARCHAR(250) NOT NULL DEFAULT '',\n\t\t\t\t\t\t\t\t\t\tdom_status ENUM('unknown','whitelist','blacklist') NOT NULL DEFAULT 'unknown',\n\t\t\t\t\t\t\t\t\t\tdom_type   ENUM('unknown','normal','searcheng','aggregator') NOT NULL DEFAULT 'unknown',\n\t\t\t\t\t\t\t\t\t\tPRIMARY KEY (dom_ID),\n\t\t\t\t\t\t\t\t\t\tUNIQUE dom_name (dom_name)\n\t\t\t\t\t\t\t\t\t)");
        // fp> the unique key was only named in version 1.9. Crap. Put the name back here to save as many souls as possible. bulk has not upgraded from 0.9 yet :/
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8820');
    }
    if ($old_db_version < 8840) {
        echo 'Creating table for user agents... ';
        $DB->query("CREATE TABLE {$tableprefix}useragents (\n\t\t\t\t\t\t\t\t\t\tagnt_ID        INT UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\tagnt_signature VARCHAR(250) NOT NULL,\n\t\t\t\t\t\t\t\t\t\tagnt_type      ENUM('rss','robot','browser','unknown') DEFAULT 'unknown' NOT NULL,\n\t\t\t\t\t\t\t\t\t\tPRIMARY KEY (agnt_ID) )");
        echo "OK.<br />\n";
        echo 'Creating table for Hit-Logs... ';
        $query = "CREATE TABLE T_hitlog (\n\t\t\t\t\t\t\t\t\thit_ID             INT(11) NOT NULL AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\thit_sess_ID        INT UNSIGNED,\n\t\t\t\t\t\t\t\t\thit_datetime       DATETIME NOT NULL,\n\t\t\t\t\t\t\t\t\thit_uri            VARCHAR(250) DEFAULT NULL,\n\t\t\t\t\t\t\t\t\thit_referer_type   ENUM('search','blacklist','referer','direct','spam') NOT NULL,\n\t\t\t\t\t\t\t\t\thit_referer        VARCHAR(250) DEFAULT NULL,\n\t\t\t\t\t\t\t\t\thit_referer_dom_ID INT UNSIGNED DEFAULT NULL,\n\t\t\t\t\t\t\t\t\thit_blog_ID        int(11) UNSIGNED NULL DEFAULT NULL,\n\t\t\t\t\t\t\t\t\thit_remote_addr    VARCHAR(40) DEFAULT NULL,\n\t\t\t\t\t\t\t\t\tPRIMARY KEY (hit_ID),\n\t\t\t\t\t\t\t\t\tINDEX hit_datetime ( hit_datetime ),\n\t\t\t\t\t\t\t\t\tINDEX hit_blog_ID (hit_blog_ID)\n\t\t\t\t\t\t\t\t)";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Creating table for subscriptions... ';
        $DB->query("CREATE TABLE T_subscriptions (\n\t\t\t\t\t\t\t\t\t\t sub_coll_ID     int(11) unsigned    not null,\n\t\t\t\t\t\t\t\t\t\t sub_user_ID     int(11) unsigned    not null,\n\t\t\t\t\t\t\t\t\t\t sub_items       tinyint(1)          not null,\n\t\t\t\t\t\t\t\t\t\t sub_comments    tinyint(1)          not null,\n\t\t\t\t\t\t\t\t\t\t primary key (sub_coll_ID, sub_user_ID)\n\t\t\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating table for blog-group permissions... ';
        $DB->query("CREATE TABLE T_coll_group_perms (\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_blog_ID int(11) unsigned NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_group_ID int(11) unsigned NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_ismember tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_poststatuses set('published','deprecated','protected','private','draft') NOT NULL default '',\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_delpost tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_comments tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_cats tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_properties tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_media_upload tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_media_browse tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tbloggroup_perm_media_change tinyint NOT NULL default 0,\n\t\t\t\t\t\t\t\t\t\t\tPRIMARY KEY bloggroup_pk (bloggroup_blog_ID,bloggroup_group_ID) )");
        echo "OK.<br />\n";
        echo 'Upgrading blogs table... ';
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tMODIFY COLUMN blog_ID int(11) unsigned NOT NULL auto_increment,\n\t\t\t\t\t\t\tMODIFY COLUMN blog_links_blog_ID INT(11) NULL DEFAULT NULL,\n\t\t\t\t\t\t\tCHANGE COLUMN blog_stub blog_urlname VARCHAR(255) NOT NULL DEFAULT 'urlname',\n\t\t\t\t\t\t\tADD COLUMN blog_allowcomments VARCHAR(20) NOT NULL default 'post_by_post' AFTER blog_keywords,\n\t\t\t\t\t\t\tADD COLUMN blog_allowblogcss TINYINT(1) NOT NULL default 1 AFTER blog_allowpingbacks,\n\t\t\t\t\t\t\tADD COLUMN blog_allowusercss TINYINT(1) NOT NULL default 1 AFTER blog_allowblogcss,\n\t\t\t\t\t\t\tADD COLUMN blog_stub VARCHAR(255) NOT NULL DEFAULT 'stub' AFTER blog_staticfilename,\n\t\t\t\t\t\t\tADD COLUMN blog_commentsexpire INT(4) NOT NULL DEFAULT 0 AFTER blog_links_blog_ID,\n\t\t\t\t\t\t\tADD COLUMN blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) DEFAULT 'default' NOT NULL AFTER blog_commentsexpire,\n\t\t\t\t\t\t\tADD COLUMN blog_media_subdir VARCHAR( 255 ) NOT NULL AFTER blog_media_location,\n\t\t\t\t\t\t\tADD COLUMN blog_media_fullpath VARCHAR( 255 ) NOT NULL AFTER blog_media_subdir,\n\t\t\t\t\t\t\tADD COLUMN blog_media_url VARCHAR(255) NOT NULL AFTER blog_media_fullpath";
        $DB->query($query);
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tADD UNIQUE blog_urlname ( blog_urlname )";
        $DB->query($query);
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tDROP INDEX blog_stub";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8840');
    }
    // sam2kb>fp: We need to make sure there are no values like "blog_a.php" in blog_urlname,
    //			after this upgrade blog URLs look like $baseurl.'blog_a.php' which might be OK in 0.x version,
    //			but this config will not work in b2evo 4. Blog URLs will be broken!
    if ($old_db_version < 8850) {
        echo 'Updating relative URLs... ';
        // We need to move the slashes to the end:
        $query = "UPDATE T_blogs\n\t\t\t\t\t\t\t\t SET blog_siteurl = CONCAT( SUBSTRING(blog_siteurl,2) , '/' )\n\t\t\t\t\t\t\t WHERE blog_siteurl LIKE '/%'";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Copying urlnames to stub names... ';
        $query = 'UPDATE T_blogs
							SET blog_stub = blog_urlname';
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8850');
    }
    if ($old_db_version < 8855) {
        echo 'Upgrading posts table... ';
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tDROP INDEX post_author,\n\t\t\t\t\t\t\tDROP INDEX post_issue_date,\n\t\t\t\t\t\t\tDROP INDEX post_category";
        $DB->query($query);
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tDROP COLUMN post_karma,\n\t\t\t\t\t\t\tDROP COLUMN post_autobr,\n\t\t\t\t\t\t\tCHANGE COLUMN ID post_ID int(11) unsigned NOT NULL auto_increment,\n\t\t\t\t\t\t\tCHANGE COLUMN post_author\tpost_creator_user_ID int(11) unsigned NOT NULL,\n\t\t\t\t\t\t\tCHANGE COLUMN post_issue_date\tpost_datestart datetime NOT NULL,\n\t\t\t\t\t\t\tCHANGE COLUMN post_mod_date\tpost_datemodified datetime NOT NULL,\n\t\t\t\t\t\t\tCHANGE COLUMN post_category post_main_cat_ID int(11) unsigned NOT NULL,\n\t\t\t\t\t\t\tADD post_parent_ID\t\t\t\tint(11) unsigned NULL AFTER post_ID,\n\t\t\t\t\t\t\tADD post_lastedit_user_ID\tint(11) unsigned NULL AFTER post_creator_user_ID,\n\t\t\t\t\t\t\tADD post_assigned_user_ID\tint(11) unsigned NULL AFTER post_lastedit_user_ID,\n\t\t\t\t\t\t\tADD post_datedeadline \t\tdatetime NULL AFTER post_datestart,\n\t\t\t\t\t\t\tADD post_datecreated\t\t\tdatetime NULL AFTER post_datedeadline,\n\t\t\t\t\t\t\tADD post_pst_ID\t\t\t\t\t\tint(11) unsigned NULL AFTER post_status,\n\t\t\t\t\t\t\tADD post_ptyp_ID\t\t\t\t\tint(11) unsigned NULL AFTER post_pst_ID,\n\t\t\t\t\t\t\tADD post_views\t\t\t\t\t\tint(11) unsigned NOT NULL DEFAULT 0 AFTER post_flags,\n\t\t\t\t\t\t\tADD post_commentsexpire\t\tdatetime DEFAULT NULL AFTER post_comments,\n\t\t\t\t\t\t\tADD post_priority\t\t\t\t\tint(11) unsigned null";
        $DB->query($query);
        $query = "ALTER TABLE {$tableprefix}posts\n\t\t\t\t\t\t\tADD INDEX post_creator_user_ID( post_creator_user_ID ),\n\t\t\t\t\t\t\tADD INDEX post_parent_ID( post_parent_ID ),\n\t\t\t\t\t\t\tADD INDEX post_assigned_user_ID( post_assigned_user_ID ),\n\t\t\t\t\t\t\tADD INDEX post_datestart( post_datestart ),\n\t\t\t\t\t\t\tADD INDEX post_main_cat_ID( post_main_cat_ID ),\n\t\t\t\t\t\t\tADD INDEX post_ptyp_ID( post_ptyp_ID ),\n\t\t\t\t\t\t\tADD INDEX post_pst_ID( post_pst_ID ) ";
        $DB->query($query);
        echo "OK.<br />\n";
        set_upgrade_checkpoint('8855');
    }
    if ($old_db_version < 8860) {
        echo 'Updating post data... ';
        $query = "UPDATE {$tableprefix}posts\n\t\t\t\t\t\t\tSET post_lastedit_user_ID = post_creator_user_ID,\n\t\t\t\t\t\t\t\t\tpost_datecreated = post_datestart";
        $DB->query($query);
        echo "OK.<br />\n";
        task_begin('Upgrading users table... ');
        $DB->query('UPDATE T_users
									  SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE dateYMDhour = \'0000-00-00 00:00:00\'');
        $DB->query('ALTER TABLE T_users
							MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
							CHANGE COLUMN ID user_ID int(11) unsigned NOT NULL auto_increment,
							MODIFY COLUMN user_icq int(11) unsigned DEFAULT 0 NOT NULL,
							ADD COLUMN user_showonline tinyint(1) NOT NULL default 1 AFTER user_notify');
        task_end();
        set_upgrade_checkpoint('8860');
    }
    if ($old_db_version < 8900) {
        echo 'Setting new defaults... ';
        $query = 'INSERT INTO T_settings (set_name, set_value)
							VALUES
								( "reloadpage_timeout", "300" ),
								( "upload_enabled", "' . (isset($use_fileupload) ? (int) $use_fileupload : '1') . '" ),
								( "upload_allowedext", "' . (isset($fileupload_allowedtypes) ? $fileupload_allowedtypes : 'jpg gif png') . '" ),
								( "upload_maxkb", "' . (isset($fileupload_maxk) ? (int) $fileupload_maxk : '96') . '" )
							';
        $DB->query($query);
        // Replace "paged" mode with "posts" // note: moved to blogsettings in 2.0
        $DB->query('UPDATE T_settings
										SET set_value = "posts"
									WHERE set_name = "what_to_show"
									  AND set_value = "paged"');
        echo "OK.<br />\n";
        if (!isset($tableblogusers_isuptodate)) {
            // We have created the blogusers table before and it's already clean!
            echo 'Altering table for Blog-User permissions... ';
            $DB->query('ALTER TABLE T_coll_user_perms
										MODIFY COLUMN bloguser_blog_ID int(11) unsigned NOT NULL default 0,
										MODIFY COLUMN bloguser_user_ID int(11) unsigned NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_upload tinyint NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_browse tinyint NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_change tinyint NOT NULL default 0');
            echo "OK.<br />\n";
        }
        task_begin('Altering comments table...');
        $DB->query('UPDATE T_comments
									  SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'');
        $DB->query('ALTER TABLE T_comments
									MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
									MODIFY COLUMN comment_post_ID		int(11) unsigned NOT NULL default 0');
        task_end();
        set_upgrade_checkpoint('8900');
    }
    if ($old_db_version < 9000) {
        echo 'Altering Posts to Categories table... ';
        $DB->query("ALTER TABLE T_postcats\n\t\t\t\t\t\t\t\t\tMODIFY COLUMN postcat_post_ID int(11) unsigned NOT NULL,\n\t\t\t\t\t\t\t\t\tMODIFY COLUMN postcat_cat_ID int(11) unsigned NOT NULL");
        echo "OK.<br />\n";
        echo 'Altering Categories table... ';
        $DB->query("ALTER TABLE T_categories\n\t\t\t\t\t\t\t\t\tMODIFY COLUMN cat_ID int(11) unsigned NOT NULL auto_increment,\n\t\t\t\t\t\t\t\t\tMODIFY COLUMN cat_parent_ID int(11) unsigned NULL,\n\t\t\t\t\t\t\t\t\tMODIFY COLUMN cat_blog_ID int(11) unsigned NOT NULL default 2");
        echo "OK.<br />\n";
        echo 'Altering Locales table... ';
        $DB->query('ALTER TABLE T_locales
									ADD loc_startofweek TINYINT UNSIGNED NOT NULL DEFAULT 1 AFTER loc_timefmt');
        echo "OK.<br />\n";
        if (!isset($tablegroups_isuptodate)) {
            // We have created the groups table before and it's already clean!
            echo 'Altering Groups table... ';
            $DB->query("ALTER TABLE T_groups\n\t\t\t\t\t\t\t\t\t\tADD COLUMN grp_perm_admin enum('none','hidden','visible') NOT NULL default 'visible' AFTER grp_name,\n\t\t\t\t\t\t\t\t\t\tADD COLUMN grp_perm_files enum('none','view','add','edit') NOT NULL default 'none'");
            echo "OK.<br />\n";
        }
        echo 'Creating table for Post Links... ';
        $DB->query("CREATE TABLE T_links (\n\t\t\t\t\t\t\t\t\tlink_ID               int(11) unsigned  not null AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\tlink_datecreated      datetime          not null,\n\t\t\t\t\t\t\t\t\tlink_datemodified     datetime          not null,\n\t\t\t\t\t\t\t\t\tlink_creator_user_ID  int(11) unsigned  not null,\n\t\t\t\t\t\t\t\t\tlink_lastedit_user_ID int(11) unsigned  not null,\n\t\t\t\t\t\t\t\t\tlink_item_ID          int(11) unsigned  NOT NULL,\n\t\t\t\t\t\t\t\t\tlink_dest_item_ID     int(11) unsigned  NULL,\n\t\t\t\t\t\t\t\t\tlink_file_ID          int(11) unsigned  NULL,\n\t\t\t\t\t\t\t\t\tlink_ltype_ID         int(11) unsigned  NOT NULL default 1,\n\t\t\t\t\t\t\t\t\tlink_external_url     VARCHAR(255)      NULL,\n\t\t\t\t\t\t\t\t\tlink_title            TEXT              NULL,\n\t\t\t\t\t\t\t\t\tPRIMARY KEY (link_ID),\n\t\t\t\t\t\t\t\t\tINDEX link_item_ID( link_item_ID ),\n\t\t\t\t\t\t\t\t\tINDEX link_dest_item_ID (link_dest_item_ID),\n\t\t\t\t\t\t\t\t\tINDEX link_file_ID (link_file_ID)\n\t\t\t\t\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Creating default Post Types... ';
        $DB->query("\n\t\t\tINSERT INTO {$tableprefix}posttypes ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 1, 'Post' ),\n\t\t\t       ( 2, 'Link' )");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9000');
    }
    if ($old_db_version < 9100) {
        // 1.8 ALPHA
        echo 'Creating table for plugin events... ';
        $DB->query('
			CREATE TABLE T_pluginevents(
					pevt_plug_ID INT(11) UNSIGNED NOT NULL,
					pevt_event VARCHAR(40) NOT NULL,
					pevt_enabled TINYINT NOT NULL DEFAULT 1,
					PRIMARY KEY( pevt_plug_ID, pevt_event )
				)');
        echo "OK.<br />\n";
        echo 'Altering Links table... ';
        $DB->query('ALTER TABLE T_links
		             CHANGE link_item_ID link_itm_ID INT( 11 ) UNSIGNED NOT NULL,
		             CHANGE link_dest_item_ID link_dest_itm_ID INT( 11 ) UNSIGNED NULL');
        echo "OK.<br />\n";
        if ($old_db_version >= 9000) {
            // sess_agnt_ID used in Phoenix-Alpha
            echo 'Altering sessions table... ';
            $query = "\n\t\t\t\t\tALTER TABLE T_sessions\n\t\t\t\t\t DROP COLUMN sess_agnt_ID";
            $DB->query($query);
            echo "OK.<br />\n";
        }
        echo 'Creating table for file types... ';
        $DB->query('
				CREATE TABLE T_filetypes (
					ftyp_ID int(11) unsigned NOT NULL auto_increment,
					ftyp_extensions varchar(30) NOT NULL,
					ftyp_name varchar(30) NOT NULL,
					ftyp_mimetype varchar(50) NOT NULL,
					ftyp_icon varchar(20) default NULL,
					ftyp_viewtype varchar(10) NOT NULL,
					ftyp_allowed tinyint(1) NOT NULL default 0,
					PRIMARY KEY (ftyp_ID)
				)');
        echo "OK.<br />\n";
        echo 'Creating default file types... ';
        $DB->query("INSERT INTO T_filetypes\n\t\t\t\t(ftyp_ID, ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)\n\t\t\tVALUES\n\t\t\t\t(1, 'gif', 'GIF image', 'image/gif', 'image2.png', 'image', 1),\n\t\t\t\t(2, 'png', 'PNG image', 'image/png', 'image2.png', 'image', 1),\n\t\t\t\t(3, 'jpg jpeg', 'JPEG image', 'image/jpeg', 'image2.png', 'image', 1),\n\t\t\t\t(4, 'txt', 'Text file', 'text/plain', 'document.png', 'text', 1),\n\t\t\t\t(5, 'htm html', 'HTML file', 'text/html', 'html.png', 'browser', 0),\n\t\t\t\t(6, 'pdf', 'PDF file', 'application/pdf', 'pdf.png', 'browser', 1),\n\t\t\t\t(7, 'doc', 'Microsoft Word file', 'application/msword', 'doc.gif', 'external', 1),\n\t\t\t\t(8, 'xls', 'Microsoft Excel file', 'application/vnd.ms-excel', 'xls.gif', 'external', 1),\n\t\t\t\t(9, 'ppt', 'Powerpoint', 'application/vnd.ms-powerpoint', 'ppt.gif', 'external', 1),\n\t\t\t\t(10, 'pps', 'Slideshow', 'pps', 'pps.gif', 'external', 1),\n\t\t\t\t(11, 'zip', 'ZIP archive', 'application/zip', 'zip.gif', 'external', 1),\n\t\t\t\t(12, 'php php3 php4 php5 php6', 'PHP script', 'application/x-httpd-php', 'php.gif', 'text', 0),\n\t\t\t\t(13, 'css', 'Style sheet', 'text/css', '', 'text', 1)\n\t\t\t");
        echo "OK.<br />\n";
        echo 'Giving Administrator Group edit perms on files... ';
        $DB->query('UPDATE T_groups
		             SET grp_perm_files = "edit"
		             WHERE grp_ID = 1');
        // Later versions give 'all' on install, but we won't upgrade to that for security.
        echo "OK.<br />\n";
        echo 'Giving Administrator Group full perms on media for all blogs... ';
        $DB->query('UPDATE T_coll_group_perms
		             SET bloggroup_perm_media_upload = 1,
		                 bloggroup_perm_media_browse = 1,
		                 bloggroup_perm_media_change = 1
		             WHERE bloggroup_group_ID = 1');
        echo "OK.<br />\n";
        if ($old_db_version >= 9000) {
            // Uninstall all ALPHA (potentially incompatible) plugins
            echo 'Uninstalling all existing plugins... ';
            $DB->query('DELETE FROM T_plugins WHERE 1=1');
            echo "OK.<br />\n";
        }
        // NOTE: basic plugins get installed separatly for upgrade and install..
        set_upgrade_checkpoint('9100');
    }
    if ($old_db_version < 9190) {
        // 1.8 ALPHA (block #2)
        echo 'Altering Posts table... ';
        $DB->query("ALTER TABLE {$tableprefix}posts\n\t\t             CHANGE post_comments post_comment_status ENUM('disabled', 'open', 'closed') NOT NULL DEFAULT 'open'");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9190');
    }
    if ($old_db_version < 9192) {
        // 1.8 ALPHA (block #3) - The payload that db_delta() handled before
        // This is a fix, which broke upgrade to 1.8 (from 1.6) in MySQL strict mode (inserted after 1.8 got released!):
        if ($DB->get_row('SHOW COLUMNS FROM T_hitlog LIKE "hit_referer_type"')) {
            // a niiiiiiiice extra check :p
            task_begin('Deleting all "spam" hitlog entries... ');
            $DB->query('
					DELETE FROM T_hitlog
					 WHERE hit_referer_type = "spam"');
            task_end();
        }
        task_begin('Upgrading users table... ');
        $DB->query('ALTER TABLE T_users
										CHANGE COLUMN user_firstname user_firstname varchar(50) NULL,
										CHANGE COLUMN user_lastname user_lastname varchar(50) NULL,
										CHANGE COLUMN user_nickname user_nickname varchar(50) NULL,
										CHANGE COLUMN user_icq user_icq int(11) unsigned NULL,
										CHANGE COLUMN user_email user_email varchar(255) NOT NULL,
										CHANGE COLUMN user_url user_url varchar(255) NULL,
										CHANGE COLUMN user_ip user_ip varchar(15) NULL,
										CHANGE COLUMN user_domain user_domain varchar(200) NULL,
										CHANGE COLUMN user_browser user_browser varchar(200) NULL,
										CHANGE COLUMN user_aim user_aim varchar(50) NULL,
										CHANGE COLUMN user_msn user_msn varchar(100) NULL,
										CHANGE COLUMN user_yim user_yim varchar(50) NULL,
										ADD COLUMN user_allow_msgform TINYINT NOT NULL DEFAULT \'1\' AFTER user_idmode,
										ADD COLUMN user_validated TINYINT(1) NOT NULL DEFAULT 0 AFTER user_grp_ID');
        task_end();
        task_begin('Creating blog settings...');
        $DB->query('CREATE TABLE T_coll_settings (
															cset_coll_ID INT(11) UNSIGNED NOT NULL,
															cset_name    VARCHAR( 30 ) NOT NULL,
															cset_value   VARCHAR( 255 ) NULL,
															PRIMARY KEY ( cset_coll_ID, cset_name )
											)');
        task_end();
        set_upgrade_checkpoint('9192');
    }
    if ($old_db_version < 9195) {
        task_begin('Upgrading posts table... ');
        $DB->query('ALTER TABLE ' . $tableprefix . 'posts
										CHANGE COLUMN post_content post_content         text NULL,
										CHANGE COLUMN post_url post_url              		VARCHAR(255) NULL DEFAULT NULL,
										CHANGE COLUMN post_renderers post_renderers     TEXT NOT NULL');
        task_end();
        task_begin('Upgrading comments table... ');
        $DB->query('ALTER TABLE T_comments
										CHANGE COLUMN comment_author_email comment_author_email varchar(255) NULL,
										CHANGE COLUMN comment_author_url comment_author_url varchar(255) NULL,
										ADD COLUMN comment_spam_karma TINYINT NULL AFTER comment_karma,
										ADD COLUMN comment_allow_msgform TINYINT NOT NULL DEFAULT 0 AFTER comment_spam_karma');
        task_end();
        set_upgrade_checkpoint('9195');
    }
    if ($old_db_version < 9200) {
        task_begin('Upgrading hitlog table... ');
        $DB->query('ALTER TABLE T_hitlog
										CHANGE COLUMN hit_referer_type hit_referer_type   ENUM(\'search\',\'blacklist\',\'referer\',\'direct\') NOT NULL,
										ADD COLUMN hit_agnt_ID        INT UNSIGNED NULL AFTER hit_remote_addr');
        task_end();
        task_begin('Upgrading post links table... ');
        $DB->query('ALTER TABLE T_links
										ADD INDEX link_itm_ID( link_itm_ID ),
										ADD INDEX link_dest_itm_ID (link_dest_itm_ID)');
        task_end();
        task_begin('Upgrading plugins table... ');
        $DB->query('ALTER TABLE T_plugins
										CHANGE COLUMN plug_priority plug_priority        TINYINT NOT NULL default 50,
										ADD COLUMN plug_code            VARCHAR(32) NULL AFTER plug_classname,
										ADD COLUMN plug_apply_rendering ENUM( \'stealth\', \'always\', \'opt-out\', \'opt-in\', \'lazy\', \'never\' ) NOT NULL DEFAULT \'never\' AFTER plug_code,
										ADD COLUMN plug_version         VARCHAR(42) NOT NULL default \'0\' AFTER plug_apply_rendering,
										ADD COLUMN plug_status          ENUM( \'enabled\', \'disabled\', \'needs_config\', \'broken\' ) NOT NULL AFTER plug_version,
										ADD COLUMN plug_spam_weight     TINYINT UNSIGNED NOT NULL DEFAULT 1 AFTER plug_status');
        $DB->query('ALTER TABLE T_plugins
										ADD UNIQUE plug_code( plug_code ),
										ADD INDEX plug_status( plug_status )');
        task_end();
        task_begin('Creating plugin settings table... ');
        $DB->query('CREATE TABLE T_pluginsettings (
															pset_plug_ID INT(11) UNSIGNED NOT NULL,
															pset_name VARCHAR( 30 ) NOT NULL,
															pset_value TEXT NULL,
															PRIMARY KEY ( pset_plug_ID, pset_name )
											)');
        task_end();
        task_begin('Creating plugin user settings table... ');
        $DB->query('CREATE TABLE T_pluginusersettings (
															puset_plug_ID INT(11) UNSIGNED NOT NULL,
															puset_user_ID INT(11) UNSIGNED NOT NULL,
															puset_name VARCHAR( 30 ) NOT NULL,
															puset_value TEXT NULL,
															PRIMARY KEY ( puset_plug_ID, puset_user_ID, puset_name )
											)');
        task_end();
        task_begin('Creating scheduled tasks table... ');
        $DB->query('CREATE TABLE T_cron__task(
												 ctsk_ID              int(10) unsigned      not null AUTO_INCREMENT,
												 ctsk_start_datetime  datetime              not null,
												 ctsk_repeat_after    int(10) unsigned,
												 ctsk_name            varchar(50)           not null,
												 ctsk_controller      varchar(50)           not null,
												 ctsk_params          text,
												 primary key (ctsk_ID)
											)');
        task_end();
        task_begin('Creating cron log table... ');
        $DB->query('CREATE TABLE T_cron__log(
															 clog_ctsk_ID              int(10) unsigned   not null,
															 clog_realstart_datetime   datetime           not null,
															 clog_realstop_datetime    datetime,
															 clog_status               enum(\'started\',\'finished\',\'error\',\'timeout\') not null default \'started\',
															 clog_messages             text,
															 primary key (clog_ctsk_ID)
											)');
        task_end();
        task_begin('Upgrading blogs table... ');
        // blog_allowpingbacks is "DEFAULT 1" in the 0.9.0.11 dump.. - changed in 0.9.2?!
        $DB->query('ALTER TABLE T_blogs
										ALTER COLUMN blog_allowpingbacks SET DEFAULT 0,
    								CHANGE COLUMN blog_media_subdir blog_media_subdir VARCHAR( 255 ) NULL,
										CHANGE COLUMN blog_media_fullpath blog_media_fullpath VARCHAR( 255 ) NULL,
										CHANGE COLUMN blog_media_url blog_media_url VARCHAR( 255 ) NULL');
        task_end();
        set_upgrade_checkpoint('9200');
        // at 1.8 "Summer Beta" release
    }
    // ____________________________ 1.9: ____________________________
    if ($old_db_version < 9290) {
        echo 'Post-fix hit_referer_type == NULL... ';
        // If you've upgraded from 1.6 to 1.8 and it did not break because of strict mode, there are now NULL values for what "spam" was:
        $DB->query('
					DELETE FROM T_hitlog
					 WHERE hit_referer_type IS NULL');
        echo "OK.<br />\n";
        echo 'Marking administrator accounts as validated... ';
        $DB->query('
				UPDATE T_users
				   SET user_validated = 1
				 WHERE user_grp_ID = 1');
        echo "OK.<br />\n";
        echo 'Converting auto_prune_stats setting... ';
        $old_auto_prune_stats = $DB->get_var('
				SELECT set_value
				  FROM T_settings
				 WHERE set_name = "auto_prune_stats"');
        if (!is_null($old_auto_prune_stats) && $old_auto_prune_stats < 1) {
            // This means it has been disabled before, so set auto_prune_stats_mode to "off"!
            $DB->query('
					REPLACE INTO T_settings ( set_name, set_value )
					 VALUES ( "auto_prune_stats_mode", "off" )');
        }
        echo "OK.<br />\n";
        echo 'Converting time_difference from hours to seconds... ';
        $DB->query('UPDATE T_settings SET set_value = set_value*3600 WHERE set_name = "time_difference"');
        echo "OK.<br />\n";
        echo 'Updating hitlog capabilities... ';
        $DB->query('
				ALTER TABLE ' . $tableprefix . 'useragents ADD INDEX agnt_type ( agnt_type )');
        $DB->query('
				ALTER TABLE T_hitlog
				  CHANGE COLUMN hit_referer_type hit_referer_type ENUM(\'search\',\'blacklist\',\'referer\',\'direct\',\'self\',\'admin\') NOT NULL');
        echo "OK.<br />\n";
        echo 'Updating plugin capabilities... ';
        $DB->query('
				ALTER TABLE T_plugins
					MODIFY COLUMN plug_status ENUM( \'enabled\', \'disabled\', \'needs_config\', \'broken\' ) NOT NULL');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9290');
    }
    if ($old_db_version < 9300) {
        // This can be so long, it needs its own checkpoint protected block in case of failure
        echo 'Updating hitlog indexes... ';
        $DB->query('
				ALTER TABLE T_hitlog
				  ADD INDEX hit_agnt_ID        ( hit_agnt_ID ),
				  ADD INDEX hit_uri            ( hit_uri ),
				  ADD INDEX hit_referer_dom_ID ( hit_referer_dom_ID )
				');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9300');
    }
    if ($old_db_version < 9310) {
        echo 'Updating basedomains... ';
        $DB->query('
				UPDATE T_basedomains
				   SET dom_status = "unknown"');
        // someone has filled this up with junk blacklists before
        $DB->query('
				ALTER TABLE T_basedomains  ADD INDEX dom_type (dom_type)');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9310');
    }
    if ($old_db_version < 9315) {
        echo 'Altering locales table... ';
        $DB->query("ALTER TABLE T_locales CHANGE COLUMN loc_datefmt loc_datefmt varchar(20) NOT NULL default 'y-m-d'");
        $DB->query("ALTER TABLE T_locales CHANGE COLUMN loc_timefmt loc_timefmt varchar(20) NOT NULL default 'H:i:s'");
        echo "OK.<br />\n";
        echo 'Creating item prerendering cache table... ';
        $DB->query("\n\t\t\t\tCREATE TABLE {$tableprefix}item__prerendering(\n\t\t\t\t\titpr_itm_ID                   INT(11) UNSIGNED NOT NULL,\n\t\t\t\t\titpr_format                   ENUM('htmlbody', 'entityencoded', 'xml', 'text') NOT NULL,\n\t\t\t\t\titpr_renderers                TEXT NOT NULL,\n\t\t\t\t\titpr_content_prerendered      TEXT NULL,\n\t\t\t\t\titpr_datemodified             TIMESTAMP NOT NULL,\n\t\t\t\t\tPRIMARY KEY (itpr_itm_ID, itpr_format)\n\t\t\t\t)");
        echo "OK.<br />\n";
        echo 'Altering plugins table... ';
        $DB->query("ALTER TABLE T_plugins ADD COLUMN plug_name            VARCHAR(255) NULL default NULL AFTER plug_version");
        $DB->query("ALTER TABLE T_plugins ADD COLUMN plug_shortdesc       VARCHAR(255) NULL default NULL AFTER plug_name");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9315');
    }
    if ($old_db_version < 9320) {
        // Dropping hit_datetime because it's very slow on INSERT (dh)
        // This can be so long, it needs its own checkpoint protected block in case of failure
        if (db_index_exists('T_hitlog', 'hit_datetime')) {
            // only drop, if it still exists (may have been removed manually)
            echo 'Updating hitlog indexes... ';
            $DB->query('
					ALTER TABLE T_hitlog
						DROP INDEX hit_datetime
					');
            echo "OK.<br />\n";
        }
        set_upgrade_checkpoint('9320');
    }
    if ($old_db_version < 9326) {
        echo 'Removing obsolete settings... ';
        $DB->query('DELETE FROM T_settings WHERE set_name = "upload_allowedext"');
        echo "OK.<br />\n";
        echo 'Updating blogs... ';
        db_drop_col('T_blogs', 'blog_allowpingbacks');
        // Remove and transform obsolete fields blog_pingb2evonet, blog_pingtechnorati, blog_pingweblogs, blog_pingblodotgs
        if (db_cols_exist('T_blogs', array('blog_pingb2evonet', 'blog_pingtechnorati', 'blog_pingweblogs', 'blog_pingblodotgs'))) {
            foreach ($DB->get_results('
					SELECT blog_ID, blog_pingb2evonet, blog_pingtechnorati, blog_pingweblogs, blog_pingblodotgs
						FROM T_blogs') as $row) {
                $ping_plugins = $DB->get_var('SELECT cset_value FROM T_coll_settings WHERE cset_coll_ID = ' . $row->blog_ID . ' AND cset_name = "ping_plugins"');
                $ping_plugins = explode(',', $ping_plugins);
                if ($row->blog_pingb2evonet) {
                    $ping_plugins[] = 'ping_b2evonet';
                }
                if ($row->blog_pingtechnorati || $row->blog_pingweblogs || $row->blog_pingblodotgs) {
                    // if either one of the previous pingers was enabled, add ping-o-matic:
                    $ping_plugins[] = 'ping_pingomatic';
                }
                // Insert transformed/generated ping plugins collection setting:
                $ping_plugins = array_unique($ping_plugins);
                $DB->query('REPLACE INTO T_coll_settings
						( cset_coll_ID, cset_name, cset_value )
						VALUES ( ' . $row->blog_ID . ', "ping_plugins", "' . implode(',', $ping_plugins) . '" )');
            }
            $DB->query('ALTER TABLE T_blogs
					DROP COLUMN blog_pingb2evonet,
					DROP COLUMN blog_pingtechnorati,
					DROP COLUMN blog_pingweblogs,
					DROP COLUMN blog_pingblodotgs');
        }
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9326');
    }
    if ($old_db_version < 9328) {
        echo 'Updating posts... ';
        db_add_col("{$tableprefix}posts", 'post_notifications_status', 'ENUM("noreq","todo","started","finished") NOT NULL DEFAULT "noreq" AFTER post_flags');
        db_add_col("{$tableprefix}posts", 'post_notifications_ctsk_ID', 'INT(10) unsigned NULL DEFAULT NULL AFTER post_notifications_status');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9328');
    }
    if ($old_db_version < 9330) {
        if (db_col_exists("{$tableprefix}posts", 'post_flags')) {
            echo 'Updating post notifications... ';
            $DB->query("\n\t\t\t\tUPDATE {$tableprefix}posts\n\t\t\t\t\t SET post_notifications_status = 'finished'\n\t\t\t\t WHERE post_flags LIKE '%pingsdone%'");
            db_drop_col("{$tableprefix}posts", 'post_flags');
            echo "OK.<br />\n";
        }
        set_upgrade_checkpoint('9330');
    }
    if ($old_db_version < 9340) {
        echo 'Removing duplicate post link indexes... ';
        if (db_index_exists('T_links', 'link_item_ID')) {
            // only drop, if it still exists (may have been removed manually)
            $DB->query('
					ALTER TABLE T_links
						DROP INDEX link_item_ID
					');
        }
        if (db_index_exists('T_links', 'link_dest_item_ID')) {
            // only drop, if it still exists (may have been removed manually)
            $DB->query('
					ALTER TABLE T_links
						DROP INDEX link_dest_item_ID
					');
        }
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9340');
    }
    // ____________________________ 1.10: ____________________________
    if ($old_db_version < 9345) {
        echo 'Updating post table... ';
        $DB->query("ALTER TABLE {$tableprefix}posts CHANGE COLUMN post_content post_content MEDIUMTEXT NULL");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9345');
    }
    if ($old_db_version < 9346) {
        echo 'Updating prerendering table... ';
        $DB->query("ALTER TABLE {$tableprefix}item__prerendering CHANGE COLUMN itpr_content_prerendered itpr_content_prerendered MEDIUMTEXT NULL");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9346');
    }
    if ($old_db_version < 9348) {
        echo 'Updating sessions table... ';
        $DB->query('ALTER TABLE T_sessions CHANGE COLUMN sess_data sess_data MEDIUMBLOB DEFAULT NULL');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9348');
    }
    if ($old_db_version < 9350) {
        echo 'Updating hitlog table... ';
        $DB->query('ALTER TABLE T_hitlog CHANGE COLUMN hit_referer_type hit_referer_type   ENUM(\'search\',\'blacklist\',\'spam\',\'referer\',\'direct\',\'self\',\'admin\') NOT NULL');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9350');
    }
    // TODO: "If a user has permission to edit a blog, he should be able to put files in the media folder for that blog." - see http://forums.b2evolution.net/viewtopic.php?p=36417#36417
    /*
    // blueyed>> I've came up with the following, but it's too generic IMHO
    if( $old_db_version < 9300 )
    {
    	echo 'Setting automatic media perms on blogs (members can upload)... ';
    	$users = $DB->query( '
    			UPDATE T_users
    			   SET bloguser_perm_media_upload = 1
    			 WHERE bloguser_ismember = 1' );
    	echo "OK.<br />\n";
    }
    */
    // ____________________________ 2.0: ____________________________
    if ($old_db_version < 9406) {
        echo 'Updating chapter url names... ';
        $DB->query('
			ALTER TABLE T_categories
				ADD COLUMN cat_urlname VARCHAR(255) NOT NULL');
        // Create cat_urlname from cat_name:
        // TODO: Also use it for cafelog upgrade.
        load_funcs('locales/_charset.funcs.php');
        foreach ($DB->get_results('SELECT cat_ID, cat_name FROM T_categories') as $cat) {
            $cat_name = trim($cat->cat_name);
            if (strlen($cat_name)) {
                // TODO: dh> pass locale (useful for transliteration). From main blog?
                $cat_urlname = urltitle_validate('', $cat_name, $cat->cat_ID, false, 'cat_urlname', 'cat_ID', 'T_categories');
            } else {
                $cat_urlname = 'c' . $cat->cat_ID;
            }
            $DB->query('
				UPDATE T_categories
					 SET cat_urlname = ' . $DB->quote($cat_urlname) . '
				 WHERE cat_ID = ' . $cat->cat_ID);
        }
        $DB->query('
			ALTER TABLE T_categories
				ADD UNIQUE cat_urlname ( cat_urlname )');
        echo "OK.<br />\n";
        echo 'Updating Settings... ';
        $DB->query('
      UPDATE T_settings
         SET set_value = "disabled"
       WHERE set_name = "links_extrapath"
         AND set_value = 0');
        $DB->query('
      UPDATE T_settings
         SET set_value = "ymd"
       WHERE set_name = "links_extrapath"
         AND set_value <> 0');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9406');
    }
    if ($old_db_version < 9407) {
        echo 'Moving general settings to blog settings... ';
        $DB->query('REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
		             SELECT blog_ID, set_name, set_value
									 FROM T_blogs, T_settings
									WHERE set_name = "posts_per_page"
									   OR set_name = "what_to_show"
									   OR set_name = "archive_mode"');
        $DB->query('DELETE FROM T_settings
									WHERE set_name = "posts_per_page"
									   OR set_name = "what_to_show"
									   OR set_name = "archive_mode"');
        echo "OK.<br />\n";
        echo 'Upgrading blogs table... ';
        $query = "ALTER TABLE T_blogs\n\t\t\t\t\t\t\tDROP COLUMN blog_force_skin";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading groups table... ';
        $query = "ALTER TABLE T_groups\n\t\t\t\t\t\t\tCHANGE COLUMN grp_perm_files grp_perm_files enum('none','view','add','edit','all') NOT NULL default 'none'";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading files table... ';
        $query = "ALTER TABLE T_files\n\t\t\t\t\t\t\tCHANGE COLUMN file_root_type file_root_type enum('absolute','user','group','collection','skins') not null default 'absolute'";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Updating file types... ';
        // Only change this if it's close enough to a default install (non customized)
        $DB->query("UPDATE T_filetypes\n\t\t\t\t\t\t\t\t\t\tSET ftyp_viewtype = 'text'\n\t\t\t\t\t\t\t\t\tWHERE ftyp_ID = 12\n\t\t\t\t\t\t\t\t\t\tAND ftyp_extensions = 'php php3 php4 php5 php6'\n\t\t\t\t\t\t\t\t\t\tAND ftyp_mimetype ='application/x-httpd-php'\n\t\t\t\t\t\t\t\t\t\tAND ftyp_icon = 'php.gif'");
        echo "OK.<br />\n";
        echo 'Remove obsolete user settings... ';
        $DB->query('DELETE FROM ' . $tableprefix . 'usersettings
									WHERE uset_name = "plugins_disp_avail"');
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9407');
    }
    if ($old_db_version < 9408) {
        echo 'Creating skins table... ';
        $DB->query('CREATE TABLE T_skins__skin (
              skin_ID      int(10) unsigned      NOT NULL auto_increment,
              skin_name    varchar(32)           NOT NULL,
              skin_type    enum(\'normal\',\'feed\') NOT NULL default \'normal\',
              skin_folder  varchar(32)           NOT NULL,
              PRIMARY KEY skin_ID (skin_ID),
              UNIQUE skin_folder( skin_folder ),
              KEY skin_name( skin_name )
            )');
        echo "OK.<br />\n";
        echo 'Creating skin containers table... ';
        $DB->query('CREATE TABLE T_skins__container (
              sco_skin_ID   int(10) unsigned      NOT NULL,
              sco_name      varchar(40)           NOT NULL,
              PRIMARY KEY (sco_skin_ID, sco_name)
            )');
        echo "OK.<br />\n";
        echo 'Creating widgets table... ';
        $DB->query('CREATE TABLE T_widget (
 						wi_ID					INT(10) UNSIGNED auto_increment,
						wi_coll_ID    INT(11) UNSIGNED NOT NULL,
						wi_sco_name   VARCHAR( 40 ) NOT NULL,
						wi_order			INT(10) UNSIGNED NOT NULL,
						wi_type       ENUM( \'core\', \'plugin\' ) NOT NULL DEFAULT \'core\',
						wi_code       VARCHAR(32) NOT NULL,
						wi_params     TEXT NULL,
						PRIMARY KEY ( wi_ID ),
						UNIQUE wi_order( wi_coll_ID, wi_sco_name, wi_order )
          )');
        echo "OK.<br />\n";
        install_basic_skins(false);
        echo 'Updating blogs table... ';
        $DB->query('ALTER TABLE T_blogs
								 ALTER COLUMN blog_allowtrackbacks SET DEFAULT 0,
									DROP COLUMN blog_default_skin,
									 ADD COLUMN blog_owner_user_ID   int(11) unsigned NOT NULL default 1 AFTER blog_name,
									 ADD COLUMN blog_skin_ID INT(10) UNSIGNED NOT NULL DEFAULT 1 AFTER blog_allowusercss');
        echo "OK.<br />\n";
        install_basic_widgets($old_db_version);
        set_upgrade_checkpoint('9408');
    }
    if ($old_db_version < 9409) {
        // Upgrade the blog access types:
        echo 'Updating blogs access types... ';
        $DB->query('UPDATE T_blogs
										SET blog_access_type = "absolute"
									WHERE blog_siteurl LIKE "http://%"
									   OR blog_siteurl LIKE "https://%"');
        $DB->query('UPDATE T_blogs
										SET blog_access_type = "relative",
												blog_siteurl = CONCAT( blog_siteurl, blog_stub )
									WHERE blog_access_type = "stub"');
        db_drop_col('T_blogs', 'blog_stub');
        echo "OK.<br />\n";
        echo 'Updating columns... ';
        $DB->query("ALTER TABLE T_groups CHANGE COLUMN grp_perm_stats grp_perm_stats enum('none','user','view','edit') NOT NULL default 'none'");
        $DB->query("ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_poststatuses bloguser_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default ''");
        $DB->query("ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_poststatuses bloggroup_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default ''");
        $DB->query("ALTER TABLE {$tableprefix}posts CHANGE COLUMN post_status post_status enum('published','deprecated','protected','private','draft','redirected') NOT NULL default 'published'");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9409');
    }
    if ($old_db_version < 9410) {
        echo 'Updating columns... ';
        $DB->query("ALTER TABLE T_comments CHANGE COLUMN comment_status comment_status ENUM('published','deprecated','protected','private','draft','redirected') DEFAULT 'published' NOT NULL");
        $DB->query("ALTER TABLE T_sessions CHANGE COLUMN sess_data sess_data MEDIUMBLOB DEFAULT NULL");
        $DB->query("ALTER TABLE T_hitlog CHANGE COLUMN hit_referer_type hit_referer_type ENUM('search','blacklist','spam','referer','direct','self','admin') NOT NULL");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9410');
    }
    if ($old_db_version < 9411) {
        echo 'Adding default Post Types... ';
        $DB->query("\n\t\t\tREPLACE INTO {$tableprefix}posttypes ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 1000, 'Page' ),\n\t\t\t\t\t\t ( 2000, 'Reserved' ),\n\t\t\t\t\t\t ( 3000, 'Reserved' ),\n\t\t\t\t\t\t ( 4000, 'Reserved' ),\n\t\t\t\t\t\t ( 5000, 'Reserved' ) ");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9411');
    }
    if ($old_db_version < 9412) {
        echo 'Adding field for post excerpts... ';
        $DB->query("ALTER TABLE {$tableprefix}posts ADD COLUMN post_excerpt  text NULL AFTER post_content");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9412');
    }
    if ($old_db_version < 9414) {
        echo "Renaming tables...";
        $DB->query("RENAME TABLE {$tableprefix}item__prerendering TO T_items__prerendering");
        $DB->query("RENAME TABLE {$tableprefix}poststatuses TO T_items__status");
        $DB->query("RENAME TABLE {$tableprefix}posttypes TO T_items__type");
        $DB->query("RENAME TABLE {$tableprefix}posts TO T_items__item");
        echo "OK.<br />\n";
        echo "Creating Tag tables...";
        $DB->query("CREATE TABLE T_items__tag (\n\t\t      tag_ID   int(11) unsigned not null AUTO_INCREMENT,\n\t\t      tag_name varchar(50) not null,\n\t\t      primary key (tag_ID),\n\t\t      UNIQUE tag_name( tag_name )\n\t\t    )");
        $DB->query("CREATE TABLE T_items__itemtag (\n\t\t      itag_itm_ID int(11) unsigned NOT NULL,\n\t\t      itag_tag_ID int(11) unsigned NOT NULL,\n\t\t      PRIMARY KEY (itag_itm_ID, itag_tag_ID),\n\t\t      UNIQUE tagitem ( itag_tag_ID, itag_itm_ID )\n\t\t    )");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9414');
    }
    if ($old_db_version < 9416) {
        echo "Updating blogs table...";
        $DB->query("ALTER TABLE T_blogs\n\t\t\t\t\t\t\t\t\tADD COLUMN blog_advanced_perms  TINYINT(1) NOT NULL default 0 AFTER blog_owner_user_ID,\n\t\t\t\t\t\t\t\t\tDROP COLUMN blog_staticfilename");
        $DB->query("UPDATE T_blogs\n\t\t\t\t\t\t\t\t\t  SET blog_advanced_perms = 1");
        echo "OK.<br />\n";
        echo "Additionnal blog permissions...";
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\t\t\t\t\t\t\tADD COLUMN bloguser_perm_admin tinyint NOT NULL default 0 AFTER bloguser_perm_properties,\n\t\t\t\t\t\t\t\t\tADD COLUMN bloguser_perm_edit  ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no' AFTER bloguser_perm_poststatuses");
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\t\t\t\t\t\t\tADD COLUMN bloggroup_perm_admin tinyint NOT NULL default 0 AFTER bloggroup_perm_properties,\n\t\t\t\t\t\t\t\t\tADD COLUMN bloggroup_perm_edit  ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no' AFTER bloggroup_perm_poststatuses");
        // Preserve full admin perms:
        $DB->query("UPDATE T_coll_user_perms\n\t\t\t\t\t\t\t\t\t\tSET bloguser_perm_admin = 1\n\t\t\t\t\t\t\t\t\tWHERE bloguser_perm_properties <> 0");
        $DB->query("UPDATE T_coll_group_perms\n\t\t\t\t\t\t\t\t\t\tSET bloggroup_perm_admin = 1\n\t\t\t\t\t\t\t\t\tWHERE bloggroup_perm_properties <> 0");
        // Preserve full edit perms:
        $DB->query("UPDATE T_coll_user_perms\n\t\t\t\t\t\t\t\t\t\tSET bloguser_perm_edit = 'all'");
        $DB->query("UPDATE T_coll_group_perms\n\t\t\t\t\t\t\t\t\t\tSET bloggroup_perm_edit = 'all'");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9416');
    }
    if ($old_db_version < 9500) {
        task_begin('Normalizing columns...');
        $DB->query('ALTER TABLE T_blogs
										ALTER COLUMN blog_shortname SET DEFAULT \'\',
										ALTER COLUMN blog_tagline SET DEFAULT \'\',
										CHANGE COLUMN blog_description blog_description     varchar(250) NULL default \'\',
										ALTER COLUMN blog_siteurl SET DEFAULT \'\'');
        task_end();
        task_begin('Normalizing dates...');
        $DB->query('UPDATE T_users
										SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE dateYMDhour = \'0000-00-00 00:00:00\'');
        $DB->query('ALTER TABLE T_users
									MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('UPDATE T_comments
										SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'');
        $DB->query('ALTER TABLE T_comments
									MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        task_end();
        task_begin('Normalizing cron jobs...');
        $DB->query('UPDATE T_cron__task
										SET ctsk_controller = REPLACE(ctsk_controller, "cron/_", "cron/jobs/_" )
									WHERE ctsk_controller LIKE "cron/_%"');
        task_end();
        task_begin('Extending comments table...');
        $DB->query('ALTER TABLE T_comments
									ADD COLUMN comment_rating     TINYINT(1) NULL DEFAULT NULL AFTER comment_content,
									ADD COLUMN comment_featured   TINYINT(1) NOT NULL DEFAULT 0 AFTER comment_rating,
									ADD COLUMN comment_nofollow   TINYINT(1) NOT NULL DEFAULT 1 AFTER comment_featured;');
        task_end();
        set_upgrade_checkpoint('9500');
    }
    if ($old_db_version < 9600) {
        // 2.2.0
        task_begin('Creating global cache table...');
        $DB->query('CREATE TABLE T_global__cache (
							      cach_name VARCHAR( 30 ) NOT NULL ,
							      cach_cache MEDIUMBLOB NULL ,
							      PRIMARY KEY ( cach_name )
							    )');
        task_end();
        task_begin('Altering posts table...');
        $DB->query('ALTER TABLE T_items__item
										MODIFY COLUMN post_datestart DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
										MODIFY COLUMN post_datemodified DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
										ADD COLUMN post_order    float NULL AFTER post_priority,
										ADD COLUMN post_featured tinyint(1) NOT NULL DEFAULT 0 AFTER post_order');
        $DB->query('ALTER TABLE T_items__item
										ADD INDEX post_order( post_order )');
        task_end();
        set_upgrade_checkpoint('9600');
    }
    if ($old_db_version < 9700) {
        // 2.3.2
        echo 'Creating PodCast Post Type... ';
        $DB->query("\n\t\t\tREPLACE INTO T_items__type ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 2000, 'Podcast' )");
        echo "OK.<br />\n";
        // 2.4.0
        echo 'Adding additional group permissions... ';
        $DB->query("\n\t      ALTER TABLE T_groups\n\t\t\t\t\tADD COLUMN grp_perm_bypass_antispam         TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_blogs,\n\t\t\t\t\tADD COLUMN grp_perm_xhtmlvalidation         VARCHAR(10) NOT NULL default 'always' AFTER grp_perm_bypass_antispam,\n\t\t\t\t\tADD COLUMN grp_perm_xhtmlvalidation_xmlrpc  VARCHAR(10) NOT NULL default 'always' AFTER grp_perm_xhtmlvalidation,\n\t\t\t\t\tADD COLUMN grp_perm_xhtml_css_tweaks        TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtmlvalidation_xmlrpc,\n      \t\tADD COLUMN grp_perm_xhtml_iframes           TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_css_tweaks,\n      \t\tADD COLUMN grp_perm_xhtml_javascript        TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_iframes,\n\t\t\t\t\tADD COLUMN grp_perm_xhtml_objects           TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_javascript ");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9700');
    }
    if ($old_db_version < 9800) {
        // 2.5.0
        echo 'Upgrading blogs table... ';
        db_drop_col('T_blogs', 'blog_commentsexpire');
        echo "OK.<br />\n";
        echo 'Upgrading items table... ';
        $DB->query("ALTER TABLE T_items__item\n\t\t\tCHANGE COLUMN post_urltitle post_urltitle VARCHAR(210) NULL DEFAULT NULL,\n\t\t\tCHANGE COLUMN post_order    post_order DOUBLE NULL,\n\t\t\tADD COLUMN post_titletag  VARCHAR(255) NULL DEFAULT NULL AFTER post_urltitle,\n\t\t\tADD COLUMN post_double1   DOUBLE NULL COMMENT 'Custom double value 1' AFTER post_priority,\n\t\t\tADD COLUMN post_double2   DOUBLE NULL COMMENT 'Custom double value 2' AFTER post_double1,\n\t\t\tADD COLUMN post_double3   DOUBLE NULL COMMENT 'Custom double value 3' AFTER post_double2,\n\t\t\tADD COLUMN post_double4   DOUBLE NULL COMMENT 'Custom double value 4' AFTER post_double3,\n\t\t\tADD COLUMN post_double5   DOUBLE NULL COMMENT 'Custom double value 5' AFTER post_double4,\n\t\t\tADD COLUMN post_varchar1  VARCHAR(255) NULL COMMENT 'Custom varchar value 1' AFTER post_double5,\n\t\t\tADD COLUMN post_varchar2  VARCHAR(255) NULL COMMENT 'Custom varchar value 2' AFTER post_varchar1,\n\t\t\tADD COLUMN post_varchar3  VARCHAR(255) NULL COMMENT 'Custom varchar value 3' AFTER post_varchar2");
        echo "OK.<br />\n";
        echo 'Creating keyphrase table... ';
        $query = "CREATE TABLE T_track__keyphrase (\n            keyp_ID      INT UNSIGNED NOT NULL AUTO_INCREMENT,\n            keyp_phrase  VARCHAR( 255 ) NOT NULL,\n            PRIMARY KEY        ( keyp_ID ),\n            UNIQUE keyp_phrase ( keyp_phrase )\n          )";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading hitlog table... ';
        evo_flush();
        $query = "ALTER TABLE T_hitlog\n\t\t\t CHANGE COLUMN hit_ID hit_ID              INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\t CHANGE COLUMN hit_datetime hit_datetime  DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',\n\t\t\t ADD COLUMN hit_keyphrase_keyp_ID         INT UNSIGNED DEFAULT NULL AFTER hit_referer_dom_ID,\n\t\t\t ADD INDEX hit_remote_addr ( hit_remote_addr ),\n\t\t\t ADD INDEX hit_sess_ID        ( hit_sess_ID )";
        $DB->query($query);
        echo "OK.<br />\n";
        echo 'Upgrading sessions table... ';
        $DB->query("ALTER TABLE T_sessions\n\t\t\tALTER COLUMN sess_lastseen SET DEFAULT '2000-01-01 00:00:00',\n\t\t\tADD COLUMN sess_hitcount  INT(10) UNSIGNED NOT NULL DEFAULT 1 AFTER sess_key,\n\t\t\tADD KEY sess_user_ID (sess_user_ID)");
        echo "OK.<br />\n";
        echo 'Creating goal tracking table... ';
        $DB->query("CREATE TABLE T_track__goal(\n\t\t\t\t\t  goal_ID int(10) unsigned NOT NULL auto_increment,\n\t\t\t\t\t  goal_name varchar(50) default NULL,\n\t\t\t\t\t  goal_key varchar(32) default NULL,\n\t\t\t\t\t  goal_redir_url varchar(255) default NULL,\n\t\t\t\t\t  goal_default_value double default NULL,\n\t\t\t\t\t  PRIMARY KEY (goal_ID),\n\t\t\t\t\t  UNIQUE KEY goal_key (goal_key)\n          )");
        $DB->query("CREATE TABLE T_track__goalhit (\n\t\t\t\t\t  ghit_ID int(10) unsigned NOT NULL auto_increment,\n\t\t\t\t\t  ghit_goal_ID    int(10) unsigned NOT NULL,\n\t\t\t\t\t  ghit_hit_ID     int(10) unsigned NOT NULL,\n\t\t\t\t\t  ghit_params     TEXT default NULL,\n\t\t\t\t\t  PRIMARY KEY  (ghit_ID),\n\t\t\t\t\t  KEY ghit_goal_ID (ghit_goal_ID),\n\t\t\t\t\t  KEY ghit_hit_ID (ghit_hit_ID)\n         )");
        echo "OK.<br />\n";
        set_upgrade_checkpoint('9800');
    }
    if ($old_db_version < 9900) {
        // 3.0 part 1
        task_begin('Updating keyphrases in hitlog table... ');
        load_class('sessions/model/_hit.class.php', 'Hit');
        // New Hit object creation was added later, to fix upgrades from very old versions.
        // We create a new temp Hit object to be able to call the Hit::extract_params_from_referer() function which was static when this upgrade block was created.
        $tempHit = new Hit();
        $sql = 'SELECT SQL_NO_CACHE hit_ID, hit_referer
  		          FROM T_hitlog
   		         WHERE hit_referer_type = "search"
		           AND hit_keyphrase_keyp_ID IS NULL';
        // this line just in case we crashed in the middle, so we restart where we stopped
        $rows = $DB->get_results($sql, OBJECT, 'get all search hits');
        foreach ($rows as $row) {
            $params = $tempHit->extract_params_from_referer($row->hit_referer);
            if (empty($params['keyphrase'])) {
                continue;
            }
            $DB->begin();
            $sql = 'SELECT keyp_ID
			          FROM T_track__keyphrase
			         WHERE keyp_phrase = ' . $DB->quote($params['keyphrase']);
            $keyp_ID = $DB->get_var($sql, 0, 0, 'Get keyphrase ID');
            if (empty($keyp_ID)) {
                $sql = 'INSERT INTO T_track__keyphrase( keyp_phrase )
				        VALUES (' . $DB->quote($params['keyphrase']) . ')';
                $DB->query($sql, 'Add new keyphrase');
                $keyp_ID = $DB->insert_id;
            }
            $DB->query('UPDATE T_hitlog
			                SET hit_keyphrase_keyp_ID = ' . $keyp_ID . '
			              WHERE hit_ID = ' . $row->hit_ID, 'Update hit');
            $DB->commit();
            echo ". \n";
        }
        task_end();
        task_begin('Upgrading widgets table... ');
        $DB->query("ALTER TABLE T_widget\n\t\t\tCHANGE COLUMN wi_order wi_order INT(10) NOT NULL");
        task_end();
        task_begin('Upgrading Files table... ');
        $DB->query("ALTER TABLE T_files\n\t\t\t\t\t\t\t\tCHANGE COLUMN file_root_type file_root_type enum('absolute','user','collection','shared','skins') not null default 'absolute'");
        task_end();
        set_upgrade_checkpoint('9900');
    }
    if ($old_db_version < 9910) {
        // 3.0 part 2
        task_begin('Upgrading Blogs table... ');
        $DB->query("ALTER TABLE T_blogs CHANGE COLUMN blog_name blog_name varchar(255) NOT NULL default ''");
        task_end();
        task_begin('Adding new Post Types...');
        $DB->query("\n\t\t\tREPLACE INTO T_items__type( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 1500, 'Intro-Main' ),\n\t\t\t\t\t\t ( 1520, 'Intro-Cat' ),\n\t\t\t\t\t\t ( 1530, 'Intro-Tag' ),\n\t\t\t\t\t\t ( 1570, 'Intro-Sub' ),\n\t\t\t\t\t\t ( 1600, 'Intro-All' ) ");
        task_end();
        task_begin('Updating User table');
        $DB->query("ALTER TABLE T_users\n\t\t\t\t\t\t\t\t\tADD COLUMN user_avatar_file_ID int(10) unsigned default NULL AFTER user_validated");
        task_end();
        task_begin('Creating table for User field definitions');
        $DB->query("CREATE TABLE T_users__fielddefs (\n\t\t\t\tufdf_ID int(10) unsigned NOT NULL,\n\t\t\t\tufdf_type char(8) NOT NULL,\n\t\t\t\tufdf_name varchar(255) collate latin1_general_ci NOT NULL,\n\t\t\t\tPRIMARY KEY  (ufdf_ID)\n\t\t\t)");
        task_end();
        task_begin('Creating default field definitions...');
        $DB->query("\n\t    INSERT INTO T_users__fielddefs (ufdf_ID, ufdf_type, ufdf_name)\n\t\t\t VALUES ( 10000, 'email',    'MSN/Live IM'),\n\t\t\t\t\t\t\t( 10100, 'word',     'Yahoo IM'),\n\t\t\t\t\t\t\t( 10200, 'word',     'AOL AIM'),\n\t\t\t\t\t\t\t( 10300, 'number',   'ICQ ID'),\n\t\t\t\t\t\t\t( 40000, 'phone',    'Skype'),\n\t\t\t\t\t\t\t( 50000, 'phone',    'Main phone'),\n\t\t\t\t\t\t\t( 50100, 'phone',    'Cell phone'),\n\t\t\t\t\t\t\t( 50200, 'phone',    'Office phone'),\n\t\t\t\t\t\t\t( 50300, 'phone',    'Home phone'),\n\t\t\t\t\t\t\t( 60000, 'phone',    'Office FAX'),\n\t\t\t\t\t\t\t( 60100, 'phone',    'Home FAX'),\n\t\t\t\t\t\t\t(100000, 'url',      'Website'),\n\t\t\t\t\t\t\t(100100, 'url',      'Blog'),\n\t\t\t\t\t\t\t(110000, 'url',      'Linkedin'),\n\t\t\t\t\t\t\t(120000, 'url',      'Twitter'),\n\t\t\t\t\t\t\t(130100, 'url',      'Facebook'),\n\t\t\t\t\t\t\t(130200, 'url',      'Myspace'),\n\t\t\t\t\t\t\t(140000, 'url',      'Flickr'),\n\t\t\t\t\t\t\t(150000, 'url',      'YouTube'),\n\t\t\t\t\t\t\t(160000, 'url',      'Digg'),\n\t\t\t\t\t\t\t(160100, 'url',      'StumbleUpon'),\n\t\t\t\t\t\t\t(200000, 'text',     'Role'),\n\t\t\t\t\t\t\t(200100, 'text',     'Company/Org.'),\n\t\t\t\t\t\t\t(200200, 'text',     'Division'),\n\t\t\t\t\t\t\t(211000, 'text',     'VAT ID'),\n\t\t\t\t\t\t\t(300000, 'text',     'Main address'),\n\t\t\t\t\t\t\t(300300, 'text',     'Home address');");
        task_end();
        task_begin('Creating table for User fields...');
        $DB->query("CREATE TABLE {$tableprefix}users_fields (\n\t\t\t\tuf_ID      int(10) unsigned NOT NULL auto_increment,\n\t\t\t  uf_user_ID int(10) unsigned NOT NULL,\n\t\t\t  uf_ufdf_ID int(10) unsigned NOT NULL,\n\t\t\t  uf_varchar varchar(255) NOT NULL,\n\t\t\t  PRIMARY KEY (uf_ID)\n\t\t\t)");
        task_end();
        set_upgrade_checkpoint('9910');
    }
    if ($old_db_version < 9920) {
        // 3.1
        task_begin('Upgrading Posts table... ');
        // This is for old posts that may have a post type of NULL which should never happen. ptyp 1 is for regular posts
        $DB->query("UPDATE T_items__item\n\t\t\t\t\t\t\t\t\t\tSET post_ptyp_ID = 1\n\t\t\t\t\t\t\t\t\tWHERE post_ptyp_ID IS NULL");
        $DB->query("ALTER TABLE T_items__item\n\t\t\t\t\t\t\tCHANGE COLUMN post_ptyp_ID post_ptyp_ID int(10) unsigned NOT NULL DEFAULT 1");
        task_end();
        task_begin('Upgrading Categories table... ');
        $DB->query("ALTER TABLE T_categories\n\t\t\tCHANGE COLUMN cat_name cat_name varchar(255) NOT NULL,\n\t\t\tCHANGE COLUMN cat_description cat_description varchar(255) NULL DEFAULT NULL");
        db_add_col('T_categories', 'cat_order', 'int(11) NULL DEFAULT NULL AFTER cat_description');
        db_add_index('T_categories', 'cat_order', 'cat_order');
        $DB->query("UPDATE T_categories\n\t\t\t\t\tSET cat_order = cat_ID");
        task_end();
        task_begin('Upgrading widgets table... ');
        db_add_col('T_widget', 'wi_enabled', 'tinyint(1) NOT NULL DEFAULT 1 AFTER wi_order');
        task_end();
    }
    if ($old_db_version < 9930) {
        // 3.1 continued
        task_begin('Updating Post Types...');
        $DB->query("\n\t\t\tREPLACE INTO T_items__type ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 3000, 'Sidebar link' )");
        echo "OK.<br />\n";
        task_end();
        task_begin('Updating items table...');
        $DB->query("ALTER TABLE T_items__item ENGINE=innodb");
        // fp> hum... this originally was a test :)
        task_end();
        task_begin('Creating versions table...');
        $DB->query("CREATE TABLE T_items__version (\n\t            iver_itm_ID        INT UNSIGNED NOT NULL ,\n\t            iver_edit_user_ID  INT UNSIGNED NOT NULL ,\n\t            iver_edit_datetime DATETIME NOT NULL ,\n\t            iver_status        ENUM('published','deprecated','protected','private','draft','redirected') NULL ,\n\t            iver_title         TEXT NULL ,\n\t            iver_content       MEDIUMTEXT NULL ,\n\t            INDEX iver_itm_ID ( iver_itm_ID )\n\t            ) ENGINE = innodb");
        task_end();
        task_begin('Updating group permissions...');
        $DB->query("UPDATE T_groups\n\t\t\t\t\t\t\t\t\t\tSET grp_perm_xhtml_css_tweaks = 1\n\t\t\t\t\t\t\t\t\tWHERE grp_ID <= 3");
        task_end();
        set_upgrade_checkpoint('9930');
    }
    if ($old_db_version < 9940) {
        // 3.2
        task_begin('Updating hitlog table...');
        $DB->query("ALTER TABLE T_hitlog ADD COLUMN hit_serprank INT UNSIGNED DEFAULT NULL AFTER hit_keyphrase_keyp_ID");
        task_end();
        task_begin('Updating versions table...');
        $DB->query("ALTER TABLE T_items__version\n\t\t\t\t\t\t\t\tCHANGE COLUMN iver_edit_user_ID iver_edit_user_ID  INT UNSIGNED NULL");
        task_end();
    }
    if ($old_db_version < 9950) {
        // 3.3
        task_begin('Altering Blogs table... ');
        $DB->query("ALTER TABLE T_blogs CHANGE COLUMN blog_shortname blog_shortname varchar(255) default ''");
        task_end();
        task_begin('Altering default dates... ');
        $DB->query("ALTER TABLE T_links\n      ALTER COLUMN link_datecreated SET DEFAULT '2000-01-01 00:00:00',\n      ALTER COLUMN link_datemodified SET DEFAULT '2000-01-01 00:00:00'");
        $DB->query("ALTER TABLE T_cron__task\n      ALTER COLUMN ctsk_start_datetime SET DEFAULT '2000-01-01 00:00:00'");
        $DB->query("ALTER TABLE T_cron__log\n      ALTER COLUMN clog_realstart_datetime SET DEFAULT '2000-01-01 00:00:00'");
        task_end();
        task_begin('Altering Items table... ');
        $DB->query("ALTER TABLE T_items__item\n\t\t\tADD COLUMN post_metadesc VARCHAR(255) NULL DEFAULT NULL AFTER post_titletag,\n\t\t\tADD COLUMN post_metakeywords VARCHAR(255) NULL DEFAULT NULL AFTER post_metadesc,\n\t\t\tADD COLUMN post_editor_code VARCHAR(32) NULL COMMENT 'Plugin code of the editor used to edit this post' AFTER post_varchar3");
        task_end();
        task_begin('Forcing AutoP posts to html editor...');
        $DB->query('UPDATE T_items__item
											SET post_editor_code = "html"
										WHERE post_renderers = "default"
											 OR post_renderers LIKE "%b2WPAutP%"');
        task_end();
        set_upgrade_checkpoint('9950');
    }
    if ($old_db_version < 9960) {
        // 3.3
        echo "Renaming tables...";
        $DB->save_error_state();
        $DB->halt_on_error = false;
        $DB->show_errors = false;
        $DB->query("ALTER TABLE {$tableprefix}users_fields RENAME TO T_users__fields");
        $DB->restore_error_state();
        echo "OK.<br />\n";
        // fp> The following is more tricky to do with CHARACTER SET. During upgrade, we don't know what the admin actually wants.
        task_begin('Making sure all tables use desired storage ENGINE as specified in the b2evo schema...');
        foreach ($schema_queries as $table_name => $table_def) {
            if ($DB->query('SHOW TABLES LIKE \'' . $table_name . '\'') && preg_match('/\\sENGINE\\s*=\\s*([a-z]+)/is', $table_def[1], $matches)) {
                // If the table exists and has an ENGINE definition:
                echo $table_name . ':' . $matches[1] . '<br />';
                $DB->query("ALTER TABLE {$table_name} ENGINE = " . $matches[1]);
            }
        }
        task_end();
        set_upgrade_checkpoint('9960');
    }
    if ($old_db_version < 9970) {
        // 4.0 part 1
        // For create_default_currencies() and create_default_countries():
        require_once dirname(__FILE__) . '/_functions_create.php';
        task_begin('Creating table for default currencies... ');
        $DB->query('CREATE TABLE ' . $tableprefix . 'currency (
				curr_ID int(10) unsigned NOT NULL auto_increment,
				curr_code char(3) NOT NULL,
				curr_shortcut varchar(30) NOT NULL,
				curr_name varchar(40) NOT NULL,
				PRIMARY KEY curr_ID (curr_ID),
				UNIQUE curr_code (curr_code)
			) ENGINE = innodb');
        task_end();
        create_default_currencies($tableprefix . 'currency');
        task_begin('Creating table for default countries... ');
        $DB->query('CREATE TABLE ' . $tableprefix . 'country (
				ctry_ID int(10) unsigned NOT NULL auto_increment,
				ctry_code char(2) NOT NULL,
				ctry_name varchar(40) NOT NULL,
				ctry_curr_ID int(10) unsigned,
				PRIMARY KEY ctry_ID (ctry_ID),
				UNIQUE ctry_code (ctry_code)
			) ENGINE = innodb');
        task_end();
        create_default_countries($tableprefix . 'country', false);
        task_begin('Upgrading user permissions table... ');
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\tADD COLUMN bloguser_perm_page\t\ttinyint NOT NULL default 0 AFTER bloguser_perm_media_change,\n\t\t\tADD COLUMN bloguser_perm_intro\t\ttinyint NOT NULL default 0 AFTER bloguser_perm_page,\n\t\t\tADD COLUMN bloguser_perm_podcast\ttinyint NOT NULL default 0 AFTER bloguser_perm_intro,\n\t\t\tADD COLUMN bloguser_perm_sidebar\ttinyint NOT NULL default 0 AFTER bloguser_perm_podcast");
        task_end();
        task_begin('Upgrading group permissions table... ');
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\tADD COLUMN bloggroup_perm_page\t\ttinyint NOT NULL default 0 AFTER bloggroup_perm_media_change,\n\t\t\tADD COLUMN bloggroup_perm_intro\t\ttinyint NOT NULL default 0 AFTER bloggroup_perm_page,\n\t\t\tADD COLUMN bloggroup_perm_podcast\ttinyint NOT NULL default 0 AFTER bloggroup_perm_intro,\n\t\t\tADD COLUMN bloggroup_perm_sidebar\ttinyint NOT NULL default 0 AFTER bloggroup_perm_podcast");
        task_end();
        task_begin('Upgrading users table... ');
        $DB->query("ALTER TABLE T_users\n\t\t\tADD COLUMN user_ctry_ID int(10) unsigned NULL AFTER user_avatar_file_ID");
        task_end();
        // Creating tables for messaging module
        task_begin('Creating table for message threads... ');
        $DB->query("CREATE TABLE T_messaging__thread (\n\t\t\tthrd_ID int(10) unsigned NOT NULL auto_increment,\n\t\t\tthrd_title varchar(255) NOT NULL,\n\t\t\tthrd_datemodified datetime NOT NULL,\n\t\t\tPRIMARY KEY thrd_ID (thrd_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Creating table for messagee... ');
        $DB->query("CREATE TABLE T_messaging__message (\n\t\t\tmsg_ID int(10) unsigned NOT NULL auto_increment,\n\t\t\tmsg_author_user_ID int(10) unsigned NOT NULL,\n\t\t\tmsg_datetime datetime NOT NULL,\n\t\t\tmsg_thread_ID int(10) unsigned NOT NULL,\n\t\t\tmsg_text text NULL,\n\t\t\tPRIMARY KEY msg_ID (msg_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Creating table for message thread statuses... ');
        $DB->query("CREATE TABLE T_messaging__threadstatus (\n\t\t\ttsta_thread_ID int(10) unsigned NOT NULL,\n\t\t\ttsta_user_ID int(10) unsigned NOT NULL,\n\t\t\ttsta_first_unread_msg_ID int(10) unsigned NULL,\n\t\t\tINDEX(tsta_user_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Creating table for messaging contacts... ');
        $DB->query("CREATE TABLE T_messaging__contact (\n\t\t\tmct_from_user_ID int(10) unsigned NOT NULL,\n\t\t\tmct_to_user_ID int(10) unsigned NOT NULL,\n\t\t\tmct_blocked tinyint(1) default 0,\n\t\t\tmct_last_contact_datetime datetime NOT NULL,\n\t\t\tPRIMARY KEY mct_PK (mct_from_user_ID, mct_to_user_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Upgrading skins table... ');
        $DB->query("ALTER TABLE T_skins__skin\n\t\t\t\t\t\tMODIFY skin_type enum('normal','feed','sitemap') NOT NULL default 'normal'");
        task_end();
        task_begin('Setting skin type of sitemap skin to "sitemap"... ');
        $DB->query("UPDATE T_skins__skin\n\t\t\t\t\t\tSET skin_type = 'sitemap'\n\t\t\t\t\t\tWHERE skin_folder = '_sitemap'");
        task_end();
        // Creating table for pluggable permissions
        // This table gets created during upgrade to v0.8.9 at checkpoint 8050
        task_begin('Creating table for Group Settings... ');
        $DB->query("CREATE TABLE IF NOT EXISTS T_groups__groupsettings (\n\t\t\tgset_grp_ID INT(11) UNSIGNED NOT NULL,\n\t\t\tgset_name VARCHAR(30) NOT NULL,\n\t\t\tgset_value VARCHAR(255) NULL,\n\t\t\tPRIMARY KEY (gset_grp_ID, gset_name)\n\t\t) ENGINE = innodb");
        task_end();
        // Rename T_usersettings table to T_users__usersettings
        task_begin('Rename T_usersettings table to T_users__usersettings... ');
        $DB->query('ALTER TABLE ' . $tableprefix . 'usersettings RENAME TO T_users__usersettings');
        task_end();
        set_upgrade_checkpoint('9970');
    }
    if ($old_db_version < 9980) {
        // 4.0 part 2
        task_begin('Upgrading posts... ');
        $DB->query('
			UPDATE T_items__item
			   SET post_datestart = FROM_UNIXTIME( FLOOR(UNIX_TIMESTAMP(post_datestart)/60)*60 )
			 WHERE post_datestart > NOW()');
        db_add_col('T_items__item', 'post_excerpt_autogenerated', 'TINYINT NULL DEFAULT NULL AFTER post_excerpt');
        db_add_col('T_items__item', 'post_dateset', 'tinyint(1) NOT NULL DEFAULT 1 AFTER post_assigned_user_ID');
        task_end();
        task_begin('Upgrading countries... ');
        db_add_col($tableprefix . 'country', 'ctry_enabled', 'tinyint(1) NOT NULL DEFAULT 1 AFTER ctry_curr_ID');
        task_end();
        task_begin('Upgrading links... ');
        // Add link_position. Temporary allow NULL, set compatibility default, then do not allow NULL.
        // TODO: dh> actually, using "teaser" for the first link and "aftermore" for the rest would make more sense (and "aftermore" should get displayed with "no-more" posts anyway).
        //           Opinions? Could be heavy to transform this though..
        // fp> no, don't change past posts unexpectedly.
        db_add_col('T_links', 'link_position', "varchar(10) NULL AFTER link_title");
        $DB->query("UPDATE T_links SET link_position = 'teaser' WHERE link_position IS NULL");
        db_add_col('T_links', 'link_position', "varchar(10) NOT NULL AFTER link_title");
        // change to NOT NULL
        // Add link_order. Temporary allow NULL, use order from ID, then do not allow NULL and add UNIQUE index.
        db_add_col('T_links', 'link_order', 'int(11) unsigned NULL AFTER link_position');
        $DB->query("UPDATE T_links SET link_order = link_ID WHERE link_order IS NULL");
        db_add_col('T_links', 'link_order', 'int(11) unsigned NOT NULL AFTER link_position');
        // change to NOT NULL
        db_add_index('T_links', 'link_itm_ID_order', 'link_itm_ID, link_order', 'UNIQUE');
        task_end();
        task_begin('Upgrading sessions... ');
        $DB->query("ALTER TABLE T_sessions CHANGE COLUMN sess_ipaddress sess_ipaddress VARCHAR(39) NOT NULL DEFAULT ''");
        task_end();
        set_upgrade_checkpoint('9980');
    }
    if ($old_db_version < 9990) {
        // 4.0 part 3
        task_begin('Upgrading hitlog... ');
        db_add_col('T_hitlog', 'hit_agent_type', "ENUM('rss','robot','browser','unknown') DEFAULT 'unknown' NOT NULL AFTER hit_remote_addr");
        if (db_col_exists('T_hitlog', 'hit_agnt_ID')) {
            $DB->query('UPDATE T_hitlog, ' . $tableprefix . 'useragents
			                SET hit_agent_type = agnt_type
			              WHERE hit_agnt_ID = agnt_ID
			                AND agnt_type <> "unknown"');
            // We already have the unknown as default
            db_drop_col('T_hitlog', 'hit_agnt_ID');
        }
        $DB->query('DROP TABLE IF EXISTS ' . $tableprefix . 'useragents');
        task_end();
        set_upgrade_checkpoint('9990');
    }
    if ($old_db_version < 10000) {
        // 4.0 part 4
        // Integrate comment_secret
        task_begin('Extending Comment table... ');
        db_add_col('T_comments', 'comment_secret', 'varchar(32) NULL default NULL');
        task_end();
        // Create T_slug table and, Insert all slugs from T_items
        task_begin('Create Slugs table... ');
        $DB->query('CREATE TABLE IF NOT EXISTS T_slug (
						slug_ID int(10) unsigned NOT NULL auto_increment,
						slug_title varchar(255) NOT NULL COLLATE ascii_bin,
						slug_type char(6) NOT NULL DEFAULT "item",
						slug_itm_ID int(11) unsigned,
						PRIMARY KEY slug_ID (slug_ID),
						UNIQUE	slug_title (slug_title)
					) ENGINE = innodb');
        task_end();
        task_begin('Making sure all posts have a slug...');
        // Get posts with empty urltitle:
        $sql = 'SELECT post_ID, post_title
				      FROM T_items__item
				     WHERE post_urltitle IS NULL OR post_urltitle = ""';
        $rows = $DB->get_results($sql, OBJECT, 'Get posts with empty urltitle');
        // Create URL titles when non existent:
        foreach ($rows as $row) {
            // TODO: dh> pass locale (useful for transliteration).
            $DB->query('UPDATE T_items__item
				              SET post_urltitle = "' . urltitle_validate('', $row->post_title, 0) . '"
		                WHERE post_ID = ' . $row->post_ID, 'Set posts urltitle');
        }
        task_end();
        task_begin('Populating Slugs table... ');
        $DB->query('REPLACE INTO T_slug( slug_title, slug_type, slug_itm_ID)
		              SELECT post_urltitle, "item", post_ID
							      FROM T_items__item');
        task_end();
        task_begin('Add canonical and tiny slug IDs to post table...');
        // modify post_urltitle column -> Not allow NULL value
        db_add_col('T_items__item', 'post_urltitle', 'VARCHAR(210) NOT NULL');
        db_add_col('T_items__item', 'post_canonical_slug_ID', 'int(10) unsigned NULL default NULL after post_urltitle');
        db_add_col('T_items__item', 'post_tiny_slug_ID', 'int(10) unsigned NULL default NULL after post_canonical_slug_ID');
        task_end();
        task_begin('Upgrading posts...');
        $DB->query('UPDATE T_items__item, T_slug
			              SET post_canonical_slug_ID = slug_ID
			            WHERE CONVERT( post_urltitle USING ASCII ) COLLATE ascii_bin = slug_title');
        task_end();
        task_begin('Adding "help" slug...');
        if (db_key_exists('T_slug', 'slug_title', '"help"')) {
            echo '<strong>Warning: "help" slug already exists!</strong><br /> ';
        } else {
            $DB->query('INSERT INTO T_slug( slug_title, slug_type )
			             VALUES( "help", "help" )', 'Add "help" slug');
            task_end();
        }
        // fp> Next time we should use pluggable permissions instead.
        task_begin('Updgrading groups: Giving Administrators Group edit perms on slugs...');
        db_add_col('T_groups', 'grp_perm_slugs', "enum('none','view','edit') NOT NULL default 'none'");
        $DB->query('UPDATE T_groups
		             SET grp_perm_slugs = "edit"
		             WHERE grp_ID = 1');
        task_end();
        task_begin('Upgrading settings table... ');
        $DB->query('UPDATE T_settings
		                SET set_value = 1
		              WHERE set_name = "fm_enable_roots_user"
		                    AND set_value = 0');
        task_end();
        // New perms for comment moderation depending on status:
        task_begin('Upgrading Blog-User permissions...');
        db_add_col('T_coll_user_perms', 'bloguser_perm_draft_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments');
        db_add_col('T_coll_user_perms', 'bloguser_perm_publ_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments');
        db_add_col('T_coll_user_perms', 'bloguser_perm_depr_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments');
        if (db_col_exists('T_coll_user_perms', 'bloguser_perm_comments')) {
            // if user had perm_comments he now gets all 3 new perms also:
            $DB->query('UPDATE T_coll_user_perms
						SET bloguser_perm_draft_cmts = bloguser_perm_comments,
							bloguser_perm_publ_cmts = bloguser_perm_comments,
							bloguser_perm_depr_cmts = bloguser_perm_comments');
            db_drop_col('T_coll_user_perms', 'bloguser_perm_comments');
        }
        task_end();
        task_begin('Upgrading Blog-Group permissions...');
        db_add_col('T_coll_group_perms', 'bloggroup_perm_draft_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments');
        db_add_col('T_coll_group_perms', 'bloggroup_perm_publ_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments');
        db_add_col('T_coll_group_perms', 'bloggroup_perm_depr_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments');
        if (db_col_exists('T_coll_group_perms', 'bloggroup_perm_comments')) {
            // if group had perm_comments he now gets all 3 new perms also:
            $DB->query('UPDATE T_coll_group_perms
						SET bloggroup_perm_draft_cmts = bloggroup_perm_comments,
							bloggroup_perm_publ_cmts = bloggroup_perm_comments,
							bloggroup_perm_depr_cmts = bloggroup_perm_comments');
            db_drop_col('T_coll_group_perms', 'bloggroup_perm_comments');
        }
        task_end();
        task_begin('Upgrading messaging permissions...');
        $DB->query('ALTER TABLE T_users ALTER COLUMN user_allow_msgform SET DEFAULT "2"');
        $DB->query('UPDATE T_users
					SET user_allow_msgform = 3
					WHERE user_allow_msgform = 1');
        task_end();
        task_begin('Upgrading currency table...');
        $DB->query('ALTER TABLE ' . $tableprefix . 'currency ADD COLUMN curr_enabled tinyint(1) NOT NULL DEFAULT 1 AFTER curr_name');
        task_end();
        task_begin('Upgrading default blog access type for new blogs...');
        $DB->query('ALTER TABLE T_blogs ALTER COLUMN blog_access_type SET DEFAULT "extrapath"');
        task_end();
        task_begin('Upgrading tags table...');
        $DB->query('ALTER TABLE T_items__tag CHANGE COLUMN tag_name tag_name varbinary(50) not null');
        task_end();
        // fp> I don't understand why we need to carry this out "again" but I observed the installer barking on
        // this setting missing when upgrading from older 2.x versions. I figured it would be no big deal to do it twice...
        task_begin('Makin sure usersettings table is InnoDB...');
        $DB->query('ALTER TABLE T_users__usersettings ENGINE=innodb');
        task_end();
        set_upgrade_checkpoint('10000');
    }
    if ($old_db_version < 10100) {
        // 4.1
        task_begin('Convert group permissions to pluggable permissions...');
        // asimo>This delete query needs just in case if this version of b2evo was used, before upgrade process call
        $DB->query('DELETE FROM T_groups__groupsettings
						WHERE gset_name = "perm_files" OR gset_name = "perm_options" OR gset_name = "perm_templates"');
        // Get current permission values from groups table
        $sql = 'SELECT grp_ID, grp_perm_spamblacklist, grp_perm_slugs, grp_perm_files, grp_perm_options, grp_perm_templates
				      FROM T_groups';
        $rows = $DB->get_results($sql, OBJECT, 'Get groups converted permissions');
        // Insert values into groupsettings table
        foreach ($rows as $row) {
            // "IGNORE" is needed if we already created T_groups__groupsettings during upgrade to v0.8.9 at checkpoint 8050
            $DB->query('INSERT IGNORE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
							VALUES( ' . $row->grp_ID . ', "perm_spamblacklist", "' . $row->grp_perm_spamblacklist . '" ),
								( ' . $row->grp_ID . ', "perm_slugs", "' . $row->grp_perm_slugs . '" ),
								( ' . $row->grp_ID . ', "perm_files", "' . $row->grp_perm_files . '" ),
								( ' . $row->grp_ID . ', "perm_options", "' . $row->grp_perm_options . '" ),
								( ' . $row->grp_ID . ', "perm_templates", "' . $row->grp_perm_templates . '" )');
        }
        // Drop all converted permissin colums from groups table
        db_drop_col('T_groups', 'grp_perm_spamblacklist');
        db_drop_col('T_groups', 'grp_perm_slugs');
        db_drop_col('T_groups', 'grp_perm_files');
        db_drop_col('T_groups', 'grp_perm_options');
        db_drop_col('T_groups', 'grp_perm_templates');
        task_end();
        task_begin('Upgrading users table, adding user gender...');
        db_add_col('T_users', 'user_gender', 'char(1) NULL DEFAULT NULL AFTER user_showonline');
        task_end();
        task_begin('Upgrading edit timpestamp blog-user permission...');
        db_add_col('T_coll_user_perms', 'bloguser_perm_edit_ts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_delpost');
        $DB->query('UPDATE T_coll_user_perms, T_users
							SET bloguser_perm_edit_ts = 1
							WHERE bloguser_user_ID = user_ID  AND user_level > 4');
        task_end();
        task_begin('Upgrading edit timpestamp blog-group permission...');
        db_add_col('T_coll_group_perms', 'bloggroup_perm_edit_ts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_delpost');
        $DB->query('UPDATE T_coll_group_perms
							SET bloggroup_perm_edit_ts = 1
							WHERE bloggroup_group_ID = 1');
        task_end();
        task_begin('Upgrading comments table, add trash status...');
        $DB->query("ALTER TABLE T_comments MODIFY COLUMN comment_status ENUM('published','deprecated','draft', 'trash') DEFAULT 'published' NOT NULL");
        task_end();
        task_begin('Upgrading groups admin access permission...');
        $sql = 'SELECT grp_ID, grp_perm_admin
					FROM T_groups';
        $rows = $DB->get_results($sql, OBJECT, 'Get groups admin perms');
        foreach ($rows as $row) {
            switch ($row->grp_perm_admin) {
                case 'visible':
                    $value = 'normal';
                    break;
                case 'hidden':
                    $value = 'restricted';
                    break;
                default:
                    $value = 'none';
            }
            // "IGNORE" is needed if we already created T_groups__groupsettings during upgrade to v0.8.9 at checkpoint 8050
            $DB->query('INSERT IGNORE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
							VALUES( ' . $row->grp_ID . ', "perm_admin", "' . $value . '" )');
        }
        db_drop_col('T_groups', 'grp_perm_admin');
        task_end();
        task_begin('Upgrading users table, add users source...');
        db_add_col('T_users', 'user_source', 'varchar(30) NULL');
        task_end();
        task_begin('Upgrading blogs table: more granularity for comment allowing...');
        $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT blog_ID, "allow_comments", "never"
							FROM T_blogs
							WHERE blog_allowcomments = "never"');
        db_drop_col('T_blogs', 'blog_allowcomments');
        task_end();
        task_begin('Upgrading blogs table: allow_rating fields...');
        $DB->query('UPDATE T_coll_settings
						SET cset_value = "any"
						WHERE cset_value = "always" AND cset_name = "allow_rating"');
        task_end();
        task_begin('Upgrading links table, add link_cmt_ID...');
        $DB->query('ALTER TABLE T_links
						MODIFY COLUMN link_itm_ID int(11) unsigned NULL,
						MODIFY COLUMN link_creator_user_ID int(11) unsigned NULL,
						MODIFY COLUMN link_lastedit_user_ID int(11) unsigned NULL,
						ADD COLUMN link_cmt_ID int(11) unsigned NULL COMMENT "Used for linking files to comments (comment attachments)" AFTER link_itm_ID');
        $DB->query('ALTER TABLE T_links
						ADD INDEX link_cmt_ID ( link_cmt_ID )');
        task_end();
        task_begin('Upgrading filetypes table...');
        // get allowed filetype ids
        $sql = 'SELECT ftyp_ID
					FROM T_filetypes
					WHERE ftyp_allowed != 0';
        $allowed_ids = implode(',', $DB->get_col($sql, 0, 'Get allowed filetypes'));
        // update table column  -- this column is about who can edit the filetype: any user, registered users or only admins.
        $DB->query('ALTER TABLE T_filetypes
						MODIFY COLUMN ftyp_allowed enum("any","registered","admin") NOT NULL default "admin"');
        // update ftyp_allowed column content
        $DB->query('UPDATE T_filetypes
						SET ftyp_allowed = "registered"
						WHERE ftyp_ID IN (' . $allowed_ids . ')');
        $DB->query('UPDATE T_filetypes
						SET ftyp_allowed = "admin"
						WHERE ftyp_ID NOT IN (' . $allowed_ids . ')');
        $DB->query('UPDATE T_filetypes
						SET ftyp_allowed = "any"
						WHERE ftyp_extensions = "gif" OR ftyp_extensions = "png" OR ftyp_extensions LIKE "%jpg%"');
        // Add m4v file type if not exists
        if (!db_key_exists('T_filetypes', 'ftyp_extensions', '"m4v"')) {
            $DB->query('INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("m4v", "MPEG video file", "video/x-m4v", "", "browser", "registered")', 'Add "m4v" file type');
        }
        task_end();
        // The AdSense plugin needs to store quite long strings of data...
        task_begin('Upgrading collection settings table, change cset_value type...');
        $DB->query('ALTER TABLE T_coll_settings
								 MODIFY COLUMN cset_name VARCHAR(50) NOT NULL,
								 MODIFY COLUMN cset_value VARCHAR(10000) NULL');
        task_end();
        set_upgrade_checkpoint('10100');
    }
    if ($old_db_version < 10200) {
        // 4.1b
        task_begin('Creating table for a specific blog post subscriptions...');
        $DB->query("CREATE TABLE T_items__subscriptions (\n\t\t\t\t\t\tisub_item_ID  int(11) unsigned NOT NULL,\n\t\t\t\t\t\tisub_user_ID  int(11) unsigned NOT NULL,\n\t\t\t\t\t\tisub_comments tinyint(1) NOT NULL default 0 COMMENT 'The user wants to receive notifications for new comments on this post',\n\t\t\t\t\t\tPRIMARY KEY (isub_item_ID, isub_user_ID )\n\t\t\t\t\t) ENGINE = innodb");
        task_end();
        task_begin('Upgrading comments table, add subscription fields...');
        db_add_col('T_comments', 'comment_notif_status', 'ENUM("noreq","todo","started","finished") NOT NULL DEFAULT "noreq" COMMENT "Have notifications been sent for this comment? How far are we in the process?" AFTER comment_secret');
        db_add_col('T_comments', 'comment_notif_ctsk_ID', 'INT(10) unsigned NULL DEFAULT NULL COMMENT "When notifications for this comment are sent through a scheduled job, what is the job ID?" AFTER comment_notif_status');
        task_end();
        task_begin('Upgrading users table...');
        db_add_col('T_users', 'user_notify_moderation', 'tinyint(1) NOT NULL default 0 COMMENT "Notify me by email whenever a comment is awaiting moderation on one of my blogs" AFTER user_notify');
        db_add_col('T_users', 'user_unsubscribe_key', 'varchar(32) NOT NULL default "" COMMENT "A specific key, it is used when a user wants to unsubscribe from a post comments without signing in" AFTER user_notify_moderation');
        // Set unsubscribe keys for existing users with no unsubscribe key
        $sql = 'SELECT user_ID
							FROM T_users
						 WHERE user_unsubscribe_key = ""';
        $rows = $DB->get_results($sql, OBJECT, 'Get users with no unsubscribe key');
        foreach ($rows as $row) {
            $DB->query('UPDATE T_users
							SET user_unsubscribe_key = "' . generate_random_key() . '"
							WHERE user_ID = ' . $row->user_ID);
        }
        task_end();
        task_begin('Upgrading settings table... ');
        // This query was removed later, to avoid performance issue because of the smart view counting
        /*$DB->query( 'INSERT INTO T_settings (set_name, set_value)
        		VALUES ( "smart_hit_count", 1 )' );*/
        $DB->query('ALTER TABLE T_coll_settings
									CHANGE COLUMN cset_value cset_value   VARCHAR( 10000 ) NULL COMMENT "The AdSense plugin wants to store very long snippets of HTML"');
        task_end();
        // The following two upgrade task were created subsequently to "Make sure DB schema is up to date".
        // Note: These queries don't modify the correct databases
        task_begin('Upgrading users table, no notification by default...');
        $DB->query('ALTER TABLE T_users ALTER COLUMN user_notify SET DEFAULT 0');
        task_end();
        task_begin('Upgrading items table...');
        $DB->query('ALTER TABLE T_items__item CHANGE COLUMN post_priority post_priority int(11) unsigned null COMMENT "Task priority in workflow"');
        task_end();
        set_upgrade_checkpoint('10200');
    }
    if ($old_db_version < 10300) {
        // 4.2
        task_begin('Upgrading user fields...');
        $DB->query('ALTER TABLE T_users__fielddefs
									ADD COLUMN ufdf_required enum("hidden","optional","recommended","require") NOT NULL default "optional"');
        $DB->query('UPDATE T_users__fielddefs
										SET ufdf_required = "recommended"
									WHERE ufdf_name in ("Website", "Twitter", "Facebook") ');
        $DB->query("REPLACE INTO T_users__fielddefs (ufdf_ID, ufdf_type, ufdf_name, ufdf_required)\n\t\t\t \t\t\t\t\t\tVALUES (400000, 'text', 'About me', 'recommended');");
        task_end();
        task_begin('Moving data to user fields...');
        $DB->query('INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10300, user_icq
									 FROM T_users
								  WHERE user_icq IS NOT NULL AND TRIM(user_icq) <> ""');
        $DB->query('INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10200, user_aim
									 FROM T_users
								  WHERE user_aim IS NOT NULL AND TRIM(user_aim) <> ""');
        $DB->query('INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10000, user_msn
									 FROM T_users
								  WHERE user_msn IS NOT NULL AND TRIM(user_msn) <> ""');
        $DB->query('INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10100, user_yim
									 FROM T_users
								  WHERE user_yim IS NOT NULL AND TRIM(user_yim) <> ""');
        task_end();
        task_begin('Dropping obsolete user columns...');
        $DB->query('ALTER TABLE T_users
									DROP COLUMN user_icq,
									DROP COLUMN user_aim,
									DROP COLUMN user_msn,
									DROP COLUMN user_yim');
        task_end();
        // ---
        task_begin('Adding new user columns...');
        $DB->query('ALTER TABLE T_users
									ADD COLUMN user_postcode varchar(12) NULL AFTER user_ID,
									ADD COLUMN user_age_min int unsigned NULL AFTER user_postcode,
									ADD COLUMN user_age_max int unsigned NULL AFTER user_age_min');
        task_end();
        task_begin('Upgrading item table for hide teaser...');
        $DB->query('ALTER TABLE T_items__item
						ADD COLUMN post_hideteaser tinyint(1) NOT NULL DEFAULT 0 AFTER post_featured');
        $DB->query('UPDATE T_items__item
										SET post_hideteaser = 1
									WHERE post_content LIKE "%<!--noteaser-->%"');
        task_end();
        task_begin('Creating table for a specific post settings...');
        $DB->query("CREATE TABLE T_items__item_settings (\n\t\t\t\t\t\tiset_item_ID  int(10) unsigned NOT NULL,\n\t\t\t\t\t\tiset_name     varchar( 50 ) NOT NULL,\n\t\t\t\t\t\tiset_value    varchar( 2000 ) NULL,\n\t\t\t\t\t\tPRIMARY KEY ( iset_item_ID, iset_name )\n\t\t\t\t\t) ENGINE = innodb");
        task_end();
        task_begin('Adding new column to comments...');
        $DB->query('ALTER TABLE T_comments
									ADD COLUMN comment_in_reply_to_cmt_ID INT(10) unsigned NULL AFTER comment_status');
        task_end();
        task_begin('Create table for internal searches...');
        $DB->query('CREATE TABLE T_logs__internal_searches (
						isrch_ID bigint(20) NOT NULL auto_increment,
						isrch_coll_ID bigint(20) NOT NULL,
						isrch_hit_ID bigint(20) NOT NULL,
						isrch_keywords varchar(255) NOT NULL,
						PRIMARY KEY (isrch_ID)
					) ENGINE = MyISAM');
        task_end();
        task_begin('Create table for comments votes...');
        $DB->query('CREATE TABLE T_comments__votes (
						cmvt_cmt_ID  int(10) unsigned NOT NULL,
						cmvt_user_ID int(10) unsigned NOT NULL,
						cmvt_helpful TINYINT(1) NULL DEFAULT NULL,
						cmvt_spam    TINYINT(1) NULL DEFAULT NULL,
						PRIMARY KEY (cmvt_cmt_ID, cmvt_user_ID),
						KEY cmvt_cmt_ID (cmvt_cmt_ID),
						KEY cmvt_user_ID (cmvt_user_ID)
					) ENGINE = innodb');
        task_end();
        task_begin('Adding new comments columns...');
        $DB->query('ALTER TABLE T_comments
									ADD comment_helpful_addvotes INT NOT NULL DEFAULT 0 AFTER comment_nofollow ,
									ADD comment_helpful_countvotes INT UNSIGNED NOT NULL DEFAULT 0 AFTER comment_helpful_addvotes ,
									ADD comment_spam_addvotes INT NOT NULL DEFAULT 0 AFTER comment_helpful_countvotes ,
									ADD comment_spam_countvotes INT UNSIGNED NOT NULL DEFAULT 0 AFTER comment_spam_addvotes ,
									CHANGE COLUMN comment_notif_ctsk_ID comment_notif_ctsk_ID      INT(10) unsigned NULL DEFAULT NULL COMMENT "When notifications for this comment are sent through a scheduled job, what is the job ID?"');
        task_end();
        task_begin('Adding new user permission for spam voting...');
        $DB->query('ALTER TABLE T_coll_user_perms
									ADD bloguser_perm_vote_spam_cmts tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts');
        task_end();
        task_begin('Adding new group permission for spam voting...');
        $DB->query('ALTER TABLE T_coll_group_perms
									ADD bloggroup_perm_vote_spam_cmts tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts');
        task_end();
        task_begin('Upgrading countries table...');
        $DB->query('ALTER TABLE ' . $tableprefix . 'country ADD COLUMN ctry_preferred tinyint(1) NOT NULL DEFAULT 0 AFTER ctry_enabled');
        task_end();
        $DB->query('ALTER TABLE T_items__subscriptions CHANGE COLUMN isub_comments isub_comments   tinyint(1) NOT NULL DEFAULT 0 COMMENT "The user wants to receive notifications for new comments on this post"');
        set_upgrade_checkpoint('10300');
    }
    if ($old_db_version < 10400) {
        // 4.2 part 2
        task_begin('Updating "Post by Email" settings...');
        $DB->query('UPDATE T_settings SET set_name = "eblog_autobr" WHERE set_name = "AutoBR"');
        task_end();
        if ($DB->get_var('SELECT set_value FROM T_settings WHERE set_name = "eblog_enabled"')) {
            // eblog enabled, let's create a scheduled job for it
            task_begin('Creating "Post by Email" scheduled job...');
            $start_date = form_date(date2mysql($GLOBALS['localtimenow'] + 86400), '05:00:00');
            // start tomorrow
            $DB->query('
				INSERT INTO T_cron__task ( ctsk_start_datetime, ctsk_repeat_after, ctsk_name, ctsk_controller, ctsk_params )
				VALUES ( ' . $DB->quote($start_date) . ', 86400, ' . $DB->quote(T_('Create posts by email')) . ', ' . $DB->quote('cron/jobs/_post_by_email.job.php') . ', ' . $DB->quote('N;') . ' )');
            task_end();
        }
        task_begin('Upgrading hitlog table...');
        $DB->query('ALTER TABLE T_hitlog
								ADD COLUMN hit_disp        VARCHAR(30) DEFAULT NULL AFTER hit_uri,
								ADD COLUMN hit_ctrl        VARCHAR(30) DEFAULT NULL AFTER hit_disp,
								ADD COLUMN hit_response_code     INT DEFAULT NULL AFTER hit_agent_type ');
        task_end();
        task_begin('Upgrading file types...');
        // Update ftyp_icon column
        // Previous versions used a image file name for this field,
        // but from now we should use a icon name from the file /conf/_icons.php
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_image"
						WHERE ftyp_extensions IN ( "gif", "png", "jpg jpeg" )');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_document"
						WHERE ftyp_extensions = "txt"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_www"
						WHERE ftyp_extensions = "htm html"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_pdf"
						WHERE ftyp_extensions = "pdf"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_doc"
						WHERE ftyp_extensions = "doc"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_xls"
						WHERE ftyp_extensions = "xls"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_ppt"
						WHERE ftyp_extensions = "ppt"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_pps"
						WHERE ftyp_extensions = "pps"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_zip"
						WHERE ftyp_extensions = "zip"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_php"
						WHERE ftyp_extensions = "php php3 php4 php5 php6"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = ""
						WHERE ftyp_extensions = "css"');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_sound"
						WHERE ftyp_extensions IN ( "mp3", "m4a" )');
        $DB->query('UPDATE T_filetypes
						SET ftyp_icon = "file_video"
						WHERE ftyp_extensions IN ( "mp4", "mov", "m4v" )');
        task_end();
        set_upgrade_checkpoint('10400');
    }
    if ($old_db_version < 10500) {
        //  part 3
        task_begin('Upgrading hitlog table...');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\t\t\t\t\t\tCHANGE COLUMN hit_referer_type  hit_referer_type ENUM(  'search',  'special',  'spam',  'referer',  'direct',  'self',  'admin', 'blacklist' ) NOT NULL,\n\t\t\t\t\t\t\t\tADD COLUMN hit_type ENUM('standard','rss','admin','ajax', 'service') DEFAULT 'standard' NOT NULL AFTER hit_ctrl,\n\t\t\t\t\t\t\t\tADD COLUMN hit_action VARCHAR(30) DEFAULT NULL AFTER hit_ctrl");
        $DB->query('UPDATE T_hitlog SET hit_referer_type = "special" WHERE hit_referer_type = "blacklist"');
        $DB->query('UPDATE T_hitlog SET hit_type = "admin", hit_referer_type = "direct"  WHERE hit_referer_type = "admin"');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\t\t\t\t\t\tCHANGE COLUMN hit_referer_type  hit_referer_type ENUM(  'search',  'special',  'spam',  'referer',  'direct',  'self' ) NOT NULL");
        task_end();
        task_begin('Creating table for Groups of user field definitions...');
        $DB->query('CREATE TABLE T_users__fieldgroups (
				ufgp_ID int(10) unsigned NOT NULL auto_increment,
				ufgp_name varchar(255) NOT NULL,
				ufgp_order int(11) NOT NULL,
				PRIMARY KEY (ufgp_ID)
			) ENGINE = innodb');
        $DB->query('INSERT INTO T_users__fieldgroups ( ufgp_name, ufgp_order )
				VALUES ( "Instant Messaging", "1" ),
							 ( "Phone", "2" ),
							 ( "Web", "3" ),
							 ( "Organization", "4" ),
							 ( "Address", "5" ),
							 ( "Other", "6" ) ');
        task_end();
        task_begin('Upgrading user field definitions...');
        // Add new fields:
        // 		"ufdf_options" to save a values of the Option list
        // 		"ufdf_duplicated" to add a several instances
        // 		"ufdf_ufgp_ID" - Group ID
        // 		"ufdf_order" - Order number
        // 		"ufdf_suggest" - Suggest values
        $DB->query('ALTER TABLE T_users__fielddefs
						ADD ufdf_options    TEXT NOT NULL AFTER ufdf_name,
						ADD ufdf_duplicated enum("forbidden","allowed","list") NOT NULL default "allowed",
						ADD ufdf_ufgp_ID    int(10) unsigned NOT NULL AFTER ufdf_ID,
						ADD ufdf_order      int(11) NOT NULL,
						ADD ufdf_suggest    tinyint(1) NOT NULL DEFAULT 0,
						CHANGE ufdf_ID ufdf_ID int(10) UNSIGNED NOT NULL AUTO_INCREMENT');
        // Set default values of the field "ufdf_duplicated"
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_duplicated = "allowed"
						WHERE ufdf_ID IN ( 10000, 10100, 10200, 10300, 50100, 50200, 100000, 100100 )');
        // Group fields by default
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "1"
						WHERE ufdf_ID <= 40000 ');
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "2"
						WHERE ufdf_ID > 40000 AND ufdf_ID <= 60100');
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "3"
						WHERE ufdf_ID > 60100 AND ufdf_ID <= 160100');
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "4"
						WHERE ufdf_ID > 160100 AND ufdf_ID <= 211000');
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "5"
						WHERE ufdf_ID > 211000 AND ufdf_ID <= 300300');
        $DB->query('UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "6"
						WHERE ufdf_ID > 300300');
        // Set order field
        $userfields = $DB->get_results('SELECT ufdf_ID, ufdf_ufgp_ID
				FROM T_users__fielddefs
				ORDER BY ufdf_ufgp_ID, ufdf_ID');
        $userfield_order = 1;
        foreach ($userfields as $uf => $userfield) {
            if ($uf > 0) {
                if ($userfields[$uf - 1]->ufdf_ufgp_ID != $userfield->ufdf_ufgp_ID) {
                    // New group is starting, reset $userfield_order
                    $userfield_order = 1;
                }
            }
            $DB->query('UPDATE T_users__fielddefs
						SET ufdf_order = "' . $userfield_order . '"
						WHERE ufdf_ID = ' . $userfield->ufdf_ID);
            $userfield_order++;
        }
        // Change field type for Group 'Organization' (group_ID=4)
        $DB->query('UPDATE T_users__fielddefs
					SET ufdf_type = "word"
					WHERE ufdf_ufgp_ID = "4"');
        // Create a default additional info for administrator (user_ID=1)
        $DB->query('INSERT INTO T_users__fields ( uf_user_ID, uf_ufdf_ID, uf_varchar )
			VALUES ( 1, 200000, "Site administrator" ),
						 ( 1, 200000, "Moderator" ),
						 ( 1, 100000, "' . $baseurl . '" )');
        // Add Indexes
        $DB->query('ALTER TABLE T_users__fields
						ADD INDEX uf_ufdf_ID ( uf_ufdf_ID ),
						ADD INDEX uf_varchar ( uf_varchar ) ');
        task_end();
        task_begin('Upgrading permissions...');
        // Group permissions
        $DB->query('ALTER TABLE T_coll_group_perms
						ADD bloggroup_perm_own_cmts tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts');
        // Set default values for Administrators & Privileged Bloggers groups
        $DB->query('UPDATE T_coll_group_perms
						SET bloggroup_perm_own_cmts = "1"
						WHERE bloggroup_group_ID IN ( 1, 2 )');
        // User permissions
        $DB->query('ALTER TABLE T_coll_user_perms
						ADD bloguser_perm_own_cmts tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts');
        task_end();
        set_upgrade_checkpoint('10500');
    }
    if ($old_db_version < 10600) {
        //  part 4
        // For create_default_regions() and create_default_subregions():
        require_once dirname(__FILE__) . '/_functions_create.php';
        task_begin('Renaming Countries table...');
        $DB->query('RENAME TABLE ' . $tableprefix . 'country TO T_regional__country');
        task_end();
        task_begin('Renaming Currencies table...');
        $DB->query('RENAME TABLE ' . $tableprefix . 'currency TO T_regional__currency');
        task_end();
        task_begin('Creating Regions table...');
        $DB->query('CREATE TABLE T_regional__region (
			rgn_ID        int(10) unsigned NOT NULL auto_increment,
			rgn_ctry_ID   int(10) unsigned NOT NULL,
			rgn_code      char(6) NOT NULL,
			rgn_name      varchar(40) NOT NULL,
			rgn_enabled   tinyint(1) NOT NULL DEFAULT 1,
			rgn_preferred tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY rgn_ID (rgn_ID),
			UNIQUE rgn_ctry_ID_code (rgn_ctry_ID, rgn_code)
		) ENGINE = innodb');
        task_end();
        create_default_regions();
        task_begin('Creating Sub-regions table...');
        $DB->query('CREATE TABLE T_regional__subregion (
			subrg_ID        int(10) unsigned NOT NULL auto_increment,
			subrg_rgn_ID    int(10) unsigned NOT NULL,
			subrg_code      char(6) NOT NULL,
			subrg_name      varchar(40) NOT NULL,
			subrg_enabled   tinyint(1) NOT NULL DEFAULT 1,
			subrg_preferred tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY subrg_ID (subrg_ID),
			UNIQUE subrg_rgn_ID_code (subrg_rgn_ID, subrg_code)
		) ENGINE = innodb');
        task_end();
        create_default_subregions();
        task_begin('Creating Cities table...');
        $DB->query('CREATE TABLE T_regional__city (
			city_ID         int(10) unsigned NOT NULL auto_increment,
			city_ctry_ID    int(10) unsigned NOT NULL,
			city_rgn_ID     int(10) unsigned NULL,
			city_subrg_ID   int(10) unsigned NULL,
			city_postcode   char(12) NOT NULL,
			city_name       varchar(40) NOT NULL,
			city_enabled    tinyint(1) NOT NULL DEFAULT 1,
			city_preferred  tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY city_ID (city_ID),
			INDEX city_ctry_ID_postcode ( city_ctry_ID, city_postcode ),
			INDEX city_rgn_ID_postcode ( city_rgn_ID, city_postcode ),
			INDEX city_subrg_ID_postcode ( city_subrg_ID, city_postcode )
		) ENGINE = innodb');
        task_end();
        task_begin('Update Item Settings...');
        // Admin: full rights for all blogs (look 'ma, doing a natural join! :>)
        $query = "INSERT INTO T_items__item_settings( iset_item_ID, iset_name, iset_value )\n\t\t\t\t\t\tSELECT post_ID, 'hide_teaser', post_hideteaser\n\t\t\t\t\t\t\tFROM T_items__item";
        $DB->query($query);
        db_drop_col('T_items__item', 'post_hideteaser');
        task_end();
        task_begin('Upgrading hitlog table...');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\t\t\t\tADD COLUMN hit_keyphrase VARCHAR(255) DEFAULT NULL AFTER hit_keyphrase_keyp_ID");
        task_end();
        task_begin('Upgrading track__keyphrase...');
        $DB->query("ALTER TABLE T_track__keyphrase\n\t\t\t\t\t\tADD COLUMN keyp_count_refered_searches INT UNSIGNED DEFAULT 0 AFTER keyp_phrase,\n\t\t\t\t\t\tADD COLUMN keyp_count_internal_searches INT UNSIGNED DEFAULT 0 AFTER keyp_count_refered_searches");
        task_end();
        task_begin('Droping table internal searches...');
        $DB->query("DROP TABLE T_logs__internal_searches");
        task_end();
        task_begin('Upgrading users table...');
        db_add_col('T_users', 'user_rgn_ID', 'int(10) unsigned NULL AFTER user_ctry_ID');
        db_add_col('T_users', 'user_subrg_ID', 'int(10) unsigned NULL AFTER user_rgn_ID');
        db_add_col('T_users', 'user_city_ID', 'int(10) unsigned NULL AFTER user_subrg_ID');
        task_end();
        task_begin('Upgrading hitlog table...');
        $DB->query('UPDATE T_hitlog
						SET hit_type = "rss",
							hit_agent_type = "unknown"
						WHERE hit_agent_type = "rss"');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\t\t\t\t\t\tCHANGE COLUMN hit_agent_type hit_agent_type ENUM('robot','browser','unknown') DEFAULT 'unknown' NOT NULL");
        task_end();
        task_begin('Creating mail log table...');
        $DB->query('CREATE TABLE ' . $tableprefix . 'mail__log (
		  emlog_ID        INT(10) UNSIGNED NOT NULL auto_increment,
		  emlog_timestamp TIMESTAMP NOT NULL,
		  emlog_to        VARCHAR(255) DEFAULT NULL,
		  emlog_success   TINYINT(1) NOT NULL DEFAULT 0,
		  emlog_subject   VARCHAR(255) DEFAULT NULL,
		  emlog_headers   TEXT DEFAULT NULL,
		  emlog_message   TEXT DEFAULT NULL,
		  PRIMARY KEY     (emlog_ID)
		) ENGINE = myisam');
        task_end();
        set_upgrade_checkpoint('10600');
    }
    if ($old_db_version < 10700) {
        // part 5
        task_begin('Upgrading user notifications settings...');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "notify_published_comments", user_notify
							FROM T_users', 'Move notify settings from users to users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "notify_comment_moderation", user_notify_moderation
							FROM T_users', 'Move notify moderation settings from users to users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_PM", 1
							FROM T_users
								WHERE user_allow_msgform = 1 OR user_allow_msgform = 3', 'Set enable PM on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_PM", 0
							FROM T_users
								WHERE user_allow_msgform = 0 OR user_allow_msgform = 2', 'Set enable PM on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_email", 1
							FROM T_users
								WHERE user_allow_msgform > 1', 'Set enable email true on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_email", 0
							FROM T_users
								WHERE user_allow_msgform < 2', 'Set enable email false on users_usersettings');
        db_drop_col('T_users', 'user_notify');
        db_drop_col('T_users', 'user_notify_moderation');
        db_drop_col('T_users', 'user_allow_msgform');
        task_end();
        task_begin('Upgrading Item table...');
        db_add_col('T_items__item', 'post_ctry_ID', 'INT(10) UNSIGNED NULL');
        db_add_col('T_items__item', 'post_rgn_ID', 'INT(10) UNSIGNED NULL');
        db_add_col('T_items__item', 'post_subrg_ID', 'INT(10) UNSIGNED NULL');
        db_add_col('T_items__item', 'post_city_ID', 'INT(10) UNSIGNED NULL');
        task_end();
        task_begin('Upgrading users table...');
        db_drop_col('T_users', 'user_postcode');
        // Previously obsoleted
        db_drop_col('T_users', 'user_idmode');
        task_end();
        task_begin('Upgrading users fields table...');
        db_add_col('T_users__fielddefs', 'ufdf_bubbletip', 'varchar(2000) NULL');
        task_end();
        task_begin('Creating table for groups of messaging contacts...');
        $DB->query("CREATE TABLE IF NOT EXISTS T_messaging__contact_groups (\n\t\t\tcgr_ID      int(10) unsigned NOT NULL auto_increment,\n\t\t\tcgr_user_ID int(10) unsigned NOT NULL,\n\t\t\tcgr_name    varchar(50) NOT NULL,\n\t\t\tPRIMARY KEY cgr_ID (cgr_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Creating table for group users of messaging contacts...');
        $DB->query("CREATE TABLE T_messaging__contact_groupusers (\n\t\t\tcgu_user_ID int(10) unsigned NOT NULL,\n\t\t\tcgu_cgr_ID  int(10) unsigned NOT NULL,\n\t\t\tPRIMARY KEY cgu_PK (cgu_user_ID, cgu_cgr_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Upgrading mail log table...');
        db_add_col($tableprefix . 'mail__log', 'emlog_user_ID', 'INT(10) UNSIGNED DEFAULT NULL AFTER emlog_timestamp');
        task_end();
        set_upgrade_checkpoint('10700');
    }
    if ($old_db_version < 10800) {
        // part 6 aka between "i1-i2" and "i2"
        task_begin('Upgrading users table, add user status...');
        db_add_col('T_users', 'user_status', 'enum( "activated", "autoactivated", "closed", "deactivated", "emailchanged", "new" ) NOT NULL default "new" AFTER user_validated');
        $update_user_status_query = 'UPDATE T_users SET user_status = ';
        // check if new users must activate their account. If users are not required to activate their account, then all existing users will be considerated as activated user.
        $new_users_must_validate = $DB->get_var('SELECT set_value FROM T_settings WHERE set_name = ' . $DB->quote('newusers_mustvalidate'));
        if ($new_users_must_validate || $new_users_must_validate == NULL) {
            // newusers_mustvalidate setting is set to true, or it is not set at all. If it is not set, we know that the default value is true!
            // set activated status only for validated users
            $update_user_status_query .= $DB->quote('activated');
            $update_user_status_query .= ' WHERE user_validated = 1';
        } else {
            $update_user_status_query .= $DB->quote('autoactivated');
        }
        // set activated status for corresponding users
        $DB->query($update_user_status_query);
        db_drop_col('T_users', 'user_validated');
        task_end();
        set_upgrade_checkpoint('10800');
    }
    if ($old_db_version < 10900) {
        // part 7 aka "i3"
        task_begin('Upgrading user settings table...');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "show_online", 0
							FROM T_users
								WHERE user_showonline = 0', 'Set show online on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_ip", user_ip
							FROM T_users
								WHERE user_ip IS NOT NULL', 'Set user ip on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_domain", user_domain
							FROM T_users
								WHERE user_domain IS NOT NULL', 'Set user domain on users_usersettings');
        $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_browser", user_browser
							FROM T_users
								WHERE user_browser IS NOT NULL', 'Set user browser on users_usersettings');
        db_drop_col('T_users', 'user_showonline');
        db_drop_col('T_users', 'user_ip');
        db_drop_col('T_users', 'user_domain');
        db_drop_col('T_users', 'user_browser');
        task_end();
        task_begin('Upgrading user activation settings...');
        // Remove all last_activation_email timestamps because we will use date instead of them
        $DB->query('DELETE FROM T_users__usersettings WHERE uset_name = "last_activation_email"');
        task_end();
        task_begin('Upgrading Users table...');
        // Update user_status column add 'failedactivation' status
        $DB->query('ALTER TABLE T_users CHANGE user_status
					user_status enum( "activated", "autoactivated", "closed", "deactivated", "emailchanged", "failedactivation", "new" ) NOT NULL default "new"');
        db_add_col('T_users', 'user_created_fromIPv4', 'int(10) unsigned NOT NULL');
        db_add_col('T_users', 'user_email_dom_ID', 'int(10) unsigned NULL');
        $DB->query('ALTER TABLE T_users CHANGE dateYMDhour user_created_datetime DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        db_add_col('T_users', 'user_reg_ctry_ID', 'int(10) unsigned NULL AFTER user_age_max');
        db_add_col('T_users', 'user_profileupdate_ts', 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP');
        $DB->query('ALTER TABLE T_users ADD INDEX user_email ( user_email )');
        task_end();
        task_begin('Renaming Email log table...');
        $DB->query('RENAME TABLE ' . $tableprefix . 'mail__log TO T_email__log');
        task_end();
        task_begin('Creating email returns table...');
        $DB->query("CREATE TABLE T_email__returns (\n\t\t\t  emret_ID        INT(10) UNSIGNED NOT NULL auto_increment,\n\t\t\t  emret_address   VARCHAR(255) DEFAULT NULL,\n\t\t\t  emret_errormsg  VARCHAR(255) DEFAULT NULL,\n\t\t\t  emret_timestamp TIMESTAMP NOT NULL,\n\t\t\t  emret_headers   TEXT DEFAULT NULL,\n\t\t\t  emret_message   TEXT DEFAULT NULL,\n\t\t\t  emret_errtype   CHAR(1) NOT NULL DEFAULT 'U',\n\t\t\t  PRIMARY KEY     (emret_ID)\n\t\t\t) ENGINE = myisam");
        task_end();
        task_begin('Upgrading general settings table...');
        $DB->query('ALTER TABLE T_settings CHANGE set_value set_value VARCHAR( 5000 ) NULL');
        task_end();
        task_begin('Upgrading sessions table...');
        db_add_col('T_sessions', 'sess_device', 'VARCHAR(8) NOT NULL DEFAULT \'\'');
        task_end();
        task_begin('Creating table for Antispam IP Ranges...');
        $DB->query("CREATE TABLE T_antispam__iprange (\n\t\t\taipr_ID         int(10) unsigned NOT NULL auto_increment,\n\t\t\taipr_IPv4start  int(10) unsigned NOT NULL,\n\t\t\taipr_IPv4end    int(10) unsigned NOT NULL,\n\t\t\taipr_IP_timestamp        datetime not null DEFAULT '2000-01-01 00:00:00',\n\t\t\taipr_user_count int(10) unsigned DEFAULT 0,\n\t\t\tPRIMARY KEY aipr_ID (aipr_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Upgrading base domains table...');
        $DB->query("ALTER TABLE T_basedomains CHANGE dom_type dom_type ENUM( 'unknown', 'normal', 'searcheng', 'aggregator', 'email' ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT 'unknown'");
        $DB->query('ALTER TABLE T_basedomains DROP INDEX dom_name');
        $DB->query('ALTER TABLE T_basedomains DROP INDEX dom_type');
        $DB->query('ALTER TABLE T_basedomains ADD UNIQUE dom_type_name ( dom_type, dom_name )');
        task_end();
        /*** Update user_email_dom_ID for all already existing users ***/
        task_begin('Upgrading users email domains...');
        $DB->begin();
        // Get the users
        $uemails_SQL = new SQL();
        $uemails_SQL->SELECT('user_ID, user_email');
        $uemails_SQL->FROM('T_users');
        $users_emails = $DB->get_assoc($uemails_SQL->get());
        if (count($users_emails) > 0) {
            // Get all email domains
            $edoms_SQL = new SQL();
            $edoms_SQL->SELECT('dom_ID, dom_name');
            $edoms_SQL->FROM('T_basedomains');
            $edoms_SQL->WHERE('dom_type = \'email\'');
            $email_domains = $DB->get_assoc($edoms_SQL->get());
            // pre_dump( $email_domains );
            foreach ($users_emails as $user_ID => $user_email) {
                if (preg_match('#@(.+)#i', strtolower($user_email), $ematch)) {
                    // Get email domain from user's email address
                    $email_domain = $ematch[1];
                    $dom_ID = array_search($email_domain, $email_domains);
                    if (!$dom_ID) {
                        // Insert new email domain
                        $DB->query('INSERT INTO T_basedomains ( dom_type, dom_name )
							VALUES ( \'email\', ' . $DB->quote($email_domain) . ' )');
                        $dom_ID = $DB->insert_id;
                        // Memorize inserted domain to prevent duplicates
                        $email_domains[$dom_ID] = $email_domain;
                        // pre_dump( $dom_ID, $email_domain );
                    }
                    // Update user_email_dom_ID
                    $DB->query('UPDATE T_users
						SET user_email_dom_ID = ' . $DB->quote($dom_ID) . '
						WHERE user_ID = ' . $DB->quote($user_ID));
                }
            }
        }
        $DB->commit();
        task_end();
        task_begin('Upgrading users fields table...');
        // Drop index before increasing a size to avoid an error about "max key length is 767 bytes"
        $DB->query('ALTER TABLE T_users__fields DROP INDEX uf_varchar');
        // Modify field size
        $DB->query('ALTER TABLE T_users__fields CHANGE uf_varchar uf_varchar VARCHAR( 10000 ) NOT NULL');
        // Add index again with limited size in 255 because of utf8 == 765
        $DB->query('ALTER TABLE T_users__fields ADD INDEX uf_varchar ( uf_varchar(255) )');
        task_end();
        task_begin('Upgrading cron tasks table...');
        $DB->query('ALTER TABLE T_cron__task CHANGE ctsk_name ctsk_name VARCHAR(255) NOT NULL');
        task_end();
        task_begin('Upgrading comments table...');
        db_add_col('T_comments', 'comment_IP_ctry_ID', 'int(10) unsigned NULL AFTER comment_author_IP');
        task_end();
        task_begin('Creating table for Blocked Email Addreses...');
        $DB->query("CREATE TABLE {$tableprefix}email__blocked (\n\t\t\temblk_ID                    INT(10) UNSIGNED NOT NULL auto_increment,\n\t\t\temblk_address               VARCHAR(255) DEFAULT NULL,\n\t\t\temblk_status                ENUM ( 'unknown', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown',\n\t\t\temblk_sent_count            INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_sent_last_returnerror INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_prmerror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_tmperror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_spamerror_count       INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_othererror_count      INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\temblk_last_sent_ts          TIMESTAMP NULL,\n\t\t\temblk_last_error_ts         TIMESTAMP NULL,\n\t\t\tPRIMARY KEY                 (emblk_ID),\n\t\t\tUNIQUE                      emblk_address (emblk_address)\n\t\t) ENGINE = myisam");
        task_end();
        task_begin('Upgrading email log table...');
        // Get old values of emlog_success field
        $SQL = new SQL();
        $SQL->SELECT('emlog_ID');
        $SQL->FROM('T_email__log');
        $SQL->WHERE('emlog_success = 0');
        $email_failed_logs = $DB->get_col($SQL->get());
        // Change a field emlog_success to new format
        $DB->query('ALTER TABLE T_email__log CHANGE emlog_success emlog_result ENUM ( "ok", "error", "blocked" ) NOT NULL DEFAULT "ok"');
        if (!empty($email_failed_logs)) {
            // Update only the failed email logs to new values
            // Do NOT update the success email logs, because we already have a result type 'ok' as default
            $DB->query('UPDATE T_email__log
					SET emlog_result = ' . $DB->quote('error') . '
				WHERE emlog_ID IN ( ' . $DB->quote($email_failed_logs) . ' )');
        }
        task_end();
        set_upgrade_checkpoint('10900');
    }
    if ($old_db_version < 10970) {
        // part 8/a trunk aka first part of "i4"
        task_begin('Upgrading Locales table...');
        db_add_col('T_locales', 'loc_transliteration_map', 'VARCHAR(10000) NOT NULL default \'\' AFTER loc_priority');
        task_end();
        task_begin('Upgrading general settings table...');
        $DB->query('UPDATE T_settings SET set_name = ' . $DB->quote('smart_view_count') . ' WHERE set_name = ' . $DB->quote('smart_hit_count'));
        // This query below was added later to turn OFF smart view counting on upgrade from v4 to v5 for better performance
        $DB->query('DELETE FROM T_settings WHERE set_name = ' . $DB->quote('smart_view_count'));
        task_end();
        task_begin('Upgrading sessions table...');
        $DB->query("UPDATE T_sessions SET sess_lastseen = concat( '2000-01-01 ', time( sess_lastseen ) )\n\t\t\t\t\t\tWHERE date( sess_lastseen ) = '1970-01-01'");
        $DB->query("ALTER TABLE T_sessions CHANGE COLUMN sess_lastseen sess_lastseen_ts TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' COMMENT 'User last logged activation time. Value may be off by up to 60 seconds'");
        db_add_col('T_sessions', 'sess_start_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER sess_hitcount");
        $DB->query('UPDATE T_sessions SET sess_start_ts = TIMESTAMPADD( SECOND, -1, sess_lastseen_ts )');
        db_drop_col('T_sessions', 'sess_hitcount');
        task_end();
        task_begin('Upgrading users table...');
        db_add_col('T_users', 'user_lastseen_ts', 'TIMESTAMP NULL AFTER user_created_datetime');
        $DB->query('UPDATE T_users SET user_lastseen_ts = ( SELECT MAX( sess_lastseen_ts ) FROM T_sessions WHERE sess_user_ID = user_ID )');
        $DB->query('UPDATE T_users SET user_profileupdate_ts = user_created_datetime WHERE user_profileupdate_ts < user_created_datetime');
        $DB->query("ALTER TABLE T_users CHANGE COLUMN user_profileupdate_ts user_profileupdate_date DATE NOT NULL DEFAULT '2000-01-01' COMMENT 'Last day when the user has updated some visible field in his profile.'");
        task_end();
        task_begin('Updating versions table...');
        db_add_col('T_items__version', 'iver_ID', 'INT UNSIGNED NOT NULL FIRST');
        $DB->query('ALTER TABLE T_items__version DROP INDEX iver_itm_ID, ADD INDEX iver_ID_itm_ID ( iver_ID , iver_itm_ID )');
        task_end();
        task_begin('Upgrading messaging contact group users...');
        db_add_foreign_key('T_messaging__contact_groupusers', 'cgu_cgr_ID', 'T_messaging__contact_groups', 'cgr_ID', 'ON DELETE CASCADE');
        task_end();
        task_begin('Creating table for a latest version of the POT file...');
        $DB->query("CREATE TABLE T_i18n_original_string (\n\t\t\tiost_ID        int(10) unsigned NOT NULL auto_increment,\n\t\t\tiost_string    varchar(10000) NOT NULL default '',\n\t\t\tiost_inpotfile tinyint(1) NOT NULL DEFAULT 0,\n\t\t\tPRIMARY KEY (iost_ID)\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Creating table for a latest versions of the PO files...');
        $DB->query("CREATE TABLE T_i18n_translated_string (\n\t\t\titst_ID       int(10) unsigned NOT NULL auto_increment,\n\t\t\titst_iost_ID  int(10) unsigned NOT NULL,\n\t\t\titst_locale   varchar(20) NOT NULL default '',\n\t\t\titst_standard varchar(10000) NOT NULL default '',\n\t\t\titst_custom   varchar(10000) NULL,\n\t\t\titst_inpofile tinyint(1) NOT NULL DEFAULT 0,\n\t\t\tPRIMARY KEY (itst_ID)\n\t\t) ENGINE = innodb DEFAULT CHARSET = utf8");
        task_end();
        task_begin('Updating Antispam IP Ranges table...');
        db_add_col('T_antispam__iprange', 'aipr_status', 'enum( \'trusted\', \'suspect\', \'blocked\' ) NULL DEFAULT NULL');
        db_add_col('T_antispam__iprange', 'aipr_block_count', 'int(10) unsigned DEFAULT 0');
        $DB->query("ALTER TABLE T_antispam__iprange CHANGE COLUMN aipr_user_count aipr_user_count int(10) unsigned DEFAULT 0");
        task_end();
        set_upgrade_checkpoint('10970');
    }
    if ($old_db_version < 10975) {
        // part 8/b trunk aka first part of "i4"
        task_begin('Creating default antispam IP ranges... ');
        $DB->query('
			INSERT INTO T_antispam__iprange ( aipr_IPv4start, aipr_IPv4end, aipr_status )
			VALUES ( ' . $DB->quote(ip2int('127.0.0.0')) . ', ' . $DB->quote(ip2int('127.0.0.255')) . ', "trusted" ),
				( ' . $DB->quote(ip2int('10.0.0.0')) . ', ' . $DB->quote(ip2int('10.255.255.255')) . ', "trusted" ),
				( ' . $DB->quote(ip2int('172.16.0.0')) . ', ' . $DB->quote(ip2int('172.31.255.255')) . ', "trusted" ),
				( ' . $DB->quote(ip2int('192.168.0.0')) . ', ' . $DB->quote(ip2int('192.168.255.255')) . ', "trusted" )
			');
        task_end();
        set_upgrade_checkpoint('10975');
    }
    if ($old_db_version < 11000) {
        // part 8/c trunk aka first part of "i4"
        task_begin('Adding new countries...');
        // IGNORE is needed for upgrades from DB version 9970 or later
        $DB->query('INSERT IGNORE INTO T_regional__country ( ctry_code, ctry_name, ctry_curr_ID ) VALUES ( \'ct\', \'Catalonia\', \'2\' )');
        task_end();
        task_begin('Upgrading message thread statuses table...');
        db_add_col('T_messaging__threadstatus', 'tsta_thread_leave_msg_ID', 'int(10) unsigned NULL DEFAULT NULL');
        task_end();
        task_begin('Upgrading Item Settings...');
        // Convert item custom fields to custom item settings ( move custom fields from T_items__item table to T_items__item_settings table )
        $query = "INSERT INTO T_items__item_settings( iset_item_ID, iset_name, iset_value ) ";
        for ($i = 1; $i <= 8; $i++) {
            // For each custom fields:
            if ($i > 1) {
                $query .= ' UNION';
            }
            $field_name = $i > 5 ? 'varchar' . ($i - 5) : 'double' . $i;
            $query .= " SELECT post_ID, 'custom_" . $field_name . "', post_" . $field_name . "\n\t\t\t\t\t\t\tFROM T_items__item WHERE post_" . $field_name . " IS NOT NULL";
        }
        $DB->query($query);
        for ($i = 1; $i <= 5; $i++) {
            // drop custom double columns from items tabe
            db_drop_col('T_items__item', 'post_double' . $i);
        }
        for ($i = 1; $i <= 3; $i++) {
            // drop custom varchar columns from items tabe
            db_drop_col('T_items__item', 'post_varchar' . $i);
        }
        // Convert post_editor_code item field to item settings
        $DB->query('INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "editor_code", post_editor_code
							FROM T_items__item
							WHERE post_editor_code IS NOT NULL');
        db_drop_col('T_items__item', 'post_editor_code');
        // Convert post_metadesc item field to item settings
        $DB->query('INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "post_metadesc", post_metadesc
							FROM T_items__item
							WHERE post_metadesc IS NOT NULL');
        db_drop_col('T_items__item', 'post_metadesc');
        // Convert and rename post_metakeywords item field to post_custom_headers item settings
        $DB->query('INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "post_custom_headers", post_metakeywords
							FROM T_items__item
							WHERE post_metakeywords IS NOT NULL');
        db_drop_col('T_items__item', 'post_metakeywords');
        task_end();
        task_begin('Upgrading items table...');
        // Drop not used column
        db_drop_col('T_items__item', 'post_commentsexpire');
        task_end();
        task_begin('Adding new video file types...');
        $ftyp = $DB->get_row('SELECT ftyp_ID, ftyp_extensions
									FROM T_filetypes
									WHERE ftyp_mimetype = "video/mp4"
									AND ftyp_extensions NOT LIKE "%f4v%"
									LIMIT 1');
        if ($ftyp) {
            // Add f4v extension to mp4 file type, if not exists
            $DB->query('UPDATE T_filetypes SET ftyp_extensions = "' . $DB->escape($ftyp->ftyp_extensions . ' f4v') . '"
							WHERE ftyp_ID = ' . $DB->quote($ftyp->ftyp_ID));
        }
        // Add flv file type if not exists
        if (!db_key_exists('T_filetypes', 'ftyp_extensions', '"flv"')) {
            $DB->query('INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("flv", "Flash video file", "video/x-flv", "", "browser", "registered")', 'Add "flv" file type');
        }
        // Add swf file type if not exists
        if (!db_key_exists('T_filetypes', 'ftyp_extensions', '"swf"')) {
            $DB->query('INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("swf", "Flash video file", "application/x-shockwave-flash", "", "browser", "registered")', 'Add "swf" file type');
        }
        task_end();
        task_begin('Upgrading custom item settings...');
        $DB->begin();
        // Convert latitude and longitude from custom setting to normal item settings
        // Get those blog ids where Latitude and Longitude are both set
        $result = $DB->get_col('SELECT cs_left.cset_coll_ID
									FROM T_coll_settings as cs_left
									INNER JOIN T_coll_settings as cs_right ON cs_left.cset_coll_ID = cs_right.cset_coll_ID
									WHERE cs_left.cset_name = "custom_double3" AND cs_left.cset_value = "Latitude" AND
										cs_right.cset_name = "custom_double4" AND cs_right.cset_value = "Longitude"');
        if ($result) {
            // blogs were found where Latitude and Longitude custom fields were set for google maps plugin
            // Set "Show location coordinates" on where Latitude and Longitude were set
            $query_values = '( ' . implode(', "show_location_coordinates", 1 ), ( ', $result) . ', "show_location_coordinates", 1 )';
            $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES ' . $query_values);
            $coll_ids = implode(', ', $result);
            // Update latitude Item settings
            $DB->query('UPDATE T_items__item_settings SET iset_name = "latitude"
							WHERE iset_name = "custom_double3" AND iset_item_ID IN (
								SELECT post_ID FROM T_items__item
								INNER JOIN T_categories ON post_main_cat_ID = cat_ID
								WHERE cat_blog_ID IN ( ' . $coll_ids . ' )
							)');
            // Update longitude Item settings
            $DB->query('UPDATE T_items__item_settings SET iset_name = "longitude"
							WHERE iset_name = "custom_double4" AND iset_item_ID IN (
								SELECT post_ID FROM T_items__item
								INNER JOIN T_categories ON post_main_cat_ID = cat_ID
								WHERE cat_blog_ID IN ( ' . $coll_ids . ' )
							)');
            // Delete proessed latitude & longitude custom fields from collection settings
            $DB->query('DELETE FROM T_coll_settings
						WHERE ( cset_name = "custom_double3" OR cset_name = "custom_double4" ) AND
							cset_coll_ID IN ( ' . $coll_ids . ' )');
        }
        $DB->commit();
        // End convert latitude and longitude
        $DB->begin();
        // Convert custom fields
        // Delete not used custom fields
        $DB->query('DELETE FROM T_coll_settings WHERE ( cset_value IS NULL OR cset_value = "" ) AND cset_name LIKE "custom\\_%"');
        // Set custom double fields count
        $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT cset_coll_ID, "count_custom_double", COUNT( cset_name )
						FROM T_coll_settings
						WHERE cset_name LIKE "custom\\_double%"
						GROUP BY cset_coll_ID');
        // Set custom varchar fields count
        $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT cset_coll_ID, "count_custom_varchar", COUNT( cset_name )
						FROM T_coll_settings
						WHERE cset_name LIKE "custom\\_varchar%"
						GROUP BY cset_coll_ID');
        // Select all custom fields from all blog, to create converted field values
        $result = $DB->get_results('SELECT cset_coll_ID as coll_ID, cset_name as name, cset_value as value
										FROM T_coll_settings
										WHERE cset_name LIKE "custom\\_%"
										ORDER BY cset_coll_ID, cset_name');
        if (!empty($result)) {
            // There are custom fields in blog settings
            $convert_field_values = '';
            $reorder_field_values = '';
            $old_prefix = "";
            $old_coll_ID = "";
            foreach ($result as $row) {
                // process each custom field
                $custom_id = uniqid('');
                $prefix = substr($row->name, 7, 6) === 'double' ? 'custom_double' : 'custom_varchar';
                // replace custom_double{N} and custom_varchar{N} values with a custom_id where N is number
                $convert_field_values .= '( ' . $row->coll_ID . ', "' . $row->name . '", "' . $custom_id . '" ), ';
                // add new custom_double_{customid} and custom_varchar_{customid} entries with the old correspinding custom field values
                $convert_field_values .= '( ' . $row->coll_ID . ', "' . $prefix . '_' . $custom_id . '", "' . $row->value . '" ), ';
                // create reorder values to replace e.g. custom_double2 to custom_double1 if custom_double1 doesn't exists yet
                $index = $old_prefix == $prefix && $old_coll_ID == $row->coll_ID ? $index + 1 : 1;
                $reorder_field_values .= '( ' . $row->coll_ID . ', "' . $prefix . $index . '", "' . $custom_id . '" ), ';
                $old_prefix = $prefix;
                $old_coll_ID = $row->coll_ID;
            }
            $convert_field_values = substr($convert_field_values, 0, -2);
            $reorder_field_values = substr($reorder_field_values, 0, -2);
            // Convert custom fields in collection setting
            $DB->query('REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES ' . $convert_field_values);
            // Update double custom field name_ids in item settings table
            $DB->query('UPDATE T_items__item_settings SET iset_name = (
								SELECT CONCAT( "custom_double_", cset_value ) FROM T_coll_settings
									INNER JOIN T_categories ON cset_coll_ID = cat_blog_ID
									INNER JOIN T_items__item ON cat_ID = post_main_cat_ID
									WHERE cset_name = iset_name AND post_ID  = iset_item_ID )
							WHERE iset_name LIKE "custom\\_double%"');
            // Update varchar custom field name_ids in item settings table
            $DB->query('UPDATE T_items__item_settings SET iset_name = (
								SELECT CONCAT( "custom_varchar_", cset_value ) FROM T_coll_settings
									INNER JOIN T_categories ON cset_coll_ID = cat_blog_ID
									INNER JOIN T_items__item ON cat_ID = post_main_cat_ID
									WHERE cset_name = iset_name AND post_ID  = iset_item_ID )
							WHERE iset_name LIKE "custom\\_varchar%"');
            // Reorder custom fields in collection settings
            $DB->query('REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES ' . $reorder_field_values);
        }
        $DB->commit();
        // End convert custom fields
        task_end();
        task_begin('Convert group users permissions to pluggable permissions...');
        $DB->query('REPLACE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
						SELECT grp_ID, "perm_users", grp_perm_users
							FROM T_groups');
        db_drop_col('T_groups', 'grp_perm_users');
        task_end();
        task_begin('Update Post Types... ');
        $DB->query("REPLACE INTO T_items__type ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 4000, 'Advertisement' )");
        task_end();
        task_begin('Update files table... ');
        db_add_col('T_files', 'file_hash', 'char(32) default NULL');
        task_end();
        task_begin('Create table for files voting...');
        $DB->query('CREATE TABLE ' . $tableprefix . 'files__vote (
				fvot_file_ID       int(11) UNSIGNED NOT NULL,
				fvot_user_ID       int(11) UNSIGNED NOT NULL,
				fvot_like          tinyint(1),
				fvot_inappropriate tinyint(1),
				fvot_spam          tinyint(1),
				primary key (fvot_file_ID, fvot_user_ID)
			) ENGINE = innodb');
        task_end();
        task_begin('Create table for users reporting...');
        $DB->query("CREATE TABLE T_users__reports (\n\t\t\turep_target_user_ID int(11) unsigned NOT NULL,\n\t\t\turep_reporter_ID    int(11) unsigned NOT NULL,\n\t\t\turep_status         enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ),\n\t\t\turep_info           varchar(240),\n\t\t\turep_datetime\t\tdatetime NOT NULL,\n\t\t\tPRIMARY KEY ( urep_target_user_ID, urep_reporter_ID )\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Upgrading skins type...');
        $DB->query("ALTER TABLE T_skins__skin MODIFY COLUMN skin_type enum('normal','feed','sitemap','mobile','tablet') NOT NULL default 'normal'");
        task_end();
        task_begin('Upgrading blogs skins...');
        // Convert blog skin ID to blog settings
        $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT blog_ID, "normal_skin_ID", blog_skin_ID
						FROM T_blogs');
        db_drop_col('T_blogs', 'blog_skin_ID');
        task_end();
        task_begin('Update categories table... ');
        db_add_col('T_categories', 'cat_meta', 'tinyint(1) NOT NULL DEFAULT 0');
        db_add_col('T_categories', 'cat_lock', 'tinyint(1) NOT NULL DEFAULT 0');
        task_end();
        task_begin('Plugin settings update...');
        $all_blog_ids = $DB->get_col('SELECT blog_ID FROM T_blogs');
        $plugin_ids = $DB->get_assoc('SELECT pset_plug_ID, pset_value FROM T_pluginsettings WHERE pset_name = "render_comments"');
        $insert_values = '';
        foreach ($all_blog_ids as $blog_ID) {
            foreach ($plugin_ids as $plugin_ID => $setting_value) {
                $apply_comment_rendering = $setting_value ? 'stealth' : 'never';
                $insert_values .= '( ' . $blog_ID . ', "plugin' . $plugin_ID . '_coll_apply_comment_rendering", "' . $apply_comment_rendering . '" ),';
            }
        }
        if (!empty($insert_values)) {
            $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						VALUES ' . substr($insert_values, 0, strlen($insert_values) - 1));
        }
        $DB->query('DELETE FROM T_pluginsettings WHERE pset_name = "render_comments"');
        task_end();
        task_begin('Creating comment prerendering cache table...');
        $DB->query("CREATE TABLE T_comments__prerendering (\n\t\t\tcmpr_cmt_ID INT(11) UNSIGNED NOT NULL,\n\t\t\tcmpr_format ENUM('htmlbody','entityencoded','xml','text') NOT NULL,\n\t\t\tcmpr_renderers TEXT NOT NULL,\n\t\t\tcmpr_content_prerendered MEDIUMTEXT NULL,\n\t\t\tcmpr_datemodified TIMESTAMP NOT NULL,\n\t\t\tPRIMARY KEY (cmpr_cmt_ID, cmpr_format)\n\t\t) ENGINE = innodb");
        db_add_col('T_comments', 'comment_renderers', "TEXT NOT NULL AFTER comment_content");
        $DB->query('UPDATE T_comments SET comment_renderers = "default"');
        task_end();
        task_begin('Upgrading plugins table...');
        db_drop_col('T_plugins', 'plug_apply_rendering');
        task_end();
        task_begin('Upgrading Auto_P plugin...');
        $blog_settings = $DB->get_assoc('SELECT cset_coll_ID, cset_value FROM T_coll_settings WHERE cset_name = "comment_autobr"');
        $insert_values = array();
        $plugin_ids = $DB->get_col('SELECT plug_ID FROM T_plugins WHERE plug_code = "b2WPAutP"');
        foreach ($blog_settings as $blog_ID => $blog_setting_value) {
            foreach ($plugin_ids as $plugin_ID) {
                switch ($blog_setting_value) {
                    case 'never':
                        $apply_comment_rendering = 'never';
                        break;
                    case 'optional':
                        $apply_comment_rendering = 'opt-out';
                        break;
                    case 'always':
                        $apply_comment_rendering = 'stealth';
                        break;
                    default:
                        break 2;
                }
                $insert_values[] = '( ' . $blog_ID . ', "plugin' . $plugin_ID . '_coll_apply_comment_rendering", "' . $apply_comment_rendering . '" )';
            }
        }
        if (count($insert_values) > 0) {
            $DB->query('REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						VALUES ' . implode(',', $insert_values));
        }
        $DB->query('DELETE FROM T_coll_settings WHERE cset_name = "comment_autobr"');
        $DB->query('UPDATE T_comments SET comment_content = REPLACE( REPLACE( comment_content, "<br>\\n", "\\n" ), "<br />\\n", "\\n" )');
        task_end();
        set_upgrade_checkpoint('11000');
    }
    if ($old_db_version < 11010) {
        // part 9 trunk aka second part of "i4"
        task_begin('Upgrading post statuses...');
        $DB->query("ALTER TABLE T_items__item CHANGE COLUMN post_status post_status enum('published','community','deprecated','protected','private','review','draft','redirected') NOT NULL default 'published'");
        $DB->query("ALTER TABLE T_items__version CHANGE COLUMN iver_status iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') NULL");
        $DB->query("ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_poststatuses bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') NOT NULL default ''");
        $DB->query("ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_poststatuses bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') NOT NULL default ''");
        task_end();
        task_begin('Upgrading groups table...');
        $pbloggers_renamed_to_moderators = $DB->query('UPDATE T_groups SET grp_name = "Moderators" WHERE grp_ID = 2 AND grp_name = "Privileged Bloggers"');
        // Update administrators and moderators users coll setting permissions with new permissions
        // Note we can change moderators permission if the group name and ID was not changed after the original install
        $moderators_condition = $pbloggers_renamed_to_moderators ? ' OR bloggroup_group_ID = 2' : '';
        $DB->query("UPDATE T_coll_group_perms SET bloggroup_perm_poststatuses = 'published,community,deprecated,protected,private,review,draft' WHERE bloggroup_group_ID = 1" . $moderators_condition);
        // Change groups name
        $DB->query('UPDATE T_groups SET grp_name = "Trusted Users" WHERE grp_ID = 3 AND grp_name = "Bloggers"');
        $DB->query('UPDATE T_groups SET grp_name = "Normal Users" WHERE grp_ID = 4 AND grp_name = "Basic Users"');
        // Get "Misbehaving/Suspect Users" group ID
        $suspect_query = 'SELECT grp_ID
						FROM T_groups
						WHERE grp_name = "Misbehaving/Suspect Users"
						ORDER BY grp_ID DESC
						LIMIT 1';
        $suspect_group_ID = $DB->get_var($suspect_query);
        if (empty($suspect_group_ID)) {
            // suspect group doesn't exists, check spammers because probably it does not exists either
            $insert_values = '( "Misbehaving/Suspect Users" )';
            // Get "Spammers/Restricted Users" group ID
            $query = 'SELECT grp_ID
					FROM T_groups
					WHERE grp_name = "Spammers/Restricted Users"
					ORDER BY grp_ID DESC
					LIMIT 1';
            $spammers_group_ID = $DB->get_var($query);
            if (empty($spammers_group_ID)) {
                $insert_values .= ', ( "Spammers/Restricted Users" )';
            }
            // Insert two new group
            $DB->query('INSERT INTO T_groups ( grp_name )
						VALUES ' . $insert_values);
            $suspect_group_ID = $DB->get_var($suspect_query);
            if ($suspect_group_ID) {
                // Set coll setting permissions for Misbehaving/Suspect Users in Forums
                $query = "\n\t\t\t\t\tINSERT INTO T_coll_group_perms( bloggroup_blog_ID, bloggroup_group_ID, bloggroup_ismember,\n\t\t\t\t\t\tbloggroup_perm_poststatuses, bloggroup_perm_delpost, bloggroup_perm_edit_ts,\n\t\t\t\t\t\tbloggroup_perm_own_cmts, bloggroup_perm_vote_spam_cmts, bloggroup_perm_draft_cmts, bloggroup_perm_publ_cmts, bloggroup_perm_depr_cmts,\n\t\t\t\t\t\tbloggroup_perm_cats, bloggroup_perm_properties,\n\t\t\t\t\t\tbloggroup_perm_media_upload, bloggroup_perm_media_browse, bloggroup_perm_media_change )\n\t\t\t\t\tSELECT blog_ID, " . $suspect_group_ID . ", 1, 'review,draft', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n\t\t\t\t\t\tFROM T_blogs WHERE blog_ID = 5 AND blog_shortname = 'Forums'";
                $DB->query($query);
            }
        }
        task_end();
        task_begin('Upgrading blogs table...');
        db_add_col('T_blogs', 'blog_type', 'ENUM( "std", "photo", "group", "forum", "manual" ) DEFAULT "std" NOT NULL');
        task_end();
        task_begin('Upgrading comment statuses...');
        $DB->query("ALTER TABLE T_comments CHANGE COLUMN comment_status comment_status ENUM('published','community','deprecated','protected','private','review','draft','trash') DEFAULT 'published' NOT NULL");
        task_end();
        task_begin('Updating collection user/group permissions...');
        db_add_col('T_coll_user_perms', 'bloguser_perm_cmtstatuses', "set('review','draft','private','protected','deprecated','community','published') NOT NULL default '' AFTER bloguser_perm_vote_spam_cmts");
        db_add_col('T_coll_user_perms', 'bloguser_perm_edit_cmt', "ENUM('no','own','anon','lt','le','all') NOT NULL default 'no' AFTER bloguser_perm_cmtstatuses");
        db_add_col('T_coll_group_perms', 'bloggroup_perm_cmtstatuses', "set('review','draft','private','protected','deprecated','community','published') NOT NULL default '' AFTER bloggroup_perm_vote_spam_cmts");
        db_add_col('T_coll_group_perms', 'bloggroup_perm_edit_cmt', "ENUM('no','own','anon','lt','le','all') NOT NULL default 'no' AFTER bloggroup_perm_cmtstatuses");
        // Add access to those comment statuses for what user had before
        $DB->query('UPDATE T_coll_user_perms
					SET bloguser_perm_cmtstatuses = ( bloguser_perm_publ_cmts * 1 ) | ( bloguser_perm_depr_cmts * 4 ) | ( bloguser_perm_draft_cmts * 64 )');
        // Add access to all cmt statuses for those users which had edit permission on all comment statuses
        $DB->query('UPDATE T_coll_user_perms
					SET bloguser_perm_cmtstatuses = "published,community,deprecated,protected,private,review,draft", bloguser_perm_edit_cmt = "all"
					WHERE bloguser_perm_publ_cmts <> 0 AND bloguser_perm_depr_cmts <> 0 AND bloguser_perm_draft_cmts <> 0');
        // Add "lower then" edit permission to those users who had permission to edit published or draft comments
        $DB->query('UPDATE T_coll_user_perms
					SET bloguser_perm_edit_cmt = "lt"
					WHERE ( bloguser_perm_cmtstatuses & 65 ) != 0 AND bloguser_perm_edit_cmt = "no"');
        // Add access to those comment statuses for what group had before
        $DB->query('UPDATE T_coll_group_perms
					SET bloggroup_perm_cmtstatuses = ( bloggroup_perm_publ_cmts * 1 ) | ( bloggroup_perm_depr_cmts * 4 ) | ( bloggroup_perm_draft_cmts * 64 )');
        // Add access to all cmt statuses for those groups which had edit permission on all comment statuses
        $DB->query('UPDATE T_coll_group_perms
					SET bloggroup_perm_cmtstatuses = "published,community,deprecated,protected,private,review,draft", bloggroup_perm_edit_cmt = "all"
					WHERE bloggroup_perm_publ_cmts <> 0 AND bloggroup_perm_depr_cmts <> 0 AND bloggroup_perm_draft_cmts <> 0');
        // Add "lower then" edit permission to those groups who had permission to edit published or draft comments
        $DB->query('UPDATE T_coll_group_perms
					SET bloggroup_perm_edit_cmt = "lt"
					WHERE ( bloggroup_perm_cmtstatuses & 65 ) != 0 AND bloggroup_perm_edit_cmt = "no"');
        db_drop_col('T_coll_user_perms', 'bloguser_perm_draft_cmts');
        db_drop_col('T_coll_user_perms', 'bloguser_perm_publ_cmts');
        db_drop_col('T_coll_user_perms', 'bloguser_perm_depr_cmts');
        db_drop_col('T_coll_group_perms', 'bloggroup_perm_draft_cmts');
        db_drop_col('T_coll_group_perms', 'bloggroup_perm_publ_cmts');
        db_drop_col('T_coll_group_perms', 'bloggroup_perm_depr_cmts');
        db_add_col('T_coll_user_perms', 'bloguser_perm_delcmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts');
        db_add_col('T_coll_group_perms', 'bloggroup_perm_delcmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts');
        // GRANT delete comment perms for moderators
        $DB->query('UPDATE T_coll_group_perms
					SET bloggroup_perm_delcmts = 1
					WHERE bloggroup_perm_edit_cmt = "le" OR bloggroup_perm_edit_cmt = "all"');
        $DB->query("ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_own_cmts bloguser_perm_recycle_owncmts tinyint NOT NULL default 0");
        $DB->query("ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_own_cmts bloggroup_perm_recycle_owncmts tinyint NOT NULL default 0");
        task_end();
        task_begin('Updating blogs settings...');
        $DB->query('UPDATE T_coll_settings SET cset_value = "blog" WHERE cset_name = "enable_goto_blog" AND cset_value = "1"');
        $DB->query('UPDATE T_coll_settings SET cset_value = "no" WHERE cset_name = "enable_goto_blog" AND cset_value = "0"');
        task_end();
        set_upgrade_checkpoint('11010');
    }
    if ($old_db_version < 11020) {
        // part 10 trunk aka third part of "i4"
        task_begin('Upgrading users table...');
        // Get all users with defined IPs
        $users_SQL = new SQL();
        $users_SQL->SELECT('user_ID, user_created_fromIPv4');
        $users_SQL->FROM('T_users');
        $users_SQL->WHERE('user_created_fromIPv4 IS NOT NULL');
        $users_SQL->WHERE_and('user_created_fromIPv4 != ' . $DB->quote(ip2int('0.0.0.0')));
        $users_SQL->WHERE_and('user_created_fromIPv4 != ' . $DB->quote(ip2int('127.0.0.1')));
        $users = $DB->get_assoc($users_SQL->get());
        // Get user's IPs from settings table
        $settings_SQL = new SQL();
        $settings_SQL->SELECT('uset_user_ID, uset_value');
        $settings_SQL->FROM('T_users__usersettings');
        $settings_SQL->WHERE('uset_name = "user_ip"');
        if (count($users) > 0) {
            // Get IPs only for users which have not IP in T_users table
            $settings_SQL->WHERE_and('uset_user_ID NOT IN (' . $DB->quote(array_keys($users)) . ')');
        }
        $settings = $DB->get_assoc($settings_SQL->get());
        if (count($users) > 0 || count($settings) > 0) {
            $users_settings_insert_sql = array();
            foreach ($users as $user_ID => $user_IP) {
                $users_settings_insert_sql[] = '( ' . $DB->quote($user_ID) . ', "created_fromIPv4", ' . $DB->quote($user_IP) . ' )';
            }
            foreach ($settings as $user_ID => $user_IP) {
                $users_settings_insert_sql[] = '( ' . $DB->quote($user_ID) . ', "created_fromIPv4", ' . $DB->quote(ip2int($user_IP)) . ' )';
            }
            // Insert IPs values into settings table
            $DB->query('INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
				VALUES ' . implode(', ', $users_settings_insert_sql));
        }
        // Remove old IPs from settings table
        $DB->query('DELETE FROM T_users__usersettings
			WHERE uset_name = "user_ip"');
        db_drop_col('T_users', 'user_created_fromIPv4');
        task_end();
        set_upgrade_checkpoint('11020');
    }
    if ($old_db_version < 11025) {
        // part 11 trunk aka fourth part of "i4"
        task_begin('Upgrading items table...');
        $DB->query("UPDATE T_items__item SET post_datecreated = concat( '2000-01-01 ', time( post_datecreated ) )\n\t\t\t\t\t\tWHERE date( post_datecreated ) = '1970-01-01'");
        $DB->query("UPDATE T_items__item SET post_datemodified = concat( '2000-01-01 ', time( post_datemodified ) )\n\t\t\t\t\t\tWHERE date( post_datemodified ) = '1970-01-01'");
        $DB->query("ALTER TABLE T_items__item CHANGE COLUMN post_datecreated post_datecreated TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'");
        $DB->query("ALTER TABLE T_items__item CHANGE COLUMN post_datemodified post_datemodified TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'");
        db_add_col('T_items__item', 'post_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER post_datemodified");
        $DB->query('UPDATE T_items__item SET post_last_touched_ts = post_datemodified');
        task_end();
        /*
         * ADD UPGRADES FOR i4 BRANCH __ABOVE__ IN THIS BLOCK.
         *
         * This part will be included in trunk and i4 branches
         */
        set_upgrade_checkpoint('11025');
    }
    // In some upgrade versions ( currently only in "i5" ) we would like to create profile pictures links from the user's files in the profile pictures folder
    // To be able to do that we need an up to date database version, so we will create profile pictures after the ugrade script run successfully.
    // Set this $create_profile_picture_links to true only in those upgrade block where it's required.
    $create_profile_picture_links = false;
    if ($old_db_version < 11100) {
        // part 12 trunk aka "i5"
        task_begin('Update links table...');
        db_add_col('T_links', 'link_usr_ID', 'int(11) unsigned  NULL COMMENT "Used for linking files to users (user profile picture)" AFTER link_cmt_ID');
        db_add_index('T_links', 'link_usr_ID', 'link_usr_ID');
        task_end();
        task_begin('Creating links for users profile pictures...');
        // Create links for main profile pictures
        $link_create_date = date2mysql(time());
        $DB->query('INSERT INTO T_links( link_datecreated, link_datemodified, link_usr_ID, link_file_ID, link_position, link_order )
						SELECT ' . $DB->quote($link_create_date) . ', ' . $DB->quote($link_create_date) . ', user_ID, user_avatar_file_ID, "", 1
						FROM T_users
						WHERE user_avatar_file_ID IS NOT NULL');
        // Set $create_profile_picture_links to true to create links for all files from the users profile_pictures folder
        $create_profile_picture_links = true;
        task_end();
        task_begin('Upgrading custom item settings...');
        $DB->begin();
        // Add names for custom fields
        // Select all custom fields from all blogs, to create field names
        $result = $DB->get_results('SELECT cset_coll_ID as coll_ID, cset_name as name, cset_value as value
										FROM T_coll_settings
										WHERE cset_name LIKE "custom\\_double\\_%"
										   OR cset_name LIKE "custom\\_varchar\\_%"
										ORDER BY cset_coll_ID, cset_name');
        if (!empty($result)) {
            // There are custom fields in blog settings
            $insert_field_names = '';
            foreach ($result as $row) {
                // process each custom field
                $field_guid = preg_replace('/^custom_(double|varchar)_([a-f0-9\\-]+)$/', '$2', $row->name);
                // Replace special chars/umlauts, if we can convert charsets:
                load_funcs('locales/_charset.funcs.php');
                $field_name = strtolower(preg_replace('/[^a-z0-9\\-_]+/i', '_', $row->value));
                $field_name = replace_special_chars($field_name);
                $insert_field_names .= '( ' . $row->coll_ID . ', "custom_fname_' . $field_guid . '", "' . $field_name . '" ), ';
            }
            // Insert names for custom fields in collection settings
            $DB->query('INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES ' . substr($insert_field_names, 0, -2));
        }
        $DB->commit();
        // End adding of names for custom fields
        task_end();
        task_begin('Upgrading comments table...');
        db_add_index('T_comments', 'comment_status', 'comment_status');
        task_end();
        set_upgrade_checkpoint('11100');
    }
    if ($old_db_version < 11110) {
        // part 13 trunk aka second part of "i5"
        // Add new settings for antispam groups
        $antispam_group_settings = $DB->get_assoc('SELECT set_name, set_value
			 FROM T_settings
			WHERE set_name IN ( ' . $DB->quote(array('antispam_suspicious_group', 'antispam_trust_groups')) . ')');
        if (count($antispam_group_settings) < 2) {
            // Insert new settings only if don't exist in DB
            task_begin('Updating general settings...');
            // Set antispam suspicious group
            if (!isset($antispam_group_settings['antispam_suspicious_group'])) {
                // Insert new value, Don't rewrite value if it already defined before
                $suspect_group_SQL = new SQL();
                $suspect_group_SQL->SELECT('grp_ID');
                $suspect_group_SQL->FROM('T_groups');
                $suspect_group_SQL->WHERE('grp_name = ' . $DB->quote('Misbehaving/Suspect Users'));
                $suspect_group_ID = $DB->get_var($suspect_group_SQL->get());
                if (!empty($suspect_group_ID)) {
                    // Save setting value
                    $DB->query('INSERT INTO T_settings ( set_name, set_value ) VALUES
							( ' . $DB->quote('antispam_suspicious_group') . ', ' . $DB->quote($suspect_group_ID) . ' )');
                }
            }
            // Set antispam trust groups
            if (!isset($antispam_group_settings['antispam_trust_groups'])) {
                // Insert new value, Don't rewrite value if it already defined before
                $trust_groups = array('Administrators', 'Moderators', 'Trusted Users', 'Spammers/Restricted Users');
                $trust_groups_SQL = new SQL();
                $trust_groups_SQL->SELECT('grp_ID');
                $trust_groups_SQL->FROM('T_groups');
                $trust_groups_SQL->WHERE('grp_name IN ( ' . $DB->quote($trust_groups) . ')');
                $trust_groups_IDs = $DB->get_col($trust_groups_SQL->get());
                if (!empty($trust_groups_IDs)) {
                    // Save setting value
                    $DB->query('INSERT INTO T_settings ( set_name, set_value ) VALUES
							( ' . $DB->quote('antispam_trust_groups') . ', ' . $DB->quote(implode(',', $trust_groups_IDs)) . ' )');
                }
            }
            task_end();
        }
        set_upgrade_checkpoint('11110');
    }
    if ($old_db_version < 11200) {
        // part 14 trunk aka "i6"
        task_begin('Upgrading comments table...');
        db_add_col('T_comments', 'comment_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER comment_date");
        $DB->query('UPDATE T_comments
		                SET comment_last_touched_ts = comment_date');
        task_end();
        task_begin('Convert email addresses to lowercase... ');
        $DB->query('UPDATE T_users SET user_email = LOWER( user_email )');
        $DB->query('UPDATE ' . $tableprefix . 'email__blocked SET emblk_address = LOWER( emblk_address )');
        $DB->query('UPDATE T_email__returns SET emret_address = LOWER( emret_address )');
        $DB->query('UPDATE T_email__log SET emlog_to = LOWER( emlog_to )');
        $DB->query('UPDATE T_comments
			  SET comment_author_email = LOWER( comment_author_email )
			WHERE comment_author_email IS NOT NULL');
        task_end();
        task_begin('Upgrading blogs table...');
        db_add_col('T_blogs', 'blog_order', 'int(11) NULL DEFAULT NULL');
        $DB->query('UPDATE T_blogs
		                SET blog_order = blog_ID');
        task_end();
        task_begin('Updating general settings...');
        $site_skins_enabled = $DB->get_var('SELECT set_value
			 FROM T_settings
			WHERE set_name = ' . $DB->quote('site_skins_enabled'));
        if (is_null($site_skins_enabled)) {
            // Insert new setting to disable site skins
            $DB->query('INSERT INTO T_settings ( set_name, set_value )
				VALUES ( ' . $DB->quote('site_skins_enabled') . ', ' . $DB->quote('0') . ' )');
        } elseif ($site_skins_enabled == '1') {
            // Disable site skins if it is enabled
            $DB->query('UPDATE T_settings
				  SET set_value = ' . $DB->quote('0') . '
				WHERE set_name = ' . $DB->quote('site_skins_enabled'));
        }
        task_end();
        task_begin('Upgrading blogs table...');
        db_add_col('T_blogs', 'blog_favorite', 'TINYINT(1) NOT NULL DEFAULT 1');
        task_end();
        task_begin('Upgrade table of base domains... ');
        $DB->query("ALTER TABLE T_basedomains CHANGE COLUMN dom_status dom_status ENUM('unknown','trusted','suspect','blocked') NOT NULL DEFAULT 'unknown'");
        task_end();
        task_begin('Create table for file links voting... ');
        $DB->query('CREATE TABLE ' . $tableprefix . 'links__vote (
				lvot_link_ID       int(11) UNSIGNED NOT NULL,
				lvot_user_ID       int(11) UNSIGNED NOT NULL,
				lvot_like          tinyint(1),
				lvot_inappropriate tinyint(1),
				lvot_spam          tinyint(1),
				primary key (lvot_link_ID, lvot_user_ID)
			) ENGINE = innodb');
        // Convert all file votes to link votes
        $DB->query('INSERT INTO ' . $tableprefix . 'links__vote ( lvot_link_ID, lvot_user_ID, lvot_like, lvot_inappropriate, lvot_spam )
						SELECT link_ID, fvot_user_ID, fvot_like, fvot_inappropriate, fvot_spam
						FROM ' . $tableprefix . 'files__vote
						LEFT JOIN T_links ON link_file_ID = fvot_file_ID
						WHERE link_ID IS NOT NULL');
        // Delete old file voting table
        $DB->query('DROP TABLE IF EXISTS ' . $tableprefix . 'files__vote');
        task_end();
        task_begin('Create table for goal categories... ');
        $DB->query('CREATE TABLE T_track__goalcat (
				gcat_ID     int(10) unsigned NOT NULL auto_increment,
				gcat_name   varchar(50) default NULL,
				gcat_color  char(7) default NULL,
				PRIMARY KEY (gcat_ID)
			) ENGINE = myisam');
        // Insert default goal category
        $DB->query('INSERT INTO T_track__goalcat ( gcat_name, gcat_color )
			VALUES ( ' . $DB->quote('Default') . ', ' . $DB->quote('#999999') . ' )');
        $default_goalcat_ID = $DB->insert_id;
        db_add_col('T_track__goal', 'goal_gcat_ID', 'int(10) unsigned NOT NULL DEFAULT "' . $default_goalcat_ID . '" AFTER goal_ID');
        $DB->query('ALTER TABLE T_track__goal
			CHANGE goal_gcat_ID goal_gcat_ID int(10) unsigned NOT NULL');
        task_end();
        // This task was not required, but we would like to make sure that we have future proof link_datecreated and link_datemodified fields.
        // There were previous versions, when these fields were set to '1970-01-01' because the $localtimenow was not initialized during the install script
        task_begin('Update links table...');
        $DB->query("UPDATE T_links SET link_datecreated = concat( '2000-01-01 ', time( link_datecreated ) )\n\t\t\t\t\t\tWHERE date( link_datecreated ) = '1970-01-01'");
        $DB->query("UPDATE T_links SET link_datemodified = concat( '2000-01-01 ', time( link_datemodified ) )\n\t\t\t\t\t\tWHERE date( link_datemodified ) = '1970-01-01'");
        task_end();
        task_begin('Upgrading Blogs table...');
        $DB->query('ALTER TABLE T_blogs CHANGE blog_description blog_shortdesc varchar(250) NULL default ""');
        task_end();
        task_begin('Upgrading Comments table...');
        $DB->query('ALTER TABLE T_comments
			CHANGE comment_post_ID   comment_item_ID        int(11) unsigned NOT NULL default 0,
			CHANGE comment_author_ID comment_author_user_ID int unsigned NULL default NULL');
        $DB->query('ALTER TABLE T_comments
			DROP INDEX comment_post_ID');
        $DB->query('ALTER TABLE T_comments
			ADD KEY comment_item_ID ( comment_item_ID )');
        task_end();
        task_begin('Upgrading Files table...');
        $DB->query('ALTER TABLE T_files
			DROP INDEX file,
			ADD COLUMN file_path_hash char(32) default NULL');
        // Change file path length to the max allowed value
        $DB->query("ALTER TABLE T_files CHANGE COLUMN file_path file_path VARCHAR(767) NOT NULL DEFAULT ''");
        $DB->query('UPDATE T_files SET file_path_hash = MD5( CONCAT( file_root_type, file_root_ID, file_path ) )');
        $DB->query('ALTER TABLE T_files ADD UNIQUE file_path (file_path_hash)');
        task_end();
        task_begin('Create table for email campaigns... ');
        $DB->query('CREATE TABLE T_email__campaign (
			ecmp_ID          INT NOT NULL AUTO_INCREMENT,
			ecmp_date_ts     TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			ecmp_name        VARCHAR(255) NOT NULL,
			ecmp_email_title VARCHAR(255) NULL,
			ecmp_email_html  TEXT NULL,
			ecmp_email_text  TEXT NULL,
			ecmp_sent_ts     TIMESTAMP NULL,
			PRIMARY KEY      (ecmp_ID)
			) ENGINE = myisam');
        task_end();
        task_begin('Create table for email campaign send data... ');
        $DB->query('CREATE TABLE T_email__campaign_send (
			csnd_camp_ID  INT(11) UNSIGNED NOT NULL,
			csnd_user_ID  INT(11) UNSIGNED NOT NULL,
			csnd_emlog_ID INT(11) UNSIGNED NULL,
			PRIMARY KEY   csnd_PK ( csnd_camp_ID, csnd_user_ID )
			) ENGINE = myisam');
        task_end();
        task_begin('Rename table "email blocked" to "email address"... ');
        $DB->query('RENAME TABLE ' . $tableprefix . 'email__blocked TO T_email__address');
        $DB->query("ALTER TABLE T_email__address\n\t\t\tCHANGE emblk_ID                    emadr_ID                    INT(10) UNSIGNED NOT NULL auto_increment,\n\t\t\tCHANGE emblk_address               emadr_address               VARCHAR(255) DEFAULT NULL,\n\t\t\tCHANGE emblk_status                emadr_status                ENUM ( 'unknown', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown',\n\t\t\tCHANGE emblk_sent_count            emadr_sent_count            INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_sent_last_returnerror emadr_sent_last_returnerror INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_prmerror_count        emadr_prmerror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_tmperror_count        emadr_tmperror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_spamerror_count       emadr_spamerror_count       INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_othererror_count      emadr_othererror_count      INT(10) UNSIGNED NOT NULL DEFAULT 0,\n\t\t\tCHANGE emblk_last_sent_ts          emadr_last_sent_ts          TIMESTAMP NULL,\n\t\t\tCHANGE emblk_last_error_ts         emadr_last_error_ts         TIMESTAMP NULL");
        $DB->query("ALTER TABLE T_email__address\n\t\t\tADD UNIQUE emadr_address ( emadr_address )");
        $DB->query("ALTER TABLE T_email__address\n\t\t\tDROP INDEX emblk_address");
        task_end();
        // Add new email status 'redemption'
        task_begin('Upgrading table of email addresses...');
        $DB->query("ALTER TABLE T_email__address\n\t\t\tCHANGE emadr_status   emadr_status ENUM ( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown'");
        task_end();
        task_begin('Upgrading blog-group permissions table...');
        db_add_col('T_coll_group_perms', 'bloggroup_can_be_assignee', 'tinyint NOT NULL default 0 AFTER bloggroup_ismember');
        $DB->query('UPDATE T_coll_group_perms
			  SET bloggroup_can_be_assignee = 1
			WHERE bloggroup_group_ID IN ( 1, 2 )');
        task_end();
        task_begin('Upgrading blog-user permissions table...');
        db_add_col('T_coll_user_perms', 'bloguser_can_be_assignee', 'tinyint NOT NULL default 0 AFTER bloguser_ismember');
        task_end();
        task_begin('Dropping obsolete columns from table Links...');
        $DB->query('ALTER TABLE T_links
									DROP COLUMN link_external_url,
									DROP COLUMN link_title,
									DROP COLUMN link_dest_itm_ID');
        task_end();
        // This task was added later to turn OFF smart view counting on upgrade from v5.0 to v5.1 for better performance
        task_begin('Turn off smart view counting...');
        $DB->query('DELETE FROM T_settings WHERE set_name = ' . $DB->quote('smart_view_count'));
        task_end();
        task_begin('Upgrading Posts table...');
        db_drop_col('T_items__item', 'post_views');
        task_end();
        task_begin('Upgrading Files table... ');
        $DB->query("ALTER TABLE T_files\n\t\t\tCHANGE COLUMN file_root_type file_root_type enum('absolute','user','collection','shared','skins','import') not null default 'absolute'");
        task_end();
        // Set flag to recreate autogenerated excerpts due to modifications on the excerpt generation
        // Note: We need to generate this in the end of the upgrade script, because the database must be up to date
        $recreate_autogenerated_excerpts = true;
        set_upgrade_checkpoint('11200');
    }
    if ($old_db_version < 11208) {
        // part 15.a trunk aka second part of "i6"
        // Note create a separate block for the hitlog upgrade because it may require very long time
        task_begin('Upgrade hitlog table...');
        $DB->query('ALTER TABLE T_hitlog
			CHANGE COLUMN hit_ID            hit_ID            INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			CHANGE COLUMN hit_datetime      hit_datetime      TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			CHANGE COLUMN hit_serprank      hit_serprank      SMALLINT UNSIGNED DEFAULT NULL,
			CHANGE COLUMN hit_blog_ID       hit_coll_ID       INT(10) UNSIGNED NULL DEFAULT NULL,
			CHANGE COLUMN hit_response_code hit_response_code SMALLINT DEFAULT NULL,
			ADD COLUMN hit_agent_ID SMALLINT UNSIGNED NULL DEFAULT NULL AFTER hit_agent_type');
        $DB->query('ALTER TABLE T_hitlog
			DROP INDEX hit_blog_ID');
        $DB->query('ALTER TABLE T_hitlog
			ADD KEY hit_coll_ID ( hit_coll_ID )');
        task_end();
        set_upgrade_checkpoint('11208');
    }
    if ($old_db_version < 11210) {
        // part 15.b trunk aka third part of "i6"
        task_begin('Updating widgets setting...');
        // Unset those widgets allow blockcache value which current settings allow blockcache but the caching is always forbidden on runtime;
        $DB->query('UPDATE T_widget
				SET wi_params = REPLACE( wi_params, \'s:16:"allow_blockcache";i:1\', \'s:16:"allow_blockcache";i:0\' )
				WHERE wi_params LIKE \'%s:16:"allow_blockcache";i:1%\' AND (
					wi_code = "user_tools" OR wi_code = "user_login" OR ( wi_code = "msg_menu_link" AND wi_params LIKE \'%s:9:"link_type";s:8:"messages"%\' )
					OR ( wi_code = "menu_link" AND ( wi_params LIKE \'%s:9:"link_type";s:5:"login"%\' OR wi_params LIKE \'%s:9:"link_type";s:8:"register"%\' ) )
					)');
        // Unset 'show_badge' setting in case of msg_menu_link widgets where the link_type is contacts
        $DB->query('UPDATE T_widget
				SET wi_params = REPLACE( wi_params, \'s:10:"show_badge";i:1\', \'s:10:"show_badge";i:0\' )
				WHERE wi_code = "msg_menu_link" AND wi_params LIKE \'%s:9:"link_type";s:8:"contacts"%\' AND wi_params LIKE \'%s:10:"show_badge";i:1%\'');
        task_end();
        task_begin('Updating files hash values...');
        $DB->query('ALTER TABLE T_files MODIFY COLUMN file_hash VARBINARY(32), MODIFY COLUMN file_path_hash VARBINARY(32)');
        $DB->query('UPDATE T_files SET file_hash = UNHEX( file_hash ), file_path_hash = UNHEX( file_path_hash )');
        $DB->query('ALTER TABLE T_files MODIFY COLUMN file_hash BINARY(16) default NULL, MODIFY COLUMN file_path_hash BINARY(16) default NULL');
        task_end();
        task_begin('Upgrading goals table...');
        $DB->query('ALTER TABLE T_track__goal
			ADD COLUMN goal_temp_redir_url varchar(255) default NULL AFTER goal_redir_url,
			ADD COLUMN goal_temp_start_ts  TIMESTAMP NULL            AFTER goal_temp_redir_url,
			ADD COLUMN goal_temp_end_ts    TIMESTAMP NULL            AFTER goal_temp_start_ts,
			ADD COLUMN goal_notes          TEXT DEFAULT NULL');
        task_end();
        set_upgrade_checkpoint('11210');
    }
    if ($old_db_version < 11220) {
        // part 16.a trunk aka fourth part of "i6"
        task_begin('Upgrading countries table...');
        $DB->query('ALTER TABLE T_regional__country
			ADD COLUMN ctry_status      enum( \'trusted\', \'suspect\', \'blocked\' ) NULL DEFAULT NULL,
			ADD COLUMN ctry_block_count int(10) unsigned DEFAULT 0');
        task_end();
        set_upgrade_checkpoint('11220');
    }
    if ($old_db_version < 11240) {
        // part 16.d trunk aka seventh part of "i6"
        task_begin('Updating general settings...');
        $DB->query('UPDATE T_settings SET
			set_name = CASE
				WHEN set_name = "user_closing_allow" THEN "account_close_enabled"
				WHEN set_name = "user_closing_intro" THEN "account_close_intro"
				WHEN set_name = "user_closing_reasons" THEN "account_close_reasons"
				WHEN set_name = "user_closing_byemsg" THEN "account_close_byemsg"
				ELSE set_name
			END');
        task_end();
        set_upgrade_checkpoint('11240');
    }
    if ($old_db_version < 11245) {
        // part 16.e trunk aka eighth part of "i6"
        task_begin('Updating Antispam IP Ranges table...');
        db_add_col('T_antispam__iprange', 'aipr_contact_email_count', 'int(10) unsigned DEFAULT 0 AFTER aipr_user_count');
        task_end();
        task_begin('Updating invalid locale settings...');
        $current_default_locale = $DB->get_var('SELECT set_value FROM T_settings WHERE set_name = "default_locale"');
        if (empty($current_default_locale)) {
            // The default locale is not set in the database, use the one from the config file
            global $default_locale;
            $current_default_locale = $default_locale;
        }
        if ($DB->get_var('SELECT loc_enabled FROM T_locales WHERE loc_locale = ' . $DB->quote($current_default_locale))) {
            // Update invalid user and collection locales to the default, but only if the default exists and it is enabled
            $DB->query('UPDATE T_users
				SET user_locale = ' . $DB->quote($current_default_locale) . '
				WHERE  user_locale NOT IN ( SELECT loc_locale FROM T_locales WHERE loc_enabled = 1 )');
            $DB->query('UPDATE T_blogs
				SET blog_locale = ' . $DB->quote($current_default_locale) . '
				WHERE  blog_locale NOT IN ( SELECT loc_locale FROM T_locales WHERE loc_enabled = 1 )');
        }
        task_end();
        set_upgrade_checkpoint('11245');
    }
    if ($old_db_version < 11250) {
        // part 16.f trunk aka ninth part of "i6"
        // Convert item content separators to new format
        load_funcs('tools/model/_dbmaintenance.funcs.php');
        dbm_convert_item_content_separators();
        set_upgrade_checkpoint('11250');
    }
    if ($old_db_version < 11255) {
        // part 16.g trunk aka tenth part of "i6"
        task_begin('Updating post types...');
        $DB->query("INSERT INTO T_items__type ( ptyp_ID, ptyp_name )\n\t\t\tVALUES ( 1400, 'Intro-Front' )");
        task_end();
        set_upgrade_checkpoint('11255');
    }
    if ($old_db_version < 11260) {
        // part 16.h trunk aka eleventh part of "i6"
        // This upgrade block updates all field collations from 'ascii_bin' to 'ascii_general_ci' except of slugs table.
        task_begin('Clean up comment emails...');
        $DB->query("UPDATE T_comments\n\t\t\t\t\t\tSET comment_author_email = CONVERT(comment_author_email USING ascii)");
        $DB->commit();
        task_end();
        task_begin('Convert the field collations from ascii_bin to ascii_general_ci... <br />');
        // fp> why would we need a transaction here?	$DB->begin();
        task_begin('- Converting skins table...');
        $DB->query("ALTER TABLE T_skins__skin\n\t\t\tMODIFY skin_type enum('normal','feed','sitemap','mobile','tablet') COLLATE ascii_general_ci NOT NULL default 'normal'");
        task_end();
        task_begin('- Converting blogs table...');
        $DB->query("ALTER TABLE T_blogs\n\t\t\tMODIFY blog_access_type    VARCHAR(10) COLLATE ascii_general_ci NOT NULL DEFAULT 'extrapath',\n\t\t\tMODIFY blog_urlname        VARCHAR(255) COLLATE ascii_general_ci NOT NULL DEFAULT 'urlname',\n\t\t\tMODIFY blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) COLLATE ascii_general_ci DEFAULT 'default' NOT NULL,\n\t\t\tMODIFY blog_type           ENUM( 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL");
        task_end();
        task_begin('- Converting blog settings table...');
        $DB->query('ALTER TABLE T_coll_settings
			MODIFY cset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('- Converting widgets table...');
        $DB->query("ALTER TABLE {$tableprefix}widget\n\t\t\tMODIFY wi_type ENUM( 'core', 'plugin' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'core',\n\t\t\tMODIFY wi_code VARCHAR(32) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting categories table...');
        $DB->query("ALTER TABLE T_categories\n\t\t\tMODIFY cat_urlname varchar(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting posts table...');
        $DB->query("ALTER TABLE T_items__item\n\t\t\tMODIFY post_status               enum('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NOT NULL default 'published',\n\t\t\tMODIFY post_urltitle             VARCHAR(210) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY post_notifications_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq',\n\t\t\tMODIFY post_comment_status       ENUM('disabled', 'open', 'closed') COLLATE ascii_general_ci NOT NULL DEFAULT 'open',\n\t\t\tMODIFY post_renderers            TEXT COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting comments table...');
        $DB->query("ALTER TABLE T_comments\n\t\t\tMODIFY comment_type         enum('comment','linkback','trackback','pingback') COLLATE ascii_general_ci NOT NULL default 'comment',\n\t\t\tMODIFY comment_status       ENUM('published','community','deprecated','protected','private','review','draft','trash') COLLATE ascii_general_ci DEFAULT 'published' NOT NULL,\n\t\t\tMODIFY comment_author_email varchar(255) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY comment_author_IP    varchar(23) COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY comment_renderers    TEXT COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY comment_secret       CHAR(32) COLLATE ascii_general_ci NULL default NULL,\n\t\t\tMODIFY comment_notif_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq' COMMENT 'Have notifications been sent for this comment? How far are we in the process?'");
        task_end();
        task_begin('- Converting post prerendered contents table...');
        $DB->query("ALTER TABLE T_items__prerendering\n\t\t\tMODIFY itpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY itpr_renderers TEXT COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting comment prerendered contents table...');
        $DB->query("ALTER TABLE T_comments__prerendering\n\t\t\tMODIFY cmpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY cmpr_renderers TEXT COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting post versions table...');
        $DB->query("ALTER TABLE T_items__version\n\t\t\tMODIFY iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NULL");
        task_end();
        task_begin('- Converting post settings table...');
        $DB->query("ALTER TABLE T_items__item_settings\n\t\t\tMODIFY iset_name varchar( 50 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting user permissions table...');
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\tMODIFY bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloguser_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',\n\t\t\tMODIFY bloguser_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloguser_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        task_end();
        task_begin('- Converting group permissions table...');
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\tMODIFY bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloggroup_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',\n\t\t\tMODIFY bloggroup_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloggroup_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        task_end();
        task_begin('- Converting links table...');
        $DB->query("ALTER TABLE T_links\n\t\t\tMODIFY link_position varchar(10) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting files table...');
        $DB->query("ALTER TABLE T_files\n\t\t\tMODIFY file_root_type enum('absolute','user','collection','shared','skins','import') COLLATE ascii_general_ci NOT NULL DEFAULT 'absolute'");
        task_end();
        task_begin('- Converting file types table...');
        $DB->query("ALTER TABLE T_filetypes\n\t\t\tMODIFY ftyp_extensions varchar(30) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ftyp_viewtype   varchar(10) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ftyp_allowed    enum('any','registered','admin') COLLATE ascii_general_ci NOT NULL default 'admin'");
        task_end();
        task_begin('- Converting sessions table...');
        $DB->query("ALTER TABLE T_sessions\n\t\t\tMODIFY sess_key       CHAR(32) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY sess_ipaddress VARCHAR(39) COLLATE ascii_general_ci NOT NULL DEFAULT '',\n\t\t\tMODIFY sess_device    VARCHAR(8) COLLATE ascii_general_ci NOT NULL DEFAULT ''");
        task_end();
        task_begin('- Converting domains table...');
        $DB->query("ALTER TABLE T_basedomains\n\t\t\tMODIFY dom_status ENUM('unknown','trusted','suspect','blocked') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown',\n\t\t\tMODIFY dom_type   ENUM('unknown','normal','searcheng','aggregator','email') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'");
        task_end();
        task_begin('- Converting logs table...');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\tMODIFY hit_ctrl         VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY hit_type         ENUM('standard','rss','admin','ajax', 'service') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL,\n\t\t\tMODIFY hit_referer_type ENUM('search','special','spam','referer','direct','self') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY hit_remote_addr  VARCHAR(40) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY hit_agent_type   ENUM('robot','browser','unknown') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL");
        task_end();
        task_begin('- Converting goal categories table...');
        $DB->query("ALTER TABLE T_track__goalcat\n\t\t\tMODIFY gcat_color  char(7) COLLATE ascii_general_ci default NULL");
        task_end();
        task_begin('- Converting groups table...');
        $DB->query("ALTER TABLE T_groups\n\t\t\tMODIFY grp_perm_blogs                  enum('user','viewall','editall') COLLATE ascii_general_ci NOT NULL default 'user',\n\t\t\tMODIFY grp_perm_xhtmlvalidation        VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',\n\t\t\tMODIFY grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',\n\t\t\tMODIFY grp_perm_stats                  enum('none','user','view','edit') COLLATE ascii_general_ci NOT NULL default 'none'");
        task_end();
        task_begin('- Converting group settings table...');
        $DB->query("ALTER TABLE T_groups__groupsettings\n\t\t\tMODIFY gset_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting settings table...');
        $DB->query("ALTER TABLE T_settings\n\t\t\tMODIFY set_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cache table...');
        $DB->query("ALTER TABLE T_global__cache\n\t\t\tMODIFY cach_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting users table...');
        $DB->query("ALTER TABLE T_users\n\t\t\tMODIFY user_email           varchar(255) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY user_status          enum( 'activated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new',\n\t\t\tMODIFY user_unsubscribe_key CHAR(32) COLLATE ascii_general_ci NOT NULL default '' COMMENT 'A specific key, it is used when a user wants to unsubscribe from a post comments without signing in',\n\t\t\tMODIFY user_gender          char(1) COLLATE ascii_general_ci NULL");
        task_end();
        task_begin('- Converting user fields table...');
        $DB->query("ALTER TABLE T_users__fielddefs\n\t\t\tMODIFY ufdf_type       char(8) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ufdf_required   enum('hidden','optional','recommended','require') COLLATE ascii_general_ci NOT NULL default 'optional',\n\t\t\tMODIFY ufdf_duplicated enum('forbidden','allowed','list') COLLATE ascii_general_ci NOT NULL default 'allowed'");
        task_end();
        task_begin('- Converting user reports table...');
        $DB->query("ALTER TABLE T_users__reports\n\t\t\tMODIFY urep_status enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ) COLLATE ascii_general_ci");
        task_end();
        task_begin('- Converting locales table...');
        $DB->query("ALTER TABLE T_locales\n\t\t\tMODIFY loc_charset varchar(15) COLLATE ascii_general_ci NOT NULL default 'iso-8859-1',\n\t\t\tMODIFY loc_datefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'y-m-d',\n\t\t\tMODIFY loc_timefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i:s'");
        task_end();
        task_begin('- Converting antispam table...');
        $DB->query("ALTER TABLE {$tableprefix}antispam\n\t\t\tMODIFY aspm_source enum( 'local','reported','central' ) COLLATE ascii_general_ci NOT NULL default 'reported'");
        task_end();
        task_begin('- Converting IP ranges table...');
        $DB->query("ALTER TABLE T_antispam__iprange\n\t\t\tMODIFY aipr_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL");
        task_end();
        task_begin('- Converting user settings table...');
        $DB->query("ALTER TABLE T_users__usersettings\n\t\t\tMODIFY uset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugins table...');
        $DB->query("ALTER TABLE T_plugins\n\t\t\tMODIFY plug_classname VARCHAR(40) COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY plug_code      VARCHAR(32) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY plug_version   VARCHAR(42) COLLATE ascii_general_ci NOT NULL default '0',\n\t\t\tMODIFY plug_status    ENUM( 'enabled', 'disabled', 'needs_config', 'broken' ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin settings table...');
        $DB->query("ALTER TABLE T_pluginsettings\n\t\t\tMODIFY pset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin user settings table...');
        $DB->query("ALTER TABLE T_pluginusersettings\n\t\t\tMODIFY puset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin events table...');
        $DB->query("ALTER TABLE T_pluginevents\n\t\t\tMODIFY pevt_event VARCHAR(40) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cron logs table...');
        $DB->query("ALTER TABLE T_cron__log\n\t\t\tMODIFY clog_status enum('started','finished','error','timeout') COLLATE ascii_general_ci not null default 'started'");
        task_end();
        task_begin('- Converting countries table...');
        $DB->query("ALTER TABLE T_regional__country\n\t\t\tMODIFY ctry_code   char(2) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ctry_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL");
        task_end();
        task_begin('- Converting regions table...');
        $DB->query("ALTER TABLE T_regional__region\n\t\t\tMODIFY rgn_code char(6) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting subregions table...');
        $DB->query("ALTER TABLE T_regional__subregion\n\t\t\tMODIFY subrg_code char(6) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cities table...');
        $DB->query("ALTER TABLE T_regional__city\n\t\t\tMODIFY city_postcode char(12) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting currencies table...');
        $DB->query("ALTER TABLE T_regional__currency\n\t\t\tMODIFY curr_code char(3) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting email logs table...');
        $DB->query("ALTER TABLE T_email__log\n\t\t\tMODIFY emlog_to     VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emlog_result ENUM( 'ok', 'error', 'blocked' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'ok'");
        task_end();
        task_begin('- Converting email returns table...');
        $DB->query("ALTER TABLE T_email__returns\n\t\t\tMODIFY emret_address   VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emret_errtype   CHAR(1) COLLATE ascii_general_ci NOT NULL DEFAULT 'U'");
        task_end();
        task_begin('- Converting email addresses table...');
        $DB->query("ALTER TABLE T_email__address\n\t\t\tMODIFY emadr_address VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emadr_status  ENUM( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'");
        task_end();
        //	$DB->commit();
        task_end();
        set_upgrade_checkpoint('11260');
    }
    if ($old_db_version < 11270) {
        // part 16.i trunk aka 12th part of "i6"
        // IPv4 mapped IPv6 addresses maximum length is 45 chars: ex. ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190
        task_begin('Upgrading comments table...');
        $DB->query("ALTER TABLE T_comments\n\t\t\tMODIFY comment_author_IP varchar(45) COLLATE ascii_general_ci NOT NULL default ''");
        task_end();
        task_begin('Upgrading sessions table...');
        $DB->query("ALTER TABLE T_sessions\n\t\t\tMODIFY sess_ipaddress VARCHAR(45) COLLATE ascii_general_ci NOT NULL DEFAULT ''");
        task_end();
        set_upgrade_checkpoint('11270');
    }
    if ($old_db_version < 11280) {
        // part 16.j trunk aka 12th part of "i6"
        task_begin('Upgrading hit logs table...');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\tMODIFY hit_remote_addr VARCHAR(45) COLLATE ascii_general_ci DEFAULT NULL");
        task_end();
        task_begin('Upgrading blogs table...');
        db_drop_col('T_blogs', 'blog_UID');
        task_end();
        set_upgrade_checkpoint('11280');
    }
    if ($old_db_version < 11285) {
        // part 16.k trunk aka 13th part of "i6"
        task_begin('Updating plugins table...');
        $DB->query('UPDATE T_plugins SET
			plug_code = CASE
				WHEN plug_classname = "generic_ping_plugin"         THEN "b2evGPing"
				WHEN plug_classname = "basic_antispam_plugin"       THEN "b2evBAspm"
				WHEN plug_classname = "flowplayer_plugin"           THEN "b2evFlwP"
				WHEN plug_classname = "html5_mediaelementjs_plugin" THEN "b2evH5MP"
				WHEN plug_classname = "html5_videojs_plugin"        THEN "b2evH5VJSP"
				ELSE plug_code
			END');
        task_end();
        set_upgrade_checkpoint('11285');
    }
    if ($old_db_version < 11286) {
        // part 16.l trunk aka 14th part of "i6"
        task_begin('Upgrade timestamp fields... ');
        $DB->query('ALTER TABLE T_email__log
			MODIFY emlog_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_email__returns
			MODIFY emret_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_items__prerendering
			MODIFY itpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_comments__prerendering
			MODIFY cmpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_users__reports
			MODIFY urep_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_items__version
			MODIFY iver_edit_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__thread
			MODIFY thrd_datemodified datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__message
			MODIFY msg_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__contact
			MODIFY mct_last_contact_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        task_end();
        set_upgrade_checkpoint('11286');
    }
    if ($old_db_version < 11300) {
        // part 17 trunk aka "i7"
        task_begin('Upgrading locales table...');
        db_add_col('T_locales', 'loc_shorttimefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "H:i" AFTER loc_timefmt');
        task_end();
        task_begin('Creating message prerendering cache table... ');
        $DB->query('CREATE TABLE T_messaging__prerendering(
				mspr_msg_ID              INT(11) UNSIGNED NOT NULL,
				mspr_format              ENUM("htmlbody","entityencoded","xml","text") COLLATE ascii_general_ci NOT NULL,
				mspr_renderers           TEXT NOT NULL,
				mspr_content_prerendered MEDIUMTEXT NULL,
				mspr_datemodified        TIMESTAMP NOT NULL,
				PRIMARY KEY (mspr_msg_ID, mspr_format)
			) ENGINE = innodb');
        db_add_col('T_messaging__message', 'msg_renderers', 'TEXT NOT NULL');
        $DB->query('UPDATE T_messaging__message SET msg_renderers = "default"');
        task_end();
        task_begin('Upgrading categories table...');
        db_add_col('T_categories', 'cat_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'");
        $DB->query('UPDATE T_categories SET cat_last_touched_ts = (
			SELECT post_last_touched_ts
			  FROM T_items__item
			       INNER JOIN T_postcats ON postcat_post_ID = post_ID
			 WHERE postcat_cat_ID = cat_ID
			 ORDER BY post_last_touched_ts DESC
			 LIMIT 1 )');
        task_end();
        task_begin('Create table for User post read status... ');
        $DB->query('CREATE TABLE T_users__postreadstatus (
			uprs_user_ID int(11) unsigned NOT NULL,
			uprs_post_ID int(11) unsigned NOT NULL,
			uprs_read_post_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			uprs_read_comment_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			PRIMARY KEY ( uprs_user_ID, uprs_post_ID )
			) ENGINE = innodb');
        task_end();
        task_begin('Create table for System log... ');
        $DB->query("CREATE TABLE T_syslog (\n\t\t\tslg_ID        INT NOT NULL AUTO_INCREMENT,\n\t\t\tslg_timestamp TIMESTAMP NOT NULL,\n\t\t\tslg_origin    ENUM('core', 'plugin') COLLATE ascii_general_ci,\n\t\t\tslg_origin_ID INT UNSIGNED NULL,\n\t\t\tslg_object    ENUM('comment', 'item', 'user') COLLATE ascii_general_ci,\n\t\t\tslg_object_ID INT UNSIGNED NOT NULL,\n\t\t\tslg_message   VARCHAR(255) NOT NULL,\n\t\t\tPRIMARY KEY   (slg_ID),\n\t\t\tINDEX         slg_object (slg_object, slg_object_ID)\n\t\t\t) ENGINE = myisam");
        task_end();
        set_upgrade_checkpoint('11300');
    }
    if ($old_db_version < 11310) {
        // part 18 trunk aka second part of "i7"
        task_begin('Upgrading cron tasks table...');
        load_funcs('cron/_cron.funcs.php');
        $DB->begin();
        $DB->query('ALTER TABLE T_cron__task
			CHANGE COLUMN ctsk_controller ctsk_key varchar(50) COLLATE ascii_general_ci NOT NULL AFTER ctsk_repeat_after,
			CHANGE COLUMN ctsk_name ctsk_name varchar(255) null COMMENT "Specific name of this task. This value is set only if this job name was modified by an admin user"');
        // Update keys from controllers
        // Important: Cron job sql query result must be converted to ascii charset since the ctsk_key is already ascii( ascii_bin collation )
        $DB->query('UPDATE T_cron__task
			INNER JOIN ( ' . cron_job_sql_query('key,ctrl') . ' ) AS temp
			       ON ctsk_key = CONVERT( temp.task_ctrl USING ascii )
			SET ctsk_key = temp.task_key');
        // Reset names to NULL if its are default
        $DB->query($sql = 'UPDATE T_cron__task
			INNER JOIN ( ' . cron_job_sql_query() . ' ) AS temp
			        ON ctsk_key = CONVERT( temp.task_key USING ascii ) AND ctsk_name = CONVERT( temp.task_name USING ' . $DB->connection_charset . ' )
			SET ctsk_name = NULL');
        $DB->commit();
        task_end();
        task_begin('Upgrade table system log... ');
        $DB->query('ALTER TABLE T_syslog
			CHANGE COLUMN slg_object slg_object ENUM(\'comment\', \'item\', \'user\', \'file\') COLLATE ascii_general_ci,
			CHANGE COLUMN slg_object_ID slg_object_ID INT UNSIGNED NULL,
			ADD    COLUMN slg_user_ID INT UNSIGNED NULL AFTER slg_timestamp,
			ADD    COLUMN slg_type ENUM(\'info\', \'warning\', \'error\', \'critical_error\') COLLATE ascii_general_ci NOT NULL DEFAULT \'info\' AFTER slg_user_ID');
        task_end();
        task_begin('Upgrade groups table... ');
        db_add_col('T_groups', 'grp_level', 'int unsigned DEFAULT 0 NOT NULL AFTER grp_name');
        $default_groups_levels = array('Administrators' => 10, 'Moderators' => 8, 'Trusted Users' => 6, 'Normal Users' => 4, 'Misbehaving/Suspect Users' => 2, 'Spammers/Restricted Users' => 1);
        // Build sql query to update group level depending on name
        $group_level_query = 'SELECT group_name, group_level FROM (';
        $first_task = true;
        foreach ($default_groups_levels as $def_group_name => $def_group_level) {
            if ($first_task) {
                $group_level_query .= 'SELECT ' . $DB->quote($def_group_name) . ' AS group_name, ' . $DB->quote($def_group_level) . ' AS group_level';
                $first_task = false;
            } else {
                $group_level_query .= ' UNION SELECT ' . $DB->quote($def_group_name) . ', ' . $DB->quote($def_group_level);
            }
        }
        $group_level_query .= ') AS inner_temp';
        // Set default levels depending on name
        $DB->query('UPDATE T_groups
			INNER JOIN ( ' . $group_level_query . ' ) AS temp
			       ON grp_name = CONVERT( temp.group_name USING ' . $DB->connection_charset . ' )
			  SET grp_level = temp.group_level');
        // Set default '4' level for all other groups
        $DB->query('UPDATE T_groups
			  SET grp_level = 4
			WHERE grp_level = 0');
        // Set default user permissions for Moderators group
        $DB->query('UPDATE T_groups__groupsettings
			  SET gset_value = "moderate"
			WHERE gset_name = "perm_users"
			  AND gset_grp_ID = (SELECT grp_ID FROM T_groups WHERE grp_name = "Moderators")');
        task_end();
        task_begin('Updating general settings...');
        $DB->query('UPDATE T_settings
				SET set_value = ' . $DB->quote('yes') . '
			WHERE set_name = ' . $DB->quote('newusers_canregister') . '
				AND set_value = ' . $DB->quote('1'));
        task_end();
        task_begin('Creating table for User invitation codes... ');
        $DB->query('CREATE TABLE T_users__invitation_code (
			ivc_ID        int(11) unsigned NOT NULL auto_increment,
			ivc_code      varchar(32) COLLATE ascii_general_ci NOT NULL,
			ivc_expire_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			ivc_source    varchar(30) NULL,
			ivc_grp_ID    int(4) NOT NULL,
			PRIMARY KEY ( ivc_ID ),
			UNIQUE ivc_code ( ivc_code )
		) ENGINE = innodb');
        task_end();
        task_begin('Creating table for User organizations... ');
        $DB->query('CREATE TABLE T_users__organization (
			org_ID   INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			org_name VARCHAR(255) NOT NULL,
			org_url  VARCHAR(2000) NULL,
			PRIMARY KEY ( org_ID ),
			UNIQUE org_name ( org_name )
		) ENGINE = innodb');
        task_end();
        task_begin('Creating table for relations users with organizations... ');
        $DB->query('CREATE TABLE T_users__user_org (
			uorg_user_ID  INT(11) UNSIGNED NOT NULL,
			uorg_org_ID   INT(11) UNSIGNED NOT NULL,
			uorg_accepted TINYINT(1) DEFAULT 0,
			PRIMARY KEY ( uorg_user_ID, uorg_org_ID )
		) ENGINE = innodb');
        task_end();
        // Rename item settings:
        //   "post_custom_headers" to "metakeywords"
        //   "post_metadesc" to "metadesc"
        //   "post_expiry_delay" to "comment_expiry_delay"
        task_begin('Upgrading Item Settings...');
        $DB->query('UPDATE T_items__item_settings
				  SET iset_name = "metakeywords"
				WHERE iset_name = "post_custom_headers"');
        $DB->query('UPDATE T_items__item_settings
				  SET iset_name = "metadesc"
				WHERE iset_name = "post_metadesc"');
        $DB->query('UPDATE T_items__item_settings
				  SET iset_name = "comment_expiry_delay"
				WHERE iset_name = "post_expiry_delay"');
        task_end();
        task_begin('Upgrade table files... ');
        db_add_col('T_files', 'file_type', "enum('image', 'audio', 'other') COLLATE ascii_general_ci NULL DEFAULT NULL AFTER file_ID");
        task_end();
        task_begin('Upgrade table posts... ');
        $DB->query('ALTER TABLE T_items__item
			CHANGE post_title     post_title     VARCHAR(255) NOT NULL,
			CHANGE post_renderers post_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table post prerendering cache... ');
        $DB->query('ALTER TABLE T_items__prerendering
			CHANGE itpr_renderers itpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table post versions... ');
        $DB->query('ALTER TABLE T_items__version
			CHANGE iver_title iver_title VARCHAR(255) NULL');
        task_end();
        task_begin('Upgrade table comments... ');
        $DB->query('ALTER TABLE T_comments
			CHANGE comment_renderers comment_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table comment prerendering cache... ');
        $DB->query('ALTER TABLE T_comments__prerendering
			CHANGE cmpr_renderers cmpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table messages... ');
        $DB->query('ALTER TABLE T_messaging__message
			CHANGE msg_renderers msg_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table message prerendering cache... ');
        $DB->query('ALTER TABLE T_messaging__prerendering
			CHANGE mspr_renderers mspr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('Upgrade table user field definitions... ');
        $DB->query('ALTER TABLE T_users__fielddefs
			CHANGE ufdf_options ufdf_options VARCHAR(255) NULL DEFAULT NULL');
        // Change emtpy ufdf_options to NULL, since it must/may be defined only in case of the list ufdf_type
        $DB->query('UPDATE T_users__fielddefs
			SET ufdf_options = NULL
			WHERE ufdf_options = "" AND ufdf_type != "list"');
        task_end();
        task_begin('Upgrade table cron tasks... ');
        $DB->query('ALTER TABLE T_cron__task
			CHANGE ctsk_params ctsk_params varchar(255)');
        task_end();
        task_begin('Upgrading users table...');
        db_add_col('T_users', 'user_salt', 'CHAR(8) NOT NULL default "" AFTER user_pass');
        task_end();
        task_begin('Updating users pass storage...');
        $DB->query('ALTER TABLE T_users MODIFY COLUMN user_pass VARBINARY(32)');
        $DB->query('UPDATE T_users SET user_pass = UNHEX( user_pass )');
        $DB->query('ALTER TABLE T_users MODIFY COLUMN user_pass BINARY(16) NOT NULL');
        task_end();
        set_upgrade_checkpoint('11310');
    }
    if ($old_db_version < 11320) {
        // part 18.a trunk aka third part of "i7"
        task_begin('Update locales to utf-8 charset...');
        db_drop_col('T_locales', 'loc_charset');
        $DB->query('UPDATE T_locales
			SET loc_name = REPLACE( loc_name, "latin1", "utf8" )
			WHERE loc_locale IN ( "en-US", "en-AU", "en-CA", "en-GB", "en-IL", "en-NZ", "en-SG" )');
        $DB->query('UPDATE T_users SET user_locale = "en-US" WHERE user_locale = "en-US-utf8"');
        $DB->query('UPDATE T_blogs SET blog_locale = "en-US" WHERE blog_locale = "en-US-utf8"');
        $DB->query('UPDATE T_items__item SET post_locale = "en-US" WHERE post_locale = "en-US-utf8"');
        $DB->query('UPDATE T_settings SET set_value = "en-US" WHERE set_name = "default_locale" AND set_value = "en-US-utf8"');
        // Check if the 'en-US-utf8' locale is enabled
        $en_us_utf8_enabled = $DB->get_var('SELECT loc_enabled FROM T_locales WHERE loc_locale = "en-US-utf8"');
        if ($en_us_utf8_enabled !== NULL) {
            // The 'en-US-utf8' was enabled we must enable the 'en-US' even if it was not enabled before because we merged the two locales into one
            $en_us_enabled = $DB->get_var('SELECT loc_enabled FROM T_locales WHERE loc_locale = "en-US"');
            if ($en_us_enabled === NULL) {
                // Update "en-US-utf8" to "en-US"
                $DB->query('UPDATE T_locales SET loc_locale = "en-US" WHERE loc_locale = "en-US-utf8"');
            } elseif ($en_us_utf8_enabled && !$en_us_enabled) {
                // Enable the "en-US" locale because it was not enabled but the "en-US-utf8" was
                $DB->query('UPDATE T_locales SET loc_enabled = 1 WHERE loc_locale = "en-US"');
            }
            if ($en_us_enabled !== NULL) {
                // Remove the "en-US-utf8" locale if the "en_US" locale is already in the database
                $DB->query('DELETE FROM T_locales WHERE loc_locale = "en-US-utf8"');
            }
        }
        task_end();
        task_begin('Upgrade table files... ');
        db_add_col('T_files', 'file_can_be_main_profile', 'TINYINT(1) NOT NULL DEFAULT 1');
        task_end();
        task_begin('Add new video file types... ');
        $video_types = array('webm' => "( 'webm', 'WebM video file', 'video/webm', 'file_video', 'browser', 'registered' )", 'ogv' => "( 'ogv', 'Ogg video file', 'video/ogg', 'file_video', 'browser', 'registered' )", 'm3u8' => "( 'm3u8', 'M3U8 video file', 'application/x-mpegurl', 'file_video', 'browser', 'registered' )");
        $SQL = new SQL();
        $SQL->SELECT('ftyp_extensions');
        $SQL->FROM('T_filetypes');
        $SQL->WHERE('ftyp_extensions LIKE "%' . implode('%" OR ftyp_extensions LIKE "%', array_keys($video_types)) . '%"');
        $existing_video_types = $DB->get_col($SQL->get());
        if (!empty($existing_video_types)) {
            // Some video types arleady exist in DB, Exclude them from inserting
            foreach ($existing_video_types as $vtype) {
                unset($video_types[$vtype]);
            }
        }
        if (count($video_types)) {
            // Insert new video file types
            $DB->query("INSERT INTO T_filetypes\n\t\t\t\t( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )\n\t\t\t\tVALUES " . implode(', ', $video_types));
        }
        task_end();
        set_upgrade_checkpoint('11320');
    }
    if ($old_db_version < 11330) {
        // part 18.b trunk aka 4th part of "i7"
        task_begin('Upgrade table blogs... ');
        $DB->query('UPDATE T_blogs
			  SET blog_in_bloglist = "1"
			WHERE blog_in_bloglist > 0');
        $DB->query('ALTER TABLE T_blogs
			CHANGE blog_in_bloglist blog_in_bloglist ENUM( "public", "logged", "member", "never" ) COLLATE ascii_general_ci DEFAULT "public" NOT NULL');
        $DB->query('UPDATE T_blogs
			  SET blog_in_bloglist = "never"
			WHERE blog_in_bloglist = ""');
        task_end();
        set_upgrade_checkpoint('11330');
    }
    if ($old_db_version < 11340) {
        // part 18.c trunk aka 5th part of "i7"
        task_begin('Upgrading blogs table...');
        $DB->query("ALTER TABLE T_blogs\n\t\t\tMODIFY blog_type ENUM( 'main', 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL");
        task_end();
        set_upgrade_checkpoint('11340');
    }
    if ($old_db_version < 11350) {
        // part 18.d trunk aka 6th part of "i7"
        task_begin('Update category ordering...');
        $DB->query('REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
				SELECT blog_ID, "category_ordering", IFNULL( set_value, "alpha" )
				FROM T_blogs LEFT JOIN T_settings ON set_name = "chapter_ordering"');
        $DB->query('DELETE FROM T_settings WHERE set_name = "chapter_ordering"');
        db_add_col('T_categories', 'cat_subcat_ordering', "enum('parent', 'alpha', 'manual') COLLATE ascii_general_ci NULL DEFAULT NULL AFTER cat_order");
        task_end();
        set_upgrade_checkpoint('11350');
    }
    if ($old_db_version < 11360) {
        // part 18.e trunk aka 7th part of "i7"
        task_begin('Upgrade table posts... ');
        $DB->query('ALTER TABLE T_items__item
            CHANGE post_ptyp_ID post_ityp_ID int(10) unsigned NOT NULL DEFAULT 1');
        $DB->query('ALTER TABLE T_items__item
            DROP INDEX post_ptyp_ID');
        $DB->query('ALTER TABLE T_items__item
            ADD INDEX post_ityp_ID ( post_ityp_ID )');
        task_end();
        task_begin('Upgrade table post types... ');
        $DB->query("ALTER TABLE T_items__type\n\t\t\tCHANGE ptyp_ID   ityp_ID   INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,\n\t\t\tCHANGE ptyp_name ityp_name VARCHAR(30) NOT NULL,\n\t\t\tADD ityp_description       TEXT NULL DEFAULT NULL,\n\t\t\tADD ityp_backoffice_tab    VARCHAR(30) NULL DEFAULT NULL,\n\t\t\tADD ityp_template_name     VARCHAR(40) NULL DEFAULT NULL,\n\t\t\tADD ityp_use_title         ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'required',\n\t\t\tADD ityp_use_url           ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_use_text          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_allow_html        TINYINT DEFAULT 1,\n\t\t\tADD ityp_allow_attachments TINYINT DEFAULT 1,\n\t\t\tADD ityp_use_excerpt       ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_use_title_tag     ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_use_meta_desc     ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_use_meta_keywds   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_use_tags          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tADD ityp_allow_featured    TINYINT DEFAULT 1,\n\t\t\tADD ityp_use_country       ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tADD ityp_use_region        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tADD ityp_use_sub_region    ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tADD ityp_use_city          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tADD ityp_use_coordinates   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tADD ityp_use_custom_fields TINYINT DEFAULT 1,\n\t\t\tADD ityp_use_comments      TINYINT DEFAULT 1,\n\t\t\tADD ityp_allow_closing_comments   TINYINT DEFAULT 1,\n\t\t\tADD ityp_allow_disabling_comments TINYINT DEFAULT 0,\n\t\t\tADD ityp_use_comment_expiration   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional'");
        $DB->query('UPDATE T_items__type SET
			ityp_backoffice_tab = CASE
				WHEN ityp_ID = 1    THEN "Posts"
				WHEN ityp_ID = 1000 THEN "Pages"
				WHEN ityp_ID >= 1400 AND ityp_ID <= 1600 THEN "Intros"
				WHEN ityp_ID = 2000 THEN "Podcasts"
				WHEN ityp_ID = 3000 THEN "Sidebar links"
				WHEN ityp_ID = 4000 THEN "Advertisement"
				WHEN ityp_ID = 5000 THEN NULL
				ELSE "Posts"
			END,
			ityp_template_name = CASE
				WHEN ityp_ID = 1 OR ityp_ID = 2000 THEN "single"
				WHEN ityp_ID = 1000 THEN "page"
				ELSE NULL
			END');
        task_end();
        task_begin('Adding new post types...');
        $DB->begin();
        $new_item_types = array('manual' => array('type_ID' => 100, 'title' => 'Manual Page'), 'forum' => array('type_ID' => 200, 'title' => 'Forum Topic'));
        $item_types_insert_data = array();
        foreach ($new_item_types as $blog_type => $item_type_data) {
            $item_type_ID = $new_item_types[$blog_type]['type_ID'];
            while ($item_type_ID !== NULL) {
                // Find first free post type ID starting with 100
                $free_item_type_ID = $item_type_ID;
                $item_type_ID = $DB->get_var('SELECT ityp_ID FROM T_items__type WHERE ityp_ID = ' . $DB->quote($item_type_ID));
                if ($item_type_ID === NULL) {
                    // Use this free ID for new type
                    $item_types_insert_data[] = '( ' . $free_item_type_ID . ', ' . $DB->quote($new_item_types[$blog_type]['title']) . ', "Posts", "single", 0 )';
                    $new_item_types[$blog_type]['new_type_ID'] = $free_item_type_ID;
                    break;
                }
                $item_type_ID++;
            }
        }
        if (count($item_types_insert_data)) {
            // Insert new post types
            $DB->query('INSERT INTO T_items__type ( ityp_ID, ityp_name, ityp_backoffice_tab, ityp_template_name, ityp_allow_html )
						VALUES ' . implode(', ', $item_types_insert_data));
            // Update types of all post with "Post" type to new created (only for blogs with type 'forum' and 'manual')
            foreach ($new_item_types as $blog_type => $item_type_data) {
                $DB->query('UPDATE T_items__item
					INNER JOIN T_categories
					   ON post_main_cat_ID = cat_ID
					  AND post_ityp_ID = 1
					INNER JOIN T_blogs
					   ON cat_blog_ID = blog_ID
					  AND blog_type = ' . $DB->quote($blog_type) . '
					  SET post_ityp_ID = ' . $DB->quote($item_type_data['new_type_ID']));
            }
        }
        $DB->commit();
        task_end();
        task_begin('Upgrade table comments... ');
        $DB->query("ALTER TABLE T_comments\n\t\t\tCHANGE comment_type comment_type enum('comment','linkback','trackback','pingback','meta') COLLATE ascii_general_ci NOT NULL default 'comment'");
        task_end();
        task_begin('Creating table for custom fields of Post Types... ');
        $DB->query('CREATE TABLE T_items__type_custom_field (
			itcf_ID      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			itcf_ityp_ID INT(11) UNSIGNED NOT NULL,
			itcf_label   VARCHAR(255) NOT NULL,
			itcf_name    VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			itcf_type    ENUM( \'double\', \'varchar\' ) COLLATE ascii_general_ci NOT NULL,
			itcf_order   INT NULL,
			PRIMARY KEY ( itcf_ID ),
			UNIQUE itcf_ityp_ID_name( itcf_ityp_ID, itcf_name )
		) ENGINE = innodb');
        global $posttypes_perms;
        // Create post types for each blog that has at aleast one custom field
        $SQL = new SQL();
        $SQL->SELECT('*');
        $SQL->FROM('T_coll_settings');
        $SQL->WHERE('cset_name LIKE ' . $DB->quote('custom_%'));
        $SQL->ORDER_BY('cset_coll_ID');
        $setting_rows = $DB->get_results($SQL->get());
        $custom_fields = array();
        $blog_setting_delete_data = array();
        $blog_setting_item_types = array();
        if (count($setting_rows)) {
            // Initialize an array of custom fields from blog settings
            foreach ($setting_rows as $setting_row) {
                if (preg_match('/custom_(double|varchar)\\d+/', $setting_row->cset_name, $matches)) {
                    // It is a custom field
                    if (!isset($custom_fields[$setting_row->cset_coll_ID])) {
                        $custom_fields[$setting_row->cset_coll_ID] = array();
                    }
                    // Delete this blog setting
                    $blog_setting_delete_data[] = 'cset_coll_ID = ' . $DB->quote($setting_row->cset_coll_ID) . ' AND cset_name = ' . $DB->quote($setting_row->cset_name);
                    $cf_type = $matches[1];
                    $cf_key = $setting_row->cset_value;
                    $cf_label = '';
                    $cf_name = '';
                    foreach ($setting_rows as $s_row) {
                        if ($s_row->cset_name == 'custom_' . $cf_type . '_' . $cf_key) {
                            // Label
                            $cf_label = $s_row->cset_value;
                            // Delete this blog setting
                            $blog_setting_delete_data[] = 'cset_coll_ID = ' . $DB->quote($s_row->cset_coll_ID) . ' AND cset_name = ' . $DB->quote($s_row->cset_name);
                        }
                        if ($s_row->cset_name == 'custom_fname_' . $cf_key) {
                            // Name
                            $cf_name = $s_row->cset_value;
                            // Delete this blog setting
                            $blog_setting_delete_data[] = 'cset_coll_ID = ' . $DB->quote($s_row->cset_coll_ID) . ' AND cset_name = ' . $DB->quote($s_row->cset_name);
                        }
                    }
                    $custom_fields[$setting_row->cset_coll_ID][] = array('type' => $cf_type, 'key' => $cf_key, 'label' => $cf_label, 'name' => $cf_name);
                }
            }
            if (count($custom_fields)) {
                // Create post type for each blog with custom fields
                $BlogCache =& get_BlogCache();
                $itypes_insert_data = array();
                $item_type_max_ID = $DB->get_var('SELECT MAX( ityp_ID ) FROM T_items__type') + 1;
                foreach ($custom_fields as $blog_ID => $c_fields) {
                    if (!($cf_Blog = $BlogCache->get_by_ID($blog_ID, false, false))) {
                        // Skip incorrect blog ID
                        continue;
                    }
                    $itypes_insert_data[] = '( ' . $item_type_max_ID . ', ' . $DB->quote('custom_' . $cf_Blog->get('shortname')) . ', ' . '"Posts", ' . '"single", ' . $DB->quote($cf_Blog->get_setting('require_title') == 'none' ? 'never' : $cf_Blog->get_setting('require_title')) . ', ' . $DB->quote(intval($cf_Blog->get_setting('allow_html_post'))) . ', ' . $DB->quote($cf_Blog->get_setting('location_country') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_country')) . ', ' . $DB->quote($cf_Blog->get_setting('location_region') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_region')) . ', ' . $DB->quote($cf_Blog->get_setting('location_subregion') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_subregion')) . ', ' . $DB->quote($cf_Blog->get_setting('location_city') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_city')) . ', ' . $DB->quote($cf_Blog->get_setting('show_location_coordinates') ? 'optional' : 'never') . ', ' . $DB->quote(intval($cf_Blog->get_setting('disable_comments_bypost'))) . ' )';
                    // Update default post type
                    $blog_setting_item_types[$cf_Blog->ID] = $item_type_max_ID;
                    $blog_categories = $DB->get_col('SELECT cat_ID FROM T_categories WHERE cat_blog_ID = ' . $cf_Blog->ID);
                    if (count($blog_categories)) {
                        // Set new post type for each post
                        $DB->query('UPDATE T_items__item SET post_ityp_ID = ' . $item_type_max_ID . '
							WHERE post_ityp_ID = 1
							  AND post_main_cat_ID IN ( ' . implode(', ', $blog_categories) . ' )');
                        if (!empty($posttypes_perms['page'])) {
                            // Find the Pages that have at least one defined custom field:
                            $pages_SQL = new SQL();
                            $pages_SQL->SELECT('post_ID');
                            $pages_SQL->FROM('T_items__item');
                            $pages_SQL->FROM_add('INNER JOIN T_items__item_settings ON post_ID = iset_item_ID');
                            $pages_SQL->WHERE('post_main_cat_ID IN ( ' . implode(', ', $blog_categories) . ' )');
                            $pages_SQL->WHERE_and('post_ityp_ID IN ( ' . implode(', ', $posttypes_perms['page']) . ' )');
                            $pages_SQL->WHERE_and('iset_name LIKE ' . $DB->quote('custom_double_%') . ' OR iset_name LIKE ' . $DB->quote('custom_varchar_%'));
                            $pages_SQL->WHERE_and('iset_value != ""');
                            $pages_SQL->GROUP_BY('post_ID');
                            $pages_IDs = $DB->get_col($pages_SQL->get());
                            $page_type_max_ID = 0;
                            if (count($pages_IDs) > 0) {
                                // We have the Pages that have the defined custom fields
                                // Increase post type ID for new special post type for pages
                                $page_type_max_ID = $item_type_max_ID + 1;
                                $itypes_insert_data[] = '( ' . $page_type_max_ID . ', ' . $DB->quote('page_' . $cf_Blog->get('shortname')) . ', ' . '"Pages", ' . '"page", ' . $DB->quote($cf_Blog->get_setting('require_title') == 'none' ? 'never' : $cf_Blog->get_setting('require_title')) . ', ' . $DB->quote(intval($cf_Blog->get_setting('allow_html_post'))) . ', ' . $DB->quote($cf_Blog->get_setting('location_country') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_country')) . ', ' . $DB->quote($cf_Blog->get_setting('location_region') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_region')) . ', ' . $DB->quote($cf_Blog->get_setting('location_subregion') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_subregion')) . ', ' . $DB->quote($cf_Blog->get_setting('location_city') == 'hidden' ? 'never' : $cf_Blog->get_setting('location_city')) . ', ' . $DB->quote($cf_Blog->get_setting('show_location_coordinates') ? 'optional' : 'never') . ', ' . $DB->quote(intval($cf_Blog->get_setting('disable_comments_bypost'))) . ' )';
                                foreach ($c_fields as $c_field) {
                                    // Insert custom field to get new ID
                                    $DB->query('INSERT INTO T_items__type_custom_field ( itcf_ityp_ID, itcf_label, itcf_name, itcf_type )
										VALUES ( ' . $page_type_max_ID . ', ' . $DB->quote($c_field['label']) . ', ' . $DB->quote($c_field['name']) . ', ' . $DB->quote($c_field['type']) . ' )');
                                    $itcf_ID = $DB->insert_id;
                                    // Change the UID of the item settings to the new inserted itcf_ID (ID of the custom field)
                                    $DB->query('UPDATE T_items__item_settings
											SET iset_name = ' . $DB->quote('custom_' . $c_field['type'] . '_' . $itcf_ID) . '
										WHERE iset_item_ID IN ( ' . implode(', ', $pages_IDs) . ' )
											AND iset_name = ' . $DB->quote('custom_' . $c_field['type'] . '_' . $c_field['key']));
                                }
                                // Set new post type for each page
                                $DB->query('UPDATE T_items__item SET post_ityp_ID = ' . $page_type_max_ID . '
									WHERE post_ID IN ( ' . implode(', ', $pages_IDs) . ' )');
                            }
                        }
                    }
                    // Insert custom fields for standard posts (not pages)
                    foreach ($c_fields as $c_field) {
                        // Insert custom field to get new ID
                        $DB->query('INSERT INTO T_items__type_custom_field ( itcf_ityp_ID, itcf_label, itcf_name, itcf_type )
							VALUES ( ' . $item_type_max_ID . ', ' . $DB->quote($c_field['label']) . ', ' . $DB->quote($c_field['name']) . ', ' . $DB->quote($c_field['type']) . ' )');
                        $itcf_ID = $DB->insert_id;
                        // Change the UID of the item settings to the new inserted itcf_ID (ID of the custom field)
                        $DB->query('UPDATE T_items__item_settings
								SET iset_name = ' . $DB->quote('custom_' . $c_field['type'] . '_' . $itcf_ID) . '
							WHERE iset_name = ' . $DB->quote('custom_' . $c_field['type'] . '_' . $c_field['key']));
                    }
                    // Increase post type ID for next
                    $item_type_max_ID += $page_type_max_ID > 0 ? 2 : 1;
                }
                // Insert post types
                $DB->query('INSERT INTO T_items__type ( ityp_ID, ityp_name, ityp_backoffice_tab, ityp_template_name, ityp_use_title, ityp_allow_html, ityp_use_country, ityp_use_region, ityp_use_sub_region, ityp_use_city, ityp_use_coordinates, ityp_allow_disabling_comments )
					VALUES ' . implode(', ', $itypes_insert_data));
                // Delete old blog settings from DB (custom fields)
                $blog_setting_delete_data[] = 'cset_name LIKE "count_custom_%"';
                $DB->query('DELETE FROM T_coll_settings
					WHERE ( ' . implode(') OR (', $blog_setting_delete_data) . ' )');
            }
        }
        // Update default post types
        $blogs = $DB->get_col('SELECT blog_ID FROM T_blogs');
        $sql_update_blog_settings = array();
        foreach ($blogs as $blog_ID) {
            if (isset($blog_setting_item_types[$blog_ID])) {
                // Set it from custom post type
                $current_item_type = $blog_setting_item_types[$blog_ID];
            } else {
                // Set it from first non reserved post type
                if (!isset($first_item_type)) {
                    $reserved_types = array();
                    foreach ($posttypes_perms as $r_types) {
                        $reserved_types = array_merge($reserved_types, $r_types);
                    }
                    $SQL = new SQL();
                    $SQL->SELECT('ityp_ID');
                    $SQL->FROM('T_items__type');
                    if (!empty($reserved_types)) {
                        $SQL->WHERE('ityp_ID NOT IN ( ' . implode(', ', $reserved_types) . ' )');
                    }
                    $SQL->ORDER_BY('ityp_ID');
                    $SQL->LIMIT('1');
                    $first_item_type = $DB->get_var($SQL->get());
                }
                $current_item_type = $first_item_type;
            }
            $sql_update_blog_settings[] = '( ' . $DB->quote($blog_ID) . ', "default_post_type", ' . $DB->quote($current_item_type) . ' )';
        }
        if (!empty($sql_update_blog_settings)) {
            // Execute a query to update the blog settings
            $DB->query('REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				VALUES ' . implode(', ', $sql_update_blog_settings));
        }
        task_end();
        task_begin('Updating site settings... ');
        if ($DB->get_var('SELECT set_value FROM T_settings WHERE set_name = "site_color"') === NULL) {
            // Set default site color only when it is not defined yet
            $DB->query('INSERT INTO T_settings ( set_name, set_value )' . ' VALUES ( "site_color", "#ff8c0f" )');
        }
        task_end();
        set_upgrade_checkpoint('11360');
    }
    if ($old_db_version < 11370) {
        // part 18.f trunk aka 8th part of "i7"
        task_begin('Updating user settings... ');
        $DB->query('DELETE FROM T_users__usersettings WHERE uset_name = "admin_skin"');
        task_end();
        set_upgrade_checkpoint('11370');
    }
    if ($old_db_version < 11375) {
        // part 18.g trunk aka 9th part of "i7"
        task_begin('Upgrade table user field definitions... ');
        $DB->query('ALTER TABLE T_users__fielddefs
			ADD ufdf_icon_name varchar(100) COLLATE ascii_general_ci NULL');
        $DB->query('UPDATE T_users__fielddefs SET
			ufdf_icon_name = CASE
				WHEN ufdf_name = "Yahoo IM"      THEN "fa fa-yahoo"
				WHEN ufdf_name = "Skype"         THEN "fa fa-skype"
				WHEN ufdf_name = "Main phone"    THEN "fa fa-phone"
				WHEN ufdf_name = "Cell phone"    THEN "fa fa-mobile-phone"
				WHEN ufdf_name = "Office phone"  THEN "fa fa-phone"
				WHEN ufdf_name = "Home phone"    THEN "fa fa-phone"
				WHEN ufdf_name = "Office FAX"    THEN "fa fa-fax"
				WHEN ufdf_name = "Home FAX"      THEN "fa fa-fax"
				WHEN ufdf_name = "Linkedin"      THEN "fa fa-linkedin fa-x-linkedin--nudge"
				WHEN ufdf_name = "Twitter"       THEN "fa fa-twitter"
				WHEN ufdf_name = "Facebook"      THEN "fa fa-facebook"
				WHEN ufdf_name = "Flickr"        THEN "fa fa-flickr"
				WHEN ufdf_name = "YouTube"       THEN "fa fa-youtube"
				WHEN ufdf_name = "Digg"          THEN "fa fa-digg"
				WHEN ufdf_name = "StumbleUpon"   THEN "fa fa-stumbleupon"
				WHEN ufdf_name = "GitHub"        THEN "fa fa-github-alt"
				WHEN ufdf_name = "Google Plus"   THEN "fa fa-google-plus fa-x-google-plus--nudge"
				WHEN ufdf_name = "Pinterest"     THEN "fa fa-pinterest-p"
				WHEN ufdf_name = "Main address"  THEN "fa fa-building"
				WHEN ufdf_name = "Home address"  THEN "fa fa-home"
				WHEN ufdf_name = "About me"      THEN "fa fa-info-circle"
				WHEN ufdf_name = "I like"        THEN "fa fa-thumbs-o-up"
				WHEN ufdf_name = "I don\'t like" THEN "fa fa-thumbs-o-down"
				ELSE ufdf_icon_name
			END');
        task_end();
        set_upgrade_checkpoint('11375');
    }
    if ($old_db_version < 11380) {
        // part 18.h trunk aka 10th part of "i7"
        task_begin('Update links table... ');
        $DB->query('UPDATE T_links
			  SET link_position = "cover"
			WHERE link_position = "albumart"');
        task_end();
        set_upgrade_checkpoint('11380');
    }
    if ($old_db_version < 11390) {
        // part 18.i trunk aka 11th part of "i7"
        task_begin('Upgrading table of relations users with organizations... ');
        $DB->query('ALTER TABLE T_users__user_org
			ADD COLUMN uorg_role VARCHAR(255) NULL');
        task_end();
        set_upgrade_checkpoint('11390');
    }
    if ($old_db_version < 11400) {
        // part 18.j trunk aka 12th part of "i7"
        task_begin('Upgrade table user field definitions... ');
        $DB->query('ALTER TABLE T_users__fielddefs
			ADD ufdf_code varchar(20) COLLATE ascii_general_ci NULL');
        $update_user_fields = array('Micro bio' => 'microbio', 'I like' => 'ilike', 'I don\'t like' => 'idontlike', 'MSN/Live IM' => 'msnliveim', 'Yahoo IM' => 'yahooim', 'AOL AIM' => 'aolaim', 'ICQ ID' => 'icqid', 'Skype' => 'skype', 'Main phone' => 'mainphone', 'Cell phone' => 'cellphone', 'Office phone' => 'officephone', 'Home phone' => 'homephone', 'Office FAX' => 'officefax', 'Home FAX' => 'homefax', 'Twitter' => 'twitter', 'Facebook' => 'facebook', 'Google Plus' => 'googleplus', 'Linkedin' => 'linkedin', 'GitHub' => 'github', 'Website' => 'website', 'Blog' => 'blog', 'Myspace' => 'myspace', 'Flickr' => 'flickr', 'YouTube' => 'youtube', 'Digg' => 'digg', 'StumbleUpon' => 'stumbleupon', 'Pinterest' => 'pinterest', 'Role' => 'role', 'Organization' => 'organization', 'Division' => 'division', 'VAT ID' => 'vatid', 'Main address' => 'mainaddress', 'Home address' => 'homeaddress');
        foreach ($update_user_fields as $update_user_field_name => $update_user_field_code) {
            $DB->query('UPDATE T_users__fielddefs
				  SET ufdf_code = ' . $DB->quote($update_user_field_code) . '
				WHERE ufdf_name = ' . $DB->quote($update_user_field_name) . '
				LIMIT 1');
            // limit by 1 in order to update only first record to avoid the duplicate codes
        }
        // Update codes for all other unknown fields
        $DB->query('UPDATE T_users__fielddefs
				SET ufdf_code = CONCAT( "code_", ufdf_ID )
			WHERE ufdf_code IS NULL');
        // Make code field unique
        $DB->query('ALTER TABLE T_users__fielddefs
			MODIFY ufdf_code varchar(20) COLLATE ascii_general_ci UNIQUE NOT NULL');
        task_end();
        /*
         * ADD UPGRADES FOR i7 BRANCH __ABOVE__ IN THIS BLOCK.
         *
         * This part will be included in trunk and i7 branches
         */
        set_upgrade_checkpoint('11400');
    }
    if ($old_db_version < 11410) {
        // part 18.k trunk aka 13th part of "i7"
        task_begin('Upgrading skin names... ');
        $DB->query('UPDATE T_skins__skin 
							 SET skin_folder = CASE
									WHEN skin_folder = "bootstrap"        THEN "bootstrap_blog_skin"
									WHEN skin_folder = "bootstrap_main"   THEN "bootstrap_main_skin"
									WHEN skin_folder = "bootstrap_manual" THEN "bootstrap_manual_skin"
									ELSE skin_folder
			END');
        task_end();
        /*
         * ADD UPGRADES FOR i7 BRANCH __ABOVE__ IN THIS BLOCK.
         *
         * This part will be included in trunk and i7 branches
         */
        set_upgrade_checkpoint('11410');
    }
    if ($old_db_version < 11420) {
        // part 18.l trunk aka 14th part of "i7"
        // This upgrade block restores all field collations that may have been broken by the back-office DB convert tool
        // to 'ascii_bin' and 'ascii_general_ci'
        task_begin('Updating hit log keyphrases table...');
        $DB->query('ALTER TABLE T_track__keyphrase
			MODIFY keyp_phrase  VARCHAR( 255 ) COLLATE utf8_bin NOT NULL');
        task_end();
        task_begin('Check and normalize the ASCII charsets/collations... <br />');
        task_begin('- Converting skins table...');
        $DB->query("ALTER TABLE T_skins__skin\n\t\t\tMODIFY skin_type enum('normal','feed','sitemap','mobile','tablet') COLLATE ascii_general_ci NOT NULL default 'normal'");
        task_end();
        task_begin('- Converting blogs table...');
        $DB->query("ALTER TABLE T_blogs\n\t\t\tMODIFY blog_access_type    VARCHAR(10) COLLATE ascii_general_ci NOT NULL DEFAULT 'extrapath',\n\t\t\tMODIFY blog_urlname        VARCHAR(255) COLLATE ascii_general_ci NOT NULL DEFAULT 'urlname',\n\t\t\tMODIFY blog_in_bloglist    ENUM( 'public', 'logged', 'member', 'never' ) COLLATE ascii_general_ci DEFAULT 'public' NOT NULL,\n\t\t\tMODIFY blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) COLLATE ascii_general_ci DEFAULT 'default' NOT NULL,\n\t\t\tMODIFY blog_type           ENUM( 'main', 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL");
        task_end();
        task_begin('- Converting blog settings table...');
        $DB->query('ALTER TABLE T_coll_settings
			MODIFY cset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL');
        task_end();
        task_begin('- Converting widgets table...');
        $DB->query("ALTER TABLE {$tableprefix}widget\n\t\t\tMODIFY wi_type ENUM( 'core', 'plugin' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'core',\n\t\t\tMODIFY wi_code VARCHAR(32) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting categories table...');
        $DB->query("ALTER TABLE T_categories\n\t\t\tMODIFY cat_urlname varchar(255) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY cat_subcat_ordering enum('parent', 'alpha', 'manual') COLLATE ascii_general_ci NULL DEFAULT NULL");
        task_end();
        task_begin('- Converting posts table...');
        $DB->query("ALTER TABLE T_items__item\n\t\t\tMODIFY post_status               enum('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NOT NULL default 'published',\n\t\t\tMODIFY post_urltitle             VARCHAR(210) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY post_notifications_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq',\n\t\t\tMODIFY post_comment_status       ENUM('disabled', 'open', 'closed') COLLATE ascii_general_ci NOT NULL DEFAULT 'open',\n\t\t\tMODIFY post_renderers            VARCHAR(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting comments table...');
        $DB->query("ALTER TABLE T_comments\n\t\t\tMODIFY comment_type         enum('comment','linkback','trackback','pingback','meta') COLLATE ascii_general_ci NOT NULL default 'comment',\n\t\t\tMODIFY comment_status       ENUM('published','community','deprecated','protected','private','review','draft','trash') COLLATE ascii_general_ci DEFAULT 'published' NOT NULL,\n\t\t\tMODIFY comment_author_email varchar(255) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY comment_author_IP    varchar(45) COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY comment_renderers    VARCHAR(255) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY comment_secret       CHAR(32) COLLATE ascii_general_ci NULL default NULL,\n\t\t\tMODIFY comment_notif_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq' COMMENT 'Have notifications been sent for this comment? How far are we in the process?'");
        task_end();
        task_begin('- Converting post prerendered contents table...');
        $DB->query("ALTER TABLE T_items__prerendering\n\t\t\tMODIFY itpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY itpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting comment prerendered contents table...');
        $DB->query("ALTER TABLE T_comments__prerendering\n\t\t\tMODIFY cmpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY cmpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting post versions table...');
        $DB->query("ALTER TABLE T_items__version\n\t\t\tMODIFY iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NULL");
        task_end();
        task_begin('- Converting post types table...');
        $DB->query("ALTER TABLE T_items__type\n\t\t\tMODIFY ityp_use_title              ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'required',\n\t\t\tMODIFY ityp_use_url                ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_text               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_excerpt            ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_title_tag          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_meta_desc          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_meta_keywds        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_tags               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',\n\t\t\tMODIFY ityp_use_country            ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tMODIFY ityp_use_region             ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tMODIFY ityp_use_sub_region         ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tMODIFY ityp_use_city               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tMODIFY ityp_use_coordinates        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',\n\t\t\tMODIFY ityp_use_comment_expiration ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional'");
        task_end();
        task_begin('- Converting post types custom fields table...');
        $DB->query("ALTER TABLE T_items__type_custom_field\n\t\t\tMODIFY itcf_name VARCHAR(255) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY itcf_type ENUM( 'double', 'varchar' ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting post settings table...');
        $DB->query("ALTER TABLE T_items__item_settings\n\t\t\tMODIFY iset_name varchar( 50 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting user permissions table...');
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\tMODIFY bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloguser_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',\n\t\t\tMODIFY bloguser_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloguser_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        task_end();
        task_begin('- Converting group permissions table...');
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\tMODIFY bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloggroup_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',\n\t\t\tMODIFY bloggroup_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY bloggroup_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        task_end();
        task_begin('- Converting links table...');
        $DB->query("ALTER TABLE T_links\n\t\t\tMODIFY link_position varchar(10) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting files table...');
        $DB->query("ALTER TABLE T_files\n\t\t\tMODIFY file_type      enum('image', 'audio', 'other') COLLATE ascii_general_ci NULL DEFAULT NULL,\n\t\t\tMODIFY file_root_type enum('absolute','user','collection','shared','skins','import') COLLATE ascii_general_ci NOT NULL DEFAULT 'absolute'");
        task_end();
        task_begin('- Converting file types table...');
        $DB->query("ALTER TABLE T_filetypes\n\t\t\tMODIFY ftyp_extensions varchar(30) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ftyp_viewtype   varchar(10) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ftyp_allowed    enum('any','registered','admin') COLLATE ascii_general_ci NOT NULL default 'admin'");
        task_end();
        task_begin('- Converting messages table...');
        $DB->query("ALTER TABLE T_messaging__message\n\t\t\tMODIFY msg_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting message prerendering contents table...');
        $DB->query("ALTER TABLE T_messaging__prerendering\n\t\t\tMODIFY mspr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY mspr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting sessions table...');
        $DB->query("ALTER TABLE T_sessions\n\t\t\tMODIFY sess_key       CHAR(32) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY sess_ipaddress VARCHAR(45) COLLATE ascii_general_ci NOT NULL DEFAULT '',\n\t\t\tMODIFY sess_device    VARCHAR(8) COLLATE ascii_general_ci NOT NULL DEFAULT ''");
        task_end();
        task_begin('- Converting domains table...');
        $DB->query("ALTER TABLE T_basedomains\n\t\t\tMODIFY dom_status ENUM('unknown','trusted','suspect','blocked') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown',\n\t\t\tMODIFY dom_type   ENUM('unknown','normal','searcheng','aggregator','email') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'");
        task_end();
        task_begin('- Converting logs table...');
        $DB->query("ALTER TABLE T_hitlog\n\t\t\tMODIFY hit_ctrl         VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY hit_type         ENUM('standard','rss','admin','ajax', 'service') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL,\n\t\t\tMODIFY hit_referer_type ENUM('search','special','spam','referer','direct','self') COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY hit_remote_addr  VARCHAR(45) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY hit_agent_type   ENUM('robot','browser','unknown') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL");
        task_end();
        task_begin('- Converting goal categories table...');
        $DB->query("ALTER TABLE T_track__goalcat\n\t\t\tMODIFY gcat_color  char(7) COLLATE ascii_general_ci default NULL");
        task_end();
        task_begin('- Converting groups table...');
        $DB->query("ALTER TABLE T_groups\n\t\t\tMODIFY grp_perm_blogs                  enum('user','viewall','editall') COLLATE ascii_general_ci NOT NULL default 'user',\n\t\t\tMODIFY grp_perm_xhtmlvalidation        VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',\n\t\t\tMODIFY grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',\n\t\t\tMODIFY grp_perm_stats                  enum('none','user','view','edit') COLLATE ascii_general_ci NOT NULL default 'none'");
        task_end();
        task_begin('- Converting group settings table...');
        $DB->query("ALTER TABLE T_groups__groupsettings\n\t\t\tMODIFY gset_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting settings table...');
        $DB->query("ALTER TABLE T_settings\n\t\t\tMODIFY set_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cache table...');
        $DB->query("ALTER TABLE T_global__cache\n\t\t\tMODIFY cach_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting users table...');
        $DB->query("ALTER TABLE T_users\n\t\t\tMODIFY user_email           varchar(255) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY user_status          enum( 'activated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new',\n\t\t\tMODIFY user_unsubscribe_key CHAR(32) COLLATE ascii_general_ci NOT NULL default '' COMMENT 'A specific key, it is used when a user wants to unsubscribe from a post comments without signing in',\n\t\t\tMODIFY user_gender          char(1) COLLATE ascii_general_ci NULL");
        task_end();
        task_begin('- Converting user fields table...');
        $DB->query("ALTER TABLE T_users__fielddefs\n\t\t\tMODIFY ufdf_type       char(8) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ufdf_required   enum('hidden','optional','recommended','require') COLLATE ascii_general_ci NOT NULL default 'optional',\n\t\t\tMODIFY ufdf_duplicated enum('forbidden','allowed','list') COLLATE ascii_general_ci NOT NULL default 'allowed',\n\t\t\tMODIFY ufdf_icon_name  varchar(100) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY ufdf_code       varchar(20) COLLATE ascii_general_ci UNIQUE NOT NULL");
        task_end();
        task_begin('- Converting user reports table...');
        $DB->query("ALTER TABLE T_users__reports\n\t\t\tMODIFY urep_status enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ) COLLATE ascii_general_ci");
        task_end();
        task_begin('- Converting user invitation codes table...');
        $DB->query("ALTER TABLE T_users__invitation_code\n\t\t\tMODIFY ivc_code varchar(32) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting locales table...');
        $DB->query("ALTER TABLE T_locales\n\t\t\tMODIFY loc_datefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'y-m-d',\n\t\t\tMODIFY loc_timefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i:s',\n\t\t\tMODIFY loc_shorttimefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i'");
        task_end();
        task_begin('- Converting antispam table...');
        $DB->query("ALTER TABLE {$tableprefix}antispam\n\t\t\tMODIFY aspm_source enum( 'local','reported','central' ) COLLATE ascii_general_ci NOT NULL default 'reported'");
        task_end();
        task_begin('- Converting IP ranges table...');
        $DB->query("ALTER TABLE T_antispam__iprange\n\t\t\tMODIFY aipr_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL");
        task_end();
        task_begin('- Converting user settings table...');
        $DB->query("ALTER TABLE T_users__usersettings\n\t\t\tMODIFY uset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugins table...');
        $DB->query("ALTER TABLE T_plugins\n\t\t\tMODIFY plug_classname VARCHAR(40) COLLATE ascii_general_ci NOT NULL default '',\n\t\t\tMODIFY plug_code      VARCHAR(32) COLLATE ascii_general_ci NULL,\n\t\t\tMODIFY plug_version   VARCHAR(42) COLLATE ascii_general_ci NOT NULL default '0',\n\t\t\tMODIFY plug_status    ENUM( 'enabled', 'disabled', 'needs_config', 'broken' ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin settings table...');
        $DB->query("ALTER TABLE T_pluginsettings\n\t\t\tMODIFY pset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin user settings table...');
        $DB->query("ALTER TABLE T_pluginusersettings\n\t\t\tMODIFY puset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting plugin events table...');
        $DB->query("ALTER TABLE T_pluginevents\n\t\t\tMODIFY pevt_event VARCHAR(40) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cron tasks table...');
        $DB->query("ALTER TABLE T_cron__task\n\t\t\tMODIFY ctsk_key varchar(50) COLLATE ascii_general_ci not null");
        task_end();
        task_begin('- Converting cron logs table...');
        $DB->query("ALTER TABLE T_cron__log\n\t\t\tMODIFY clog_status enum('started','finished','error','timeout') COLLATE ascii_general_ci not null default 'started'");
        task_end();
        task_begin('- Converting countries table...');
        $DB->query("ALTER TABLE T_regional__country\n\t\t\tMODIFY ctry_code   char(2) COLLATE ascii_general_ci NOT NULL,\n\t\t\tMODIFY ctry_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL");
        task_end();
        task_begin('- Converting regions table...');
        $DB->query("ALTER TABLE T_regional__region\n\t\t\tMODIFY rgn_code char(6) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting subregions table...');
        $DB->query("ALTER TABLE T_regional__subregion\n\t\t\tMODIFY subrg_code char(6) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting cities table...');
        $DB->query("ALTER TABLE T_regional__city\n\t\t\tMODIFY city_postcode char(12) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting currencies table...');
        $DB->query("ALTER TABLE T_regional__currency\n\t\t\tMODIFY curr_code char(3) COLLATE ascii_general_ci NOT NULL");
        task_end();
        task_begin('- Converting slugs table...');
        $DB->query("ALTER TABLE T_slug\n\t\t\tMODIFY slug_title varchar(255) COLLATE ascii_bin NOT NULL,\n\t\t\tMODIFY slug_type\tchar(6) COLLATE ascii_bin NOT NULL DEFAULT 'item'");
        task_end();
        task_begin('- Converting email logs table...');
        $DB->query("ALTER TABLE T_email__log\n\t\t\tMODIFY emlog_to     VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emlog_result ENUM( 'ok', 'error', 'blocked' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'ok'");
        task_end();
        task_begin('- Converting email returns table...');
        $DB->query("ALTER TABLE T_email__returns\n\t\t\tMODIFY emret_address   VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emret_errtype   CHAR(1) COLLATE ascii_general_ci NOT NULL DEFAULT 'U'");
        task_end();
        task_begin('- Converting email addresses table...');
        $DB->query("ALTER TABLE T_email__address\n\t\t\tMODIFY emadr_address VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,\n\t\t\tMODIFY emadr_status  ENUM( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'");
        task_end();
        task_begin('- Converting system log table...');
        $DB->query("ALTER TABLE T_syslog\n\t\t\tMODIFY slg_type   ENUM('info', 'warning', 'error', 'critical_error') COLLATE ascii_general_ci NOT NULL DEFAULT 'info',\n\t\t\tMODIFY slg_origin ENUM('core', 'plugin') COLLATE ascii_general_ci,\n\t\t\tMODIFY slg_object ENUM('comment', 'item', 'user', 'file') COLLATE ascii_general_ci");
        task_end();
        task_end();
        set_upgrade_checkpoint('11420');
    }
    if ($old_db_version < 11430) {
        // part 18.m trunk aka 15th part of "i7"
        task_begin('Upgrading tags table...');
        // Get all tags that contain not ascii chars, because some mysql versions cannot convert them correctly to utf8_bin
        $not_ascii_tags = $DB->get_results('SELECT *
			 FROM T_items__tag
			WHERE tag_name NOT REGEXP "^[A-Za-z0-9_\\-\\s]+$"');
        foreach ($not_ascii_tags as $not_ascii_tag) {
            // Replace each not ascii char with "_" in tag name in order to avoid error on below table upgrading
            $ascii_tag_name = preg_replace('/[^A-Za-z0-9_\\-\\s]/', '_', $not_ascii_tag->tag_name);
            $ascii_tag_name = str_replace('__', '_', $ascii_tag_name);
            if ($ascii_tag_name == $not_ascii_tag->tag_name) {
                // Skip this tag name because it doesn't contain not ascii chars really
                continue;
            }
            // Check tag name for uniqueness
            $c = 1;
            $new_tag_name = $ascii_tag_name;
            while ($DB->get_var('SELECT tag_ID
				 FROM T_items__tag
				WHERE tag_name = ' . $DB->quote($new_tag_name))) {
                $new_tag_name = $ascii_tag_name . $c;
                $c++;
            }
            // Update tag name to new value without not ascii chars
            $DB->query('UPDATE T_items__tag
				  SET tag_name = ' . $DB->quote($new_tag_name) . '
				WHERE tag_ID = ' . $not_ascii_tag->tag_ID);
        }
        // Remove the empty tags
        $empty_tag_IDs = $DB->get_col('SELECT tag_ID FROM T_items__tag
			WHERE tag_name = ""');
        if (!empty($empty_tag_IDs)) {
            $DB->query('DELETE FROM T_items__tag
				WHERE tag_ID IN ( ' . $DB->quote($empty_tag_IDs) . ' ) ');
            $DB->query('DELETE FROM T_items__itemtag
				WHERE itag_tag_ID IN ( ' . $DB->quote($empty_tag_IDs) . ' ) ');
        }
        // Upgrade field "tag_name" from varbinary to varchar utf8_bin
        $DB->query('ALTER TABLE T_items__tag
			MODIFY tag_name VARCHAR(50) COLLATE utf8_bin NOT NULL');
        // Allow multiple special char variations for each tag
        task_end();
        task_begin('Upgrading collection user/group permissions tables...');
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\tMODIFY bloguser_perm_edit ENUM('no','own','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\tMODIFY bloggroup_perm_edit ENUM('no','own','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'");
        task_end();
        // fp> Note: do NOT put back and "add upgrades" comment here. The comment is OUTSIDE of the block now!
        set_upgrade_checkpoint('11430');
    }
    if ($old_db_version < 11440) {
        // part 18.n trunk aka 16th part of "i7"
        task_begin('Upgrading base domains table...');
        $DB->query("ALTER TABLE T_basedomains\n\t\t\tMODIFY dom_name VARCHAR(250) COLLATE utf8_bin NOT NULL DEFAULT ''");
        task_end();
        set_upgrade_checkpoint('11440');
    }
    if ($old_db_version < 11450) {
        // part 18.o trunk aka 17th part of "i7"
        task_begin('Upgrading blog-group permissions table...');
        $DB->query("ALTER TABLE T_coll_group_perms\n\t\t\tADD COLUMN bloggroup_perm_item_type ENUM('standard','restricted','admin') COLLATE ascii_general_ci NOT NULL default 'standard' AFTER bloggroup_perm_poststatuses,\n\t\t\tDROP COLUMN bloggroup_perm_page,\n\t\t\tDROP COLUMN bloggroup_perm_intro,\n\t\t\tDROP COLUMN bloggroup_perm_podcast,\n\t\t\tDROP COLUMN bloggroup_perm_sidebar");
        task_end();
        task_begin('Upgrading blog-user permissions table...');
        $DB->query("ALTER TABLE T_coll_user_perms\n\t\t\tADD COLUMN bloguser_perm_item_type ENUM('standard','restricted','admin') COLLATE ascii_general_ci NOT NULL default 'standard' AFTER bloguser_perm_poststatuses,\n\t\t\tDROP COLUMN bloguser_perm_page,\n\t\t\tDROP COLUMN bloguser_perm_intro,\n\t\t\tDROP COLUMN bloguser_perm_podcast,\n\t\t\tDROP COLUMN bloguser_perm_sidebar");
        task_end();
        task_begin('Upgrade post types table... ');
        $DB->query("ALTER TABLE T_items__type\n\t\t\tADD COLUMN ityp_perm_level ENUM( 'standard', 'restricted', 'admin' ) COLLATE ascii_general_ci NOT NULL default 'standard'");
        task_end();
        set_upgrade_checkpoint('11450');
    }
    if ($old_db_version < 11460) {
        // part 18.p trunk aka 18th part of "i7"
        task_begin('Creating table for PostType-to-Collection relationships...');
        $DB->query("CREATE TABLE T_items__type_coll (\n\t\t\titc_ityp_ID int(11) unsigned NOT NULL,\n\t\t\titc_coll_ID int(11) unsigned NOT NULL,\n\t\t\tPRIMARY KEY (itc_ityp_ID, itc_coll_ID),\n\t\t\tUNIQUE itemtypecoll ( itc_ityp_ID, itc_coll_ID )\n\t\t) ENGINE = innodb");
        task_end();
        task_begin('Updating collection permissions... ');
        $DB->query('UPDATE T_coll_group_perms
			  SET bloggroup_perm_item_type = "restricted"
			WHERE bloggroup_perm_item_type = "standard"');
        $DB->query('UPDATE T_coll_user_perms
			  SET bloguser_perm_item_type = "restricted"
			WHERE bloguser_perm_item_type = "standard"');
        task_end();
        task_begin('Updating post types table... ');
        $DB->query('UPDATE T_items__type SET
			ityp_perm_level = CASE
				WHEN ityp_ID = "1"    THEN "standard"
				WHEN ityp_ID = "100"  THEN "standard"
				WHEN ityp_ID = "200"  THEN "standard"
				WHEN ityp_ID = "1000" THEN "restricted"
				WHEN ityp_ID = "1400" THEN "restricted"
				WHEN ityp_ID = "1500" THEN "restricted"
				WHEN ityp_ID = "1520" THEN "restricted"
				WHEN ityp_ID = "1530" THEN "restricted"
				WHEN ityp_ID = "1570" THEN "restricted"
				WHEN ityp_ID = "1600" THEN "restricted"
				WHEN ityp_ID = "2000" THEN "standard"
				WHEN ityp_ID = "3000" THEN "admin"
				WHEN ityp_ID = "4000" THEN "admin"
				ELSE ityp_perm_level
			END');
        task_end();
        set_upgrade_checkpoint('11460');
    }
    if ($old_db_version < 11470) {
        // part 18.r trunk aka 19th part of "i7"
        task_begin('Updating widgets table... ');
        // Disable all widgets of Menu container for all "Main" collections
        $DB->query('UPDATE ' . $tableprefix . 'widget
			INNER JOIN T_blogs ON blog_ID = wi_coll_ID AND blog_type = "main"
			  SET wi_enabled = 0
			WHERE wi_sco_name = "Menu"');
        task_end();
        set_upgrade_checkpoint('11470');
    }
    if ($old_db_version < 11480) {
        // part 18.s trunk aka 20th part of "i7"
        task_begin('Updating table for PostType-to-Collection relationships... ');
        // Get all collections:
        $collections_SQL = new SQL();
        $collections_SQL->SELECT('blog_ID, blog_type');
        $collections_SQL->FROM('T_blogs');
        $collections = $DB->get_assoc($collections_SQL->get());
        // Get all post types:
        $posttypes_SQL = new SQL();
        $posttypes_SQL->SELECT('ityp_ID');
        $posttypes_SQL->FROM('T_items__type');
        $posttypes = $DB->get_col($posttypes_SQL->get());
        // Enable post types for the collections:
        $posttypes_collections = array();
        foreach ($collections as $collection_ID => $collection_type) {
            switch ($collection_type) {
                // Set what post types should not be enabled depending on the collection type:
                case 'main':
                case 'photo':
                    $skip_posttypes = array(100, 200, 2000, 5000);
                    break;
                case 'forum':
                    $skip_posttypes = array(1, 100, 2000, 5000);
                    break;
                case 'manual':
                    $skip_posttypes = array(1, 200, 2000, 5000);
                    break;
                default:
                    // 'std'
                    $skip_posttypes = array(100, 200, 5000);
                    break;
            }
            foreach ($posttypes as $posttype_ID) {
                if (in_array($posttype_ID, $skip_posttypes)) {
                    // Skip(Don't enable) this post type for the collection:
                    continue;
                }
                $posttypes_collections[] = '( ' . $posttype_ID . ', ' . $collection_ID . ' )';
            }
        }
        if (count($posttypes_collections)) {
            // Update the relationships only when at least one is required:
            $DB->query('REPLACE INTO T_items__type_coll
				( itc_ityp_ID, itc_coll_ID )
				VALUES ' . implode(', ', $posttypes_collections));
        }
        task_end();
        set_upgrade_checkpoint('11480');
    }
    if ($old_db_version < 11482) {
        // v6.6.3
        task_begin('Updating default post types for forums and manual collections... ');
        $item_types = array('manual' => array('ID' => 100, 'name' => 'Manual Page'), 'forum' => array('ID' => 200, 'name' => 'Forum Topic'));
        $update_default_type_sql = array();
        foreach ($item_types as $collection_type => $item_type) {
            // Try to find an item type by ID or name:
            $item_type_ID = $DB->get_var('SELECT ityp_ID
				 FROM T_items__type
				WHERE ityp_ID = ' . $item_type['ID'] . '
				   OR ityp_name = ' . $DB->quote($item_type['name']));
            if (empty($item_type_ID)) {
                // Item type is not found in DB, Skip it:
                continue;
            }
            // Get all collections with type:
            $type_collection_IDs = $DB->get_col('SELECT blog_ID
				 FROM T_blogs
				WHERE blog_type = ' . $DB->quote($collection_type));
            foreach ($type_collection_IDs as $type_collection_ID) {
                $update_default_type_sql[] = '( ' . $type_collection_ID . ', "default_post_type", ' . $DB->quote($item_type_ID) . ' )';
            }
        }
        if (count($update_default_type_sql) > 0) {
            // Update default post types of collections:
            $DB->query('REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				VALUES ' . implode(',', $update_default_type_sql));
        }
        task_end();
        set_upgrade_checkpoint('11482');
    }
    if ($old_db_version < 11483) {
        // v6.6.4
        task_begin('Updating general settings...');
        $DB->query('UPDATE T_settings
				SET set_value = ' . $DB->quote('no') . '
			WHERE set_name = ' . $DB->quote('newusers_canregister') . '
				AND set_value = ' . $DB->quote('0'));
        task_end();
        task_begin('Updating user settings...');
        $DB->query('ALTER TABLE T_users__usersettings CHANGE COLUMN uset_name uset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL');
        $DB->query('ALTER TABLE T_pluginusersettings CHANGE COLUMN puset_name puset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL');
        task_end();
        set_upgrade_checkpoint('11483');
    }
    if ($old_db_version < 11484) {
        // part 2 of v6.6.4
        task_begin('Upgrade table item types... ');
        $DB->query("ALTER TABLE T_items__type\n\t\t\tADD ityp_use_parent ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never' AFTER ityp_use_url");
        task_end();
        set_upgrade_checkpoint('11484');
    }
    if ($old_db_version < 11485) {
        // v6.6.6
        task_begin('Upgrade table item types... ');
        $DB->query('ALTER TABLE T_items__type
			ADD ityp_allow_breaks TINYINT DEFAULT 1 AFTER ityp_allow_html');
        $DB->query('UPDATE T_items__type
			SET ityp_allow_breaks = 0,
			    ityp_allow_featured = 0
			WHERE ityp_ID >= 1400
			  AND ityp_ID <= 1600');
        task_end();
        set_upgrade_checkpoint('11485');
    }
    if ($old_db_version < 11486) {
        // part 2 of v6.6.6
        task_begin('Upgrade timestamp fields... ');
        $DB->query('ALTER TABLE T_email__log
			MODIFY emlog_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_email__returns
			MODIFY emret_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_syslog
			MODIFY slg_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_items__prerendering
			MODIFY itpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_comments__prerendering
			MODIFY cmpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__prerendering
			MODIFY mspr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_users__reports
			MODIFY urep_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_items__version
			MODIFY iver_edit_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__thread
			MODIFY thrd_datemodified datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__message
			MODIFY msg_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        $DB->query('ALTER TABLE T_messaging__contact
			MODIFY mct_last_contact_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'');
        task_end();
        // set_upgrade_checkpoint( '11486' );
    }
    /*
     * ADD UPGRADES __ABOVE__ IN A NEW UPGRADE BLOCK.
     *
     * YOU MUST USE:
     * task_begin( 'Descriptive text about action...' );
     * task_end();
     *
     * ALL DB CHANGES MUST BE EXPLICITLY CARRIED OUT. DO NOT RELY ON SCHEMA UPDATES!
     * Schema updates do not survive after several incremental changes.
     *
     * NOTE: every change that gets done here, should bump {@link $new_db_version} (by 100).
     */
    // Execute general upgrade tasks.
    // These tasks needs to be called after every upgrade process, except if they were already executed but the upgrade was not finished because of the max execution time check.
    if (param('exec_general_tasks', 'boolean', 1)) {
        // We haven't executed these general tasks yet:
        // Update modules own b2evo tables
        echo "Calling modules for individual upgrades...<br>\n";
        evo_flush();
        modules_call_method('upgrade_b2evo_tables');
        // Just in case, make sure the db schema version is up to date at the end.
        if ($old_db_version != $new_db_version) {
            // Update DB schema version to $new_db_version
            set_upgrade_checkpoint($new_db_version);
        }
        // We're going to need some environment in order to init caches and create profile picture links...
        if (!is_object($Settings)) {
            // create Settings object
            load_class('settings/model/_generalsettings.class.php', 'GeneralSettings');
            $Settings = new GeneralSettings();
        }
        if (!is_object($Plugins)) {
            // create Plugins object
            load_class('plugins/model/_plugins.class.php', 'Plugins');
            $Plugins = new Plugins();
        }
        // Init Caches:
        load_funcs('tools/model/_system.funcs.php');
        system_init_caches(true, $old_db_version <= 11410);
        // Only force enabling the caches if we upgrade from a version older or equal to 11410 (6.4.2-beta)
        // note: the above outputs messages
        // Check/Repair Caches:
        task_begin('Checking &amp; repairing caches...');
        load_funcs('tools/model/_system.funcs.php');
        // Check all cache folders if exist and work properly. Try to repair cache folders if they aren't ready for operation.
        $check_cache_messages = system_check_caches(true);
        if (is_array($check_cache_messages) && count($check_cache_messages)) {
            // Display errors of the cache checking
            foreach ($check_cache_messages as $check_cache_message) {
                echo '<br /><span class="text-danger"><evo:error>' . $check_cache_message . '</evo:error></span>';
            }
            echo '<br />';
        }
        task_end();
        // Check if profile picture links should be recreated. It won't be executed in each upgrade, but only in those cases when it is required.
        // This requires an up to date database, and also $Plugins and $GeneralSettings objects must be initialized before this.
        // Note: Check $create_profile_picture_links intialization and usage above to get more information.
        if ($create_profile_picture_links) {
            // Create links for all files from the users profile_pictures folder
            task_begin('Creating profile picture links...');
            create_profile_picture_links();
            task_end();
        }
        // Invalidate all page caches after every upgrade.
        // A new version of b2evolution may not use the same links to access special pages.
        // We want to play it safe here so that people don't think that upgrading broke their blog!
        task_begin('Invalidating all page caches to make sure they don\'t contain old action links...');
        invalidate_pagecaches();
        task_end();
        // Reload plugins after every upgrade, to detect even those changes on plugins which didn't require db modifications
        task_begin('Reloading installed plugins to make sure their config is up to date...');
        $Plugins_admin =& get_Plugins_admin();
        $Plugins_admin->reload_plugins();
        task_end();
        // This has to be at the end because plugin install may fail if the DB schema is not current (matching Plugins class).
        // Only new default plugins will be installed, based on $old_db_version.
        // dh> NOTE: if this fails (e.g. fatal error in one of the plugins), it will not get repeated
        task_begin('Installing new default plugins (if any)...');
        install_basic_plugins($old_db_version);
        task_end();
        // Create default cron jobs (this can be done at each upgrade):
        echo "Checking if some default cron jobs need to be installed...<br/>\n";
        evo_flush();
        require_once dirname(__FILE__) . '/_functions_create.php';
        create_default_jobs(true);
        // "Time running low" test: Check if the upgrade script elapsed time is close to the max execution time.
        // Note: This should not really happen except the case when many plugins must be installed.
        task_begin('Checking timing of upgrade...');
        $elapsed_time = time() - $script_start_time;
        $max_exe_time = ini_get('max_execution_time');
        if ($max_exe_time && $elapsed_time > $max_exe_time - 20) {
            // Max exe time not disabled and we're recahing the end
            // URL to continue the upgrade process from install folder
            $recreate_excerpts = $recreate_autogenerated_excerpts ? '&amp;recreate_excerpts=1' : '';
            $upgrade_continue_url = $baseurl . 'install/index.php?locale=' . $locale . '&amp;action=' . $upgrade_action . '&amp;exec_general_tasks=0' . $recreate_excerpts;
            echo 'We are reaching the time limit for this script. Please click <a href="' . $upgrade_continue_url . '">continue</a>...';
            // Dirty temporary solution:
            exit(0);
        }
        task_end();
    }
    if ($recreate_autogenerated_excerpts) {
        if (!is_object($Settings)) {
            // create Settings object
            load_class('settings/model/_generalsettings.class.php', 'GeneralSettings');
            $Settings = new GeneralSettings();
        }
        if (!is_object($Plugins)) {
            // create Plugins object
            load_class('plugins/model/_plugins.class.php', 'Plugins');
            $Plugins = new Plugins();
        }
        task_begin('Recreate autogenerated post excerpts...');
        $upgrade_continue_url = $baseurl . 'install/index.php?locale=' . $locale . '&amp;action=' . $upgrade_action . '&amp;exec_general_tasks=0&amp;recreate_excerpts=1';
        $all_excerpt = param('all_excerpt', 'integer', 0);
        recreate_autogenerated_excerpts($upgrade_continue_url, $all_excerpt == 0);
        task_end();
    }
    // Update the progress bar status
    update_install_progress_bar();
    /*
     * -----------------------------------------------
     * Check to make sure the DB schema is up to date:
     * -----------------------------------------------
     */
    echo "Starting to check DB...<br/>\n";
    evo_flush();
    $upgrade_db_deltas = array();
    // This holds changes to make, if any (just all queries)
    global $debug;
    foreach ($schema_queries as $table => $query_info) {
        // For each table in the schema, check diffs...
        if ($debug) {
            echo '<br />Checking table: ' . $table . ': ';
        }
        $updates = db_delta($query_info[1], array('drop_column', 'drop_index'), false, true);
        if (empty($updates)) {
            if ($debug) {
                echo 'ok';
            }
        } else {
            if ($debug) {
                echo 'NEEDS UPDATE!';
            }
            foreach ($updates as $table => $queries) {
                foreach ($queries as $qinfo) {
                    foreach ($qinfo['queries'] as $query) {
                        // subqueries for this query (usually one, but may include required other queries)
                        $upgrade_db_deltas[] = $query;
                    }
                }
            }
        }
    }
    if ($debug) {
        echo '<br />';
    }
    if (empty($upgrade_db_deltas)) {
        // no upgrades needed:
        echo '<p>' . T_('The database schema is up to date.') . '</p>';
    } else {
        // Upgrades are needed:
        $confirmed_db_upgrade = param('confirmed', 'integer', 0);
        // force confirmation
        $upgrade_db_deltas_confirm_md5 = param('upgrade_db_deltas_confirm_md5', 'string', '');
        if (!$confirmed_db_upgrade) {
            if (!empty($upgrade_db_deltas_confirm_md5)) {
                // received confirmation from form
                if ($upgrade_db_deltas_confirm_md5 != md5(implode('', $upgrade_db_deltas))) {
                    // unlikely to happen
                    echo '<p class="text-danger"><evo:error>' . T_('The DB schema has been changed since confirmation.') . '</evo:error></p>';
                } else {
                    $confirmed_db_upgrade = true;
                }
            }
        }
        if (!$confirmed_db_upgrade) {
            global $action, $form_action;
            load_class('_core/ui/forms/_form.class.php', 'Form');
            if (!empty($form_action)) {
                $Form = new Form($form_action, '', 'post');
            } else {
                $Form = new Form(NULL, '', 'post');
            }
            $Form->begin_form('fform', T_('Upgrade database'));
            $Form->begin_fieldset();
            $Form->hidden('upgrade_db_deltas_confirm_md5', md5(implode('', $upgrade_db_deltas)));
            $Form->hidden('action', $action);
            $Form->hidden('locale', $locale);
            echo '<p>' . T_('The version number is correct, but we have detected changes in the database schema. This can happen if you\'ve been using development versions directly off GitHub...') . '</p>';
            echo '<p>' . T_('The following database changes will be carried out. If you are not sure what this means, it will probably be alright.') . '</p>';
            echo '<ul>';
            foreach ($upgrade_db_deltas as $l_delta) {
                #echo '<li><code>'.nl2br($l_delta).'</code></li>';
                echo '<li><pre>' . str_replace("\t", '  ', $l_delta) . '</pre></li>';
            }
            echo '</ul>';
            $Form->submit(array('', T_('Try to Repair/Upgrade database now!'), 'btn-warning'));
            $Form->end_form();
            return 'need-fix';
        }
        // Alter DB to match DB schema:
        install_make_db_schema_current(true);
    }
    // Force MySQL strict mode
    $DB->query('SET sql_mode = "TRADITIONAL"', 'Force MySQL "strict" mode (and make sure server is not configured with a weird incompatible mode)');
    track_step('upgrade-success');
    return true;
}
Esempio n. 17
0
 /**
  * Get the latest Comment on this Item
  *
  * @param string the status of the latest comment
  * @return Comment
  */
 function &get_latest_Comment($status = NULL)
 {
     global $DB;
     if (is_null($this->latest_Comment)) {
         $SQL = new SQL('Get the latest Comment on the Item');
         $SQL->SELECT('comment_ID');
         $SQL->FROM('T_comments');
         $SQL->WHERE('comment_item_ID = ' . $DB->quote($this->ID));
         $SQL->WHERE_and('comment_type != "meta"');
         $SQL->ORDER_BY('comment_date DESC');
         $SQL->LIMIT('1');
         if ($status != NULL) {
             $SQL->WHERE_and('comment_status = ' . $DB->quote($status));
         }
         if ($comment_ID = $DB->get_var($SQL->get())) {
             $CommentCache =& get_CommentCache();
             $this->latest_Comment =& $CommentCache->get_by_ID($comment_ID);
         }
     }
     return $this->latest_Comment;
 }
Esempio n. 18
0
/**
 * Import the messages
 */
function phpbb_import_messages()
{
    global $DB, $phpbb_DB, $tableprefix;
    if (!phpbb_check_step('messages')) {
        // Check current step
        return;
        // Exit here if we cannot process this step
    }
    // Reset previous value
    phpbb_unset_var('messages_count_imported');
    phpbb_log(T_('Importing messages...'));
    $DB->begin();
    // Init SQL to get the messages data and the count of the messages
    $SQL = new SQL();
    $SQL->FROM('BB_privmsgs m');
    $SQL->FROM_add('LEFT JOIN BB_privmsgs_text mt ON m.privmsgs_id = mt.privmsgs_text_id');
    // Get the count of the messages
    $count_SQL = $SQL;
    $count_SQL->SELECT('COUNT( m.privmsgs_id )');
    $phpbb_messages_count = $phpbb_DB->get_var($count_SQL->get());
    if ($phpbb_messages_count > 0) {
        phpbb_log(sprintf(T_('%s messages have been found in the phpBB database'), $phpbb_messages_count));
    } else {
        // No messages
        phpbb_log(T_('No found messages in the phpBB database.'), 'error');
        $DB->commit();
        return;
        // Exit here
    }
    $users_IDs = phpbb_table_get_links('users');
    phpbb_log(T_('Start importing <b>private messages</b> into the b2evolution database...'), 'message', '');
    // Init SQL to get the messages from phpbb database
    $SQL->SELECT('m.privmsgs_id, m.privmsgs_subject, mt.privmsgs_text, m.privmsgs_date, m.privmsgs_from_userid, m.privmsgs_to_userid, mt.privmsgs_bbcode_uid');
    $SQL->WHERE('m.privmsgs_subject NOT LIKE \'Re: %\' ');
    $SQL->ORDER_BY('m.privmsgs_date');
    $SQL->GROUP_BY('m.privmsgs_from_userid, m.privmsgs_to_userid, m.privmsgs_date');
    $page = 0;
    $page_size = 100;
    $phpbb_messages_count_imported = 0;
    $phpbb_missing_users = 0;
    do {
        // Split by page to optimize process
        // It gives to save the memory rather than if we get all replies by one query without LIMIT clause
        // Get the messages from phpbb database
        $SQL->LIMIT($page * $page_size . ', ' . $page_size);
        $phpbb_messages = $phpbb_DB->get_results($SQL->get());
        foreach ($phpbb_messages as $message) {
            if (!isset($users_IDs[(string) $message->privmsgs_from_userid])) {
                // The message has the incorrect user's ID by some reason
                /*if( !phpbb_import_invalid_user( $message->privmsgs_from_userid, $users_IDs ) )
                		{	// We cannot create invalid user
                			phpbb_log( sprintf( '<br />'.T_('Skipped message: %s. Incorrect user ID: %s. <b>Content:</b> %s'), $message->privmsgs_id, $message->privmsgs_from_userid, substr( $message->privmsgs_subject, 0, 250 ).' ...' ), 'error' );
                			continue;
                		}*/
                $phpbb_missing_users++;
                //phpbb_log( sprintf( '<br />'.T_('Skipped message: %s. Incorrect sender user ID: %s. <b>Content:</b> %s'), $message->privmsgs_id, $message->privmsgs_from_userid, substr( $message->privmsgs_subject, 0, 250 ).' ...' ), 'error', ' ' );
                continue;
            }
            if (!isset($users_IDs[(string) $message->privmsgs_to_userid])) {
                // The message has the incorrect user's ID by some reason
                $phpbb_missing_users++;
                //phpbb_log( sprintf( '<br />'.T_('Skipped message: %s. Incorrect reciever user ID: %s. <b>Content:</b> %s'), $message->privmsgs_id, $message->privmsgs_to_userid, substr( $message->privmsgs_subject, 0, 250 ).' ...' ), 'error', ' ' );
                continue;
            }
            mysql_query('INSERT INTO ' . $tableprefix . 'messaging__thread ( thrd_title, thrd_datemodified )
					VALUES ( ' . $DB->quote($message->privmsgs_subject) . ', ' . $DB->quote(date('Y-m-d H:i:s', $message->privmsgs_date)) . ' )', $DB->dbhandle);
            $thread_ID = mysql_insert_id($DB->dbhandle);
            // Import all messages from this thread
            $count_messages = phpbb_import_messages_texts($thread_ID, $message);
            $phpbb_messages_count_imported += $count_messages;
            if ($phpbb_messages_count_imported % 1000 == 0) {
                // Display the processing dots after 1000 topics
                phpbb_log(' .', 'message', '');
            }
        }
        $page++;
    } while (count($phpbb_messages) > 0);
    $DB->commit();
    phpbb_set_var('messages_count_imported', $phpbb_messages_count_imported);
    phpbb_set_var('messages_count_missing_users', $phpbb_missing_users);
}
Esempio n. 19
0
/**
 * Block request by IP address
 */
function antispam_block_by_ip()
{
    global $DB;
    // Detect request IP adresses
    $request_ip_list = get_ip_list();
    if (empty($request_ip_list)) {
        // Could not get any IP address, so can't check anything
        return;
    }
    $condition = '';
    foreach ($request_ip_list as $ip_address) {
        // create condition for each detected IP address
        $numeric_ip_address = ip2int($ip_address);
        $condition .= ' OR ( aipr_IPv4start <= ' . $DB->quote($numeric_ip_address) . ' AND aipr_IPv4end >= ' . $DB->quote($numeric_ip_address) . ' )';
    }
    $condition = '( ' . substr($condition, 4) . ' )';
    $SQL = new SQL();
    $SQL->SELECT('aipr_ID');
    $SQL->FROM('T_antispam__iprange');
    $SQL->WHERE($condition);
    $SQL->WHERE_and('aipr_status = \'blocked\'');
    $SQL->LIMIT(1);
    $ip_range_ID = $DB->get_var($SQL->get());
    if (!is_null($ip_range_ID)) {
        // The request from this IP address must be blocked
        $DB->query('UPDATE T_antispam__iprange
			SET aipr_block_count = aipr_block_count + 1
			WHERE aipr_ID = ' . $DB->quote($ip_range_ID));
        $debug_message = sprintf('A request with ( %s ) ip addresses was blocked because of a blocked IP range ID#%s.', implode(', ', $request_ip_list), $ip_range_ID);
        exit_blocked_request('IP', $debug_message);
        // WILL exit();
    }
}