Seditio Source
Root |
./othercms/ips_4.3.4/applications/convert/sources/Software/Core/Mybb.php
<?php

/**
 * @brief        Converter MyBB Class
 * @author        <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright    (c) Invision Power Services, Inc.
 * @package        Invision Community
 * @subpackage    Converter
 * @since        21 Jan 2015
 */

namespace IPS\convert\Software\Core;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
   
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
    exit;
}

class
_Mybb extends \IPS\convert\Software
{
   
/**
     * Software Name
     *
     * @return    string
     */
   
public static function softwareName()
    {
       
/* Child classes must override this method */
       
return "MyBB 1.8.x";
    }
   
   
/**
     * Software Key
     *
     * @return    string
     */
   
public static function softwareKey()
    {
       
/* Child classes must override this method */
       
return "mybb";
    }
   
   
/**
     * Content we can convert from this software.
     *
     * @return    array
     */
   
public static function canConvert()
    {
        return array(
           
'convertBanfilters'            => array(
               
'table'                            => 'banfilters',
               
'where'                            => NULL
           
),
           
'convertEmoticons'                => array(
               
'table'                            => 'smilies',
               
'where'                            => NULL,
            ),
           
'convertWarnActions'            => array(
               
'table'                            => 'warninglevels',
               
'where'                            => NULL
           
),
           
'convertWarnReasons'            => array(
               
'table'                            => 'warningtypes',
               
'where'                            => NULL
           
),
           
'convertProfileFields'        => array(
               
'table'                            => 'profilefields',
               
'where'                            => NULL
           
),
           
'convertGroups'                => array(
               
'table'                            => 'usergroups',
               
'where'                            => NULL
           
),
           
'convertMembers'                => array(
               
'table'                            => 'users', # note convert ignored users during this step, rather than individually
               
'where'                            => NULL
           
),
           
'convertAnnouncements'            => array(
               
'table'                            => 'announcements',
               
'where'                            => NULL
           
),
           
'convertRanks'                    => array(
               
'table'                            => 'usertitles',
               
'where'                            => NULL
           
),
           
'convertPrivateMessages'        => array(
               
'table'                            => 'privatemessages',
               
'where'                            => NULL
           
),
           
'convertPrivateMessageReplies'    => array(
               
'table'                            => 'privatemessages',
               
'where'                            => NULL,
            ),
           
'convertProfanityFilters'        => array(
               
'table'                            => 'badwords',
               
'where'                            => NULL
           
),
           
'convertQuestionAndAnswers'    => array(
               
'table'                            => 'questions',
               
'where'                            => NULL
           
)
        );
    }
   
   
/**
     * Can we convert passwords from this software.
     *
     * @return     boolean
     */
   
public static function loginEnabled()
    {
        return
TRUE;
    }

   
/**
     * List of conversion methods that require additional information
     *
     * @return    array
     */
   
public static function checkConf()
    {
        return array(
           
'convertEmoticons',
           
'convertProfileFields',
           
'convertGroups',
           
'convertMembers'
       
);
    }
   
   
/**
     * Get More Information
     *
     * @param    string    $method    Conversion method
     * @return    array
     */
   
public function getMoreInfo( $method )
    {
       
$return = array();
        switch(
$method )
        {
            case
'convertEmoticons':
                \
IPS\Member::loggedIn()->language()->words['emoticon_path'] = \IPS\Member::loggedIn()->language()->addToStack( 'source_path', FALSE, array( 'sprintf' => array( 'MyBB' ) ) );
               
$return['convertEmoticons']['emoticon_path'] = array(
                   
'field_class'        => 'IPS\\Helpers\\Form\\Text',
                   
'field_default'        => NULL,
                   
'field_required'    => TRUE,
                   
'field_extra'        => array(),
                   
'field_hint'        => NULL,
                   
'field_validation'    => function( $value ) { if ( !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
                );
               
$return['convertEmoticons']['keep_existing_emoticons']    = array(
                   
'field_class'        => 'IPS\\Helpers\\Form\\Checkbox',
                   
'field_default'        => TRUE,
                   
'field_required'    => FALSE,
                   
'field_extra'        => array(),
                   
'field_hint'        => NULL,
                );
                break;
               
            case
'convertProfileFields':
               
$return['convertProfileFields'] = array();
               
               
$options = array();
               
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack( 'none' );
                foreach( new \
IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_pfields_data' ), 'IPS\core\ProfileFields\Field' ) AS $field )
                {
                   
$options[$field->_id] = $field->_title;
                }
               
                foreach(
$this->db->select( '*', 'profilefields' ) AS $field )
                {
                    \
IPS\Member::loggedIn()->language()->words["map_pfield_{$field['fid']}"]        = $field['name'];
                    \
IPS\Member::loggedIn()->language()->words["map_pfield_{$field['fid']}_desc"]    = \IPS\Member::loggedIn()->language()->addToStack( 'map_pfield_desc' );
                   
                   
$return['convertProfileFields']["map_pfield_{$field['fid']}"] = array(
                       
'field_class'        => 'IPS\\Helpers\\Form\\Select',
                       
'field_default'        => NULL,
                       
'field_required'    => FALSE,
                       
'field_extra'        => array( 'options' => $options ),
                       
'field_hint'        => NULL,
                    );
                }
                break;
           
            case
'convertGroups':
               
$return['convertGroups'] = array();
               
               
$options = array();
               
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack( 'none' );
                foreach( new \
IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_groups' ), 'IPS\Member\Group' ) AS $group )
                {
                   
$options[$group->g_id] = $group->name;
                }
               
                foreach(
$this->db->select( '*', 'usergroups' ) AS $group )
                {
                    \
IPS\Member::loggedIn()->language()->words["map_group_{$group['gid']}"]            = $group['title'];
                    \
IPS\Member::loggedIn()->language()->words["map_group_{$group['gid']}_desc"]    = \IPS\Member::loggedIn()->language()->addToStack( 'map_group_desc' );
                   
                   
$return['convertGroups']["map_group_{$group['gid']}"] = array(
                       
'field_class'        => 'IPS\\Helpers\\Form\\Select',
                       
'field_default'        => NULL,
                       
'field_required'    => FALSE,
                       
'field_extra'        => array( 'options' => $options ),
                       
'field_hint'        => NULL
                   
);
                }
               
                \
IPS\Member::loggedIn()->language()->words['icon_path'] = \IPS\Member::loggedIn()->language()->addToStack( 'source_path', FALSE, array( 'sprintf' => array( 'MyBB' ) ) );
               
$return['convertGroups']['icon_path'] = array(
                   
'field_class'            => "IPS\\Helpers\\Form\\Text",
                   
'field_default'            => NULL,
                   
'field_required'        => FALSE,
                   
'field_extra'            => array(),
                   
'field_hint'            => \IPS\Member::loggedIn()->language()->addToStack('convert_groupicon_hint'),
                   
'field_validation'        => function( $value ) { if ( !empty( $value ) AND !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
                );
                break;
           
            case
'convertMembers':
               
$return['convertMembers'] = array();

               
/* Find out where the photos live */
               
\IPS\Member::loggedIn()->language()->words['photo_location']        = \IPS\Member::loggedIn()->language()->addToStack( 'source_path', FALSE, array( 'sprintf' => array( 'MyBB' ) ) );
                \
IPS\Member::loggedIn()->language()->words['photo_location_desc']    = '';
               
$return['convertMembers']['photo_location'] = array(
                   
'field_class'            => 'IPS\\Helpers\\Form\\Text',
                   
'field_default'            => NULL,
                   
'field_required'        => TRUE,
                   
'field_extra'            => array(),
                   
'field_hint'            => NULL,
                   
'field_validation'    => function( $value ) { if ( !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
                );

                foreach( array(
'website', 'icq', 'aim', 'yahoo', 'skype', 'google' ) AS $field )
                {
                    \
IPS\Member::loggedIn()->language()->words["field_{$field}"]        = \IPS\Member::loggedIn()->language()->addToStack( 'pseudo_field', FALSE, array( 'sprintf' => $field ) );
                    \
IPS\Member::loggedIn()->language()->words["field_{$field}_desc"]    = \IPS\Member::loggedIn()->language()->addToStack( 'pseudo_field_desc' );
                   
$return['convertMembers']["field_{$field}"] = array(
                       
'field_class'            => 'IPS\\Helpers\\Form\\Radio',
                       
'field_default'            => 'no_convert',
                       
'field_required'        => TRUE,
                       
'field_extra'            => array(
                           
'options'                => array(
                               
'no_convert'            => \IPS\Member::loggedIn()->language()->addToStack( 'no_convert' ),
                               
'create_field'            => \IPS\Member::loggedIn()->language()->addToStack( 'create_field' ),
                            ),
                           
'userSuppliedInput'        => 'create_field'
                       
),
                       
'field_hint'            => NULL
                   
);
                }
                break;
        }
       
        return ( isset(
$return[ $method ] ) ) ? $return[ $method ] : array();
    }
   
   
/**
     * Finish - Adds everything it needs to the queues and clears data store
     *
     * @return    array        Messages to display
     */
   
public function finish()
    {
       
/* Search Index Rebuild */
       
\IPS\Content\Search\Index::i()->rebuild();
       
       
/* Clear Cache and Store */
       
\IPS\Data\Store::i()->clearAll();
        \
IPS\Data\Cache::i()->clearAll();
       
       
/* Non-Content Rebuilds */
       
\IPS\Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_announcements', 'extension' => 'core_Announcement' ), 2, array( 'app', 'link', 'extension' ) );
        \
IPS\Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_message_posts', 'extension' => 'core_Messaging' ), 2, array( 'app', 'link', 'extension' ) );
        \
IPS\Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_members', 'extension' => 'core_Signatures' ), 2, array( 'app', 'link', 'extension' ) );
       
       
/* Content Counts */
       
\IPS\Task::queue( 'core', 'RecountMemberContent', array( 'app' => $this->app->app_id ), 4, array( 'app' ) );

       
/* First Post Data */
       
\IPS\Task::queue( 'convert', 'RebuildConversationFirstIds', array( 'app' => $this->app->app_id ), 2, array( 'app' ) );

       
/* Attachments */
       
\IPS\Task::queue( 'core', 'RebuildAttachmentThumbnails', array( 'app' => $this->app->app_id ), 1, array( 'app' ) );
       
        return array(
"f_search_index_rebuild", "f_clear_caches", "f_rebuild_pms", "f_signatures_rebuild", "f_announce_rebuild" );
    }

   
/**
     * Fix post data
     *
     * @param     string        raw post data
     * @return     string        parsed post data
     */
   
public static function fixPostData( $post )
    {
       
/* Replace align tags with left/right/center/justify */
       
$post = preg_replace( '/\[align=(justify|left|right)\](.+?)\[\/align\]/i', '[$1]$2[/$1]', $post );

       
/* remove justify, since we don't support it */
       
$post = str_replace( array( '[justify]', '[/justify]' ), '', $post );

        return
$post;
    }

   
/**
     * Convert announcements
     *
     * @return    void
     */
   
public function convertAnnouncements()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'aid' );
       
        foreach (
$this->fetch( 'announcements', 'aid' ) AS $row )
        {
           
$libraryClass->convertAnnouncement( array(
               
'announce_id'            => $row['aid'],
               
'announce_title'        => $row['subject'],
               
'announce_content'        => $row['message'],
               
'announce_member_id'    => $row['uid'],
               
'announce_start'        => $row['startdate'],
               
'announce_end'            => $row['enddate'],
               
'announce_active'        => ( $row['enddate'] == 0 OR $row['enddate'] > time() ) ? 1 : 0,
            ) );
           
           
$libraryClass->setLastKeyValue( $row['aid'] );
        }
    }
   
   
/**
     * Convert ban filters
     *
     * @return    void
     */
   
public function convertBanfilters()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'fid' );
       
        foreach(
$this->fetch( 'banfilters', 'fid' ) AS $row )
        {
            switch(
$row['type'] )
            {
                case
1:
                   
$type = 'ip';
                    break;
               
                case
2:
                   
$type = 'name';
                    break;
               
                case
3:
                   
$type = 'email';
                    break;
            }
           
           
$libraryClass->convertBanfilter( array(
               
'ban_id'            => $row['fid'],
               
'ban_type'            => $type,
               
'ban_content'        => $row['filter'],
               
'ban_date'            => $row['dateline']
            ) );
           
           
$libraryClass->setLastKeyValue( $row['fid'] );
        }
    }
   
   
/**
     * Convert emoticons
     *
     * @return    void
     */
   
public function convertEmoticons()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'sid' );
       
        foreach(
$this->fetch( 'smilies', 'sid' ) AS $row )
        {
           
$set = array(
               
'set'        => md5( 'Converted' ),
               
'title'        => 'Converted',
               
'position'    => 1,
            );
           
           
$filepath    = explode( '/', $row['image'] );
           
$filename    = array_pop( $filepath );
           
$path        = rtrim( $this->app->_session['more_info']['convertEmoticons']['emoticon_path'], '/' ) . '/' . implode( '/', $filepath );
           
           
$typed        = explode( "\n", $row['find'] );
           
$typed        = array_shift( $typed );
           
           
$info = array(
               
'id'            => $row['sid'],
               
'typed'            => $typed,
               
'filename'        => $filename,
               
'clickable'        => $row['showclickable'],
               
'emo_position'    => $row['disporder']
            );
           
           
$libraryClass->convertEmoticon( $info, $set, $this->app->_session['more_info']['convertEmoticons']['keep_existing_emoticons'], $path );
           
           
$libraryClass->setLastKeyValue( $row['sid'] );
        }
    }
   
   
/**
     * Convert warn actions
     *
     * @return    void
     */
   
public function convertWarnActions()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'lid' );
       
        foreach(
$this->fetch( 'warninglevels', 'lid' ) AS $row )
        {
           
$action = \unserialize( $row['action'] );
           
           
$mq                = 0;
           
$mq_unit        = 'h';
           
$rpa            = 0;
           
$rpa_unit        = 'h';
           
$suspend        = 0;
           
$suspend_unit    = 'h';
            switch(
$action['type'] )
            {
               
// Banned
               
case 1:
                    if (
$action['length'] >= 86400 )
                    {
                       
$suspend_unit    = 'd';
                       
$suspend        = floor( $action['length'] / 86400 );
                    }
                    else
                    {
                       
$suspend_unit    = 'h';
                       
$suspend        = floor( $action['length'] / 3600 );
                    }
                    break;
               
               
// Restrict Posting
               
case 2:
                    if (
$action['length'] >= 86400 )
                    {
                       
$rpa_unit        = 'd';
                       
$rpa            = floor( $action['length'] / 86400 );
                    }
                    else
                    {
                       
$rpa_unit        = 'h';
                       
$rpa            = floor( $action['length'] / 3600 );
                    }
                    break;
               
               
// Moderate Posting
               
case 3:
                    if (
$action['length'] >= 86400 )
                    {
                       
$mq_unit        = 'd';
                       
$mq                = floor( $action['length'] / 86400 );
                    }
                    else
                    {
                       
$mq_unit        = 'h';
                       
$mq                = floor( $action['length'] / 3600 );
                    }
                    break;
            }
           
           
$libraryClass->convertWarnAction( array(
               
'wa_id'                => $row['lid'],
               
'wa_points'            => $row['percentage'],
               
'wa_mq'                => $mq,
               
'wa_mq_unit'        => $mq_unit,
               
'wa_rpa'            => $rpa,
               
'wa_rpa_unit'        => $rpa_unit,
               
'wa_suspend'        => $suspend,
               
'wa_suspend_unit'    => $suspend_unit,
            ) );
           
           
$libraryClass->setLastKeyValue( $row['lid'] );
        }
    }
   
   
/**
     * Convert warn reasons
     *
     * @return    void
     */
   
public function convertWarnReasons()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'tid' );
       
        foreach(
$this->fetch( 'warningtypes', 'tid' ) AS $row )
        {
           
$libraryClass->convertWarnReason( array(
               
'wr_id'            => $row['tid'],
               
'wr_name'        => $row['title'],
               
'wr_points'        => $row['points'],
               
'wr_remove'        => floor( $row['expirationtime'] / 3600 ),
            ) );
           
           
$libraryClass->setLastKeyValue( $row['tid'] );
        }
    }
   
   
/**
     * Convert profile fields
     *
     * @return    void
     */
   
public function convertProfileFields()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'fid' );
       
        foreach(
$this->fetch( 'profilefields', 'fid' ) AS $row )
        {
           
/* MyBB stores the type and the options in the same column. */
           
$typeAndOptions    = explode( "\n", $row['type'] );
           
$theirType        = array_shift( $typeAndOptions );
           
$ourType        = $this->_fieldMap( $theirType );
           
$options        = $typeAndOptions;
           
           
$info = array(
               
'pf_id'                => $row['fid'],
               
'pf_type'            => $ourType,
               
'pf_name'            => $row['name'],
               
'pf_desc'            => $row['description'],
               
'pf_content'        => $options,
               
'pf_not_null'        => $row['required'],
               
'pf_member_hide'    => $row['profile'],
               
'pf_max_input'        => $row['maxlength'],
               
'pf_position'        => $row['disporder'],
               
'pf_show_on_reg'    => $row['registration'],
               
'pf_input_format'    => '/' . $row['regex'] . '/i',
               
'pf_admin_only'        => ( $row['editableby'] == -1 ) ? 0 : 1, # MyBB allows you to define which groups can edit, so if this value is anything other than -1, assume it's admin only
               
'pf_multiple'        => ( $theirType == 'multiselect' ) ? 1 : 0
           
);
           
           
$merge = $this->app->_session['more_info']['convertProfileFields']["map_pfield_{$row['fid']}"] != 'none' ? $this->app->_session['more_info']['convertProfileFields']["map_pfield_{$row['fid']}"] : NULL;
           
           
$libraryClass->convertProfileField( $info, $merge );
           
           
$libraryClass->setLastKeyValue( $row['fid'] );
        }
    }
   
   
/**
     * Maps a MyBB Profile Field type to IPS
     *
     * @param    string    MyBB Type
     * @return    string    IPS Type
     */
   
protected function _fieldMap( $type )
    {
        switch(
$type )
        {
            case
'text':
                return
'Text';
                break;
           
            case
'textarea':
                return
"TextArea";
                break;
           
            case
'select':
            case
'multiselect':
                return
'Select';
                break;
           
            case
'checkbox':
                return
'CheckboxSet';
                break;
           
            case
'radio':
                return
'Radio';
                break;
        }
    }
   
   
/**
     * Convert groups
     *
     * @return    void
     */
   
public function convertGroups()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'gid' );
       
        foreach(
$this->fetch( 'usergroups', 'gid' ) AS $row )
        {
           
/* Are we trying to fetch icons? */
           
$icon_path = $this->app->_session['more_info']['convertGroups']['icon_path'];
           
           
/* Work out promotions */
           
$promotion_unit    = 0;
           
$promotion_data    = NULL;
            try
            {
               
/* We only support one type of promotion, so just fetch the first one we can find */
               
$promotion = $this->db->select( '*', 'promotions', array( "originalusergroup=? AND usergrouptype=? AND ( requirements=? OR requirements=? )", $row['gid'], 'primary', 'postcount', 'timeregistered' ) )->first();
               
                switch(
$promotion['requirements'] )
                {
                    case
'postcount':
                        if ( !
in_array( $promotion['posttype'], array( '>', '>=', '=' ) ) )
                        {
                           
/* Bubble up */
                           
throw new \UnderflowException;
                        }
                       
$promotion_unit = 0;
                       
$promotion_data = array( $promotion['newusergroup'], $promotion['posts'] );
                        break;
                   
                    case
'timeregistered':
                        if ( !
in_array( $promotion['registeredtype'], array( '>', '>=', '=' ) ) )
                        {
                            throw new \
UnderflowException;
                        }
                       
$promotion_unit = 0;
                       
$promotion_data = array( $promotion['newusergroup'], $promotion['registered'] );
                        break;
                }
            }
            catch( \
UnderflowException $e ) {}
           
           
/* Username Styles */
           
$style = explode( '{username}', $row['namestyle'] );
           
$prefix = isset( $style[0] ) ? $style[0] : '';
           
$suffix = isset( $style[1] ) ? $style[1] : '';
           
           
$info = array(
               
'g_id'                    => $row['gid'],
               
'g_name'                => $row['title'],
               
'g_icon'                => ( $icon_path AND $row['image'] ) ? $row['image'] : NULL,
               
'g_promotion'            => $promotion_data ?: NULL,
               
'g_bitoptions'            => array(
                   
'gbw_promote_unit_type'    => $promotion_unit,
                ),
               
'g_view_board'            => $row['canview'],
               
'g_mem_info'            => $row['canviewprofiles'],
               
'g_use_search'            => $row['cansearch'],
               
'g_edit_profile'        => $row['canusercp'],
               
'g_edit_posts'            => $row['caneditposts'],
               
'g_use_pm'                => $row['cansendpms'],
               
'g_pm_flood_mins'        => $row['emailfloodtime'],
               
'g_post_polls'            => $row['canpostpolls'],
               
'g_vote_polls'            => $row['canvotepolls'],
               
'g_delete_own_posts'    => $row['candeleteposts'],
               
'g_is_supmod'            => $row['issupermod'],
               
'g_access_cp'            => $row['cancp'],
               
'g_access_offline'        => $row['canviewboardclosed'],
               
'g_max_messages'        => $row['pmquota'],
               
'g_attach_max'            => ( $row['attachquota'] == 0 ) ? -1 : $row['attachquota'],
               
'prefix'                => $prefix,
               
'suffix'                => $suffix,
               
'g_max_mass_pm'            => $row['maxpmrecipients'],
               
'g_rep_max_positive'    => $row['maxreputationsday'],
               
'g_rep_max_negative'    => $row['maxreputationsday'],
            );
           
           
$merge = $this->app->_session['more_info']['convertGroups']["map_group_{$row['gid']}"] != 'none' ? $this->app->_session['more_info']['convertGroups']["map_group_{$row['gid']}"] : NULL;
           
           
$libraryClass->convertGroup( $info, $merge, ( $icon_path ) ? rtrim( $icon_path, '/' ) . '/' . $row['image'] : NULL );
           
           
$libraryClass->setLastKeyValue( $row['gid'] );
        }

       
/* Now check for group promotions */
       
if( count( $libraryClass->groupPromotions ) )
        {
            foreach(
$libraryClass->groupPromotions as $groupPromotion )
            {
               
$libraryClass->convertGroupPromotion( $groupPromotion );
            }
        }
    }
   
   
/**
     * Convert members
     *
     * @return    void
     */
   
public function convertMembers()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'uid' );
       
        foreach(
$this->fetch( 'users', 'uid' ) AS $row )
        {
           
/* Last warning */
           
$last_warn = 0;
            try
            {
               
$last_warn = $this->db->select( 'dateline', 'warnings', array( "uid=?", $row['uid'] ), "dateline DESC" )->first();
            }
            catch( \
UnderflowException $e ) {}
           
           
/* Restrict posting */
           
$restrict_post = 0;
            if (
$row['suspendposting'] )
            {
                if (
$row['suspensiontime'] > 0 )
                {
                   
$restrict_post = $row['suspensiontime'];
                }
                else
                {
                   
$restrict_post = -1;
                }
            }
           
           
/* Birthday */
           
$bday_day = $bday_month = $bday_year = NULL;
           
$birthday = explode( '-', $row['birthday'] );
           
            if ( isset(
$birthday[0] ) )
            {
               
$bday_day = $birthday[0];
            }
           
            if ( isset(
$birthday[1] ) )
            {
               
$bday_month = $birthday[1];
            }
           
            if ( isset(
$birthday[2] ) )
            {
               
$bday_year = $birthday[2];
            }
           
           
/* Moderate Posts */
           
$mod_posts = 0;
            if (
$row['moderateposts'] )
            {
                if (
$row['moderationtime'] > 0 )
                {
                   
$mod_posts = $row['moderationtime'];
                }
                else
                {
                   
$mod_posts = -1;
                }
            }
           
           
/* Subscription */
           
switch( $row['subscriptionmethod'] )
            {
                case
0:
                   
$auto_track = array( 'content' => 0, 'comments' => 0, 'method' => 'none' );
                    break;
               
                case
1:
                   
$auto_track = array( 'content' => 1, 'comments' => 1, 'method' => 'none' );
                    break;
               
                case
2:
                case
3:
                   
$auto_track = array( 'content' => 1, 'comments' => 1, 'method' => 'immediate' );
                    break;
            }
           
           
/* Banned */
           
$temp_ban = 0;
            try
            {
               
$temp_ban = $this->db->select( 'lifted', 'banned', array( "uid=?", $row['uid'] ) )->first();
               
                if (
$temp_ban == 0 )
                {
                   
$temp_ban = -1;
                }
            }
            catch( \
UnderflowException $e ) {}
           
           
$info = array(
               
'member_id'                => $row['uid'],
               
'name'                    => $row['username'],
               
'email'                    => $row['email'],
               
'password'                => $row['password'],
               
'password_extra'        => $row['salt'],
               
'member_group_id'        => $row['usergroup'],
               
'joined'                => $row['regdate'],
               
'ip_address'            => $row['regip'],
               
'warn_level'            => $row['warningpoints'],
               
'warn_lastwarn'            => $last_warn,
               
'restrict_post'            => $restrict_post,
               
'bday_day'                => str_pad( $bday_day, 2, '0', STR_PAD_LEFT ),
               
'bday_month'            => str_pad( $bday_month, 2, '0', STR_PAD_LEFT ),
               
'bday_year'                => $bday_year ? intval( $bday_year ) : NULL,
               
'msg_count_new'            => $row['unreadpms'],
               
'msg_count_total'        => $row['totalpms'],
               
'msg_show_notification'    => $row['pmnotify'],
               
'last_visit'            => $row['lastvisit'],
               
'last_activity'            => $row['lastactive'],
               
'mod_posts'                => $mod_posts,
               
'auto_track'            => $auto_track,
               
'temp_ban'                => $temp_ban,
               
'mgroup_others'            => $row['additionalgroups'],
               
'members_bitoptions'    => array(
                   
'view_sigs'                => $row['showsigs'],
                ),
               
'members_bitoptions2'    => array(
                   
'show_pm_popup'            => $row['pmnotify'],
                ),
               
'pp_reputation_points'    => $row['reputation'],
               
'signature'                => $row['signature'],
               
'timezone'                => $row['timezone'],
               
'allow_admin_mails'        => $row['allownotices'],
               
'members_disable_pm'    => ( $row['receivepms'] ) ? 0 : 1,
               
'member_title'            => $row['usertitle'],
               
'member_posts'            => $row['postnum'],
               
'member_last_post'        => $row['lastpost'],
            );
           
           
$pfields = array();
            foreach(
$this->db->select( '*', 'userfields', array( "ufid=?", $row['uid'] ) ) AS $key => $field )
            {
               
$key = str_replace( 'fid', '', $key );
               
$pfields[ $key ] = $field;
            }
           
            foreach( array(
'website', 'icq', 'aim', 'yahoo', 'skype', 'google' ) AS $pseudo )
            {
               
/* Are we retaining? */
               
if ( $this->app->_session['more_info']['convertMembers']["field_{$pseudo}"] == 'no_convert' )
                {
                   
/* No, skip */
                   
continue;
                }
               
                try
                {
                   
/* We don't actually need this, but we need to make sure the field was created */
                   
$fieldId = $this->app->getLink( $pseudo, 'core_pfields_data' );
                }
                catch( \
OutOfRangeException $e )
                {
                   
$libraryClass->convertProfileField( array(
                       
'pf_id'                => $pseudo,
                       
'pf_name'            => $this->app->_session['more_info']['convertMembers']["field_{$pseudo}"],
                       
'pf_desc'            => '',
                       
'pf_type'            => 'Text',
                       
'pf_content'        => '[]',
                       
'pf_member_hide'    => 0,
                       
'pf_max_input'        => 255,
                       
'pf_member_edit'    => 1,
                       
'pf_show_on_reg'    => 0,
                       
'pf_admin_only'        => 0,
                    ) );
                }
               
               
$pfields[$pseudo] = $row[$pseudo];
            }
           
           
/* Photo */
           
$filename = NULL;
           
$filepath = NULL;
            switch(
$row['avatartype'] )
            {
                case
'gravatar':
                   
$info['pp_gravatar']    = $row['email'];
                   
$info['pp_photo_type']    = 'gravatar';
                    break;
               
                case
'upload':
                   
$info['pp_photo_type'] = 'custom';
                   
                   
$avatar        = trim( '.', $row['avatar'] );
                   
$filepath    = explode( '/', $avatar );
                   
$filename    = array_pop( $filepath );
                   
$filepath    = rtrim( $this->app->_session['more_info']['convertMembers']['photo_location'], '/' ) . implode( '/', $filepath );
                    break;
            }
           
           
$libraryClass->convertMember( $info, $pfields, $filename, $filepath );
           
           
/* Followers */
           
foreach( explode( ',', $row['buddylist'] ) AS $buddy )
            {
               
$libraryClass->convertFollow( array(
                   
'follow_app'            => 'core',
                   
'follow_area'            => 'members',
                   
'follow_rel_id'            => $buddy,
                   
'follow_rel_id_type'    => 'core_members',
                   
'follow_member_id'        => $row['uid'],
                ) );
            }
           
           
/* Ignore List */
           
foreach( explode( ',', $row['ignorelist'] ) AS $ignore )
            {
               
$libraryClass->convertIgnoredUser( array(
                   
'ignore_id'            => $row['uid'] . '-' . $ignore,
                   
'ignore_owner_id'    => $row['uid'],
                   
'ignore_ignore_id'    => $ignore
               
) );
            }
           
           
/* Warnings */
           
foreach( $this->db->select( '*', 'warnings', array( "uid=? AND pid=?", $row['uid'], 0 ) ) AS $warning )
            {
               
$warnId = $libraryClass->convertWarnLog( array(
                   
'wl_id'                => $warning['wid'],
                   
'wl_member'            => $warning['uid'],
                   
'wl_moderator'        => $warning['issuedby'],
                   
'wl_date'            => $warning['dateline'],
                   
'wl_reason'            => $warning['tid'],
                   
'wl_points'            => $warning['points'],
                   
'wl_note_mods'        => $warning['notes'],
                   
'wl_expire_date'    => $warning['expires'],
                ) );

               
/* Add a member history record for this member */
               
$libraryClass->convertMemberHistory( array(
                       
'log_id'        => 'w' . $warning['wid'],
                       
'log_member'    => $warning['uid'],
                       
'log_by'        => $warning['issuedby'],
                       
'log_type'        => 'warning',
                       
'log_data'        => array( 'wid' => $warnId ),
                       
'log_date'        => $warning['dateline']
                    )
                );
            }
           
           
$libraryClass->setLastKeyValue( $row['uid'] );
        }
    }
   
   
/**
     * Convert ranks
     *
     * @return    void
     */
   
public function convertRanks()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'utid' );
       
        foreach(
$this->fetch( 'usertitles', 'utid' ) AS $row )
        {
           
$libraryClass->convertRank( array(
               
'id'            => $row['utid'],
               
'title'            => $row['title'],
               
'posts'            => $row['posts'],
               
'pips'            => $row['stars']
            ) );
           
           
$libraryClass->setLastKeyValue( $row['utid'] );
        }
    }
   
   
/**
     * Convert PMs
     *
     * @return    void
     */
   
public function convertPrivateMessages()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'pmid' );
       
        foreach(
$this->fetch( 'privatemessages', 'pmid' ) AS $row )
        {
           
/* My hands are kind of tied here... every individual message is stored separately, rather than grouped into conversations. In this instance, we'll bring over each individual message as it's own topic for archival purposes. */
           
$recipients = \unserialize( $row['recipients'] );
           
           
$topic = array(
               
'mt_id'                => $row['pmid'],
               
'mt_date'            => $row['dateline'],
               
'mt_title'            => $row['subject'],
               
'mt_starter_id'        => $row['uid'],
               
'mt_start_time'        => $row['dateline'],
               
'mt_last_post_time'    => $row['dateline'],
               
'mt_to_count'        => 1,
            );
           
           
$maps = array();
           
$maps[$row['uid']] = array(
               
'map_user_id'        => $row['uid'],
               
'map_read_time'        => $row['readtime'],
            );
           
           
$libraryClass->convertPrivateMessage( $topic, $maps );
           
           
$libraryClass->setLastKeyValue( $row['pmid'] );
        }
    }
   
   
/**
     * Convert PM replies
     *
     * @return    void
     */
   
public function convertPrivateMessageReplies()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'pmid' );
       
        foreach(
$this->fetch( 'privatemessages', 'pmid' ) AS $row )
        {
           
$libraryClass->convertPrivateMessageReply( array(
               
'msg_id'            => $row['pmid'],
               
'msg_topic_id'        => $row['pmid'],
               
'msg_date'            => $row['dateline'],
               
'msg_post'            => $row['message'],
               
'msg_author_id'        => $row['uid'],
               
'msg_ip_address'    => $row['ipaddress'],
            ) );
           
           
$libraryClass->setLastKeyValue( $row['pmid'] );
        }
    }

   
/**
     * Convert profanity filters
     *
     * @return    void
     */
   
public function convertProfanityFilters()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'bid' );
       
        foreach(
$this->fetch( 'badwords', 'bid' ) AS $row )
        {
           
$libraryClass->convertProfanityFilter( array(
               
'wid'        => $row['bid'],
               
'type'        => $row['badword'],
               
'swop'        => $row['replacement'],
            ) );
           
           
$libraryClass->setLastKeyValue( $row['bid'] );
        }
    }
   
   
/**
     * Convert questions and answers
     *
     * @return    void
     */
   
public function convertQuestionAndAnswers()
    {
       
$libraryClass = $this->getLibrary();
       
       
$libraryClass::setKey( 'qid' );
       
        foreach(
$this->fetch( 'questions', 'qid' ) AS $row )
        {
           
$answers = explode( "\n", $row['answer'] );
           
           
$libraryClass->convertQuestionAndAnswer( array(
               
'qa_id'            => $row['qid'],
               
'qa_question'    => $row['question'],
            ),
$answers );
        }
    }

   
/**
     * Check if we can redirect the legacy URLs from this software to the new locations
     *
     * @return    NULL|\IPS\Http\Url
     */
   
public function checkRedirects()
    {
       
/* If we can't access profiles, don't bother trying to redirect */
       
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members' ) ) )
        {
            return
NULL;
        }

       
$url = \IPS\Request::i()->url();

        if(
mb_strpos( $url->data[ \IPS\Http\Url::COMPONENT_PATH ], 'member.php' ) !== FALSE )
        {
            try
            {
               
$data = (string) $this->app->getLink( \IPS\Request::i()-uid, array( 'members', 'core_members' ) );
                return \
IPS\Member::load( $data )->url();
            }
            catch( \
Exception $e )
            {
                return
NULL;
            }
        }

        return
NULL;
    }

   
/**
     * Process a login
     *
     * @param    \IPS\Member        $member            The member
     * @param    string            $password        Password from form
     * @return    bool
     */
   
public function login( $member, $password )
    {
        if ( \
IPS\Login::compareHashes( $member->conv_password, md5( md5( $member->misc ) . md5( $password ) ) ) )
        {
            return
TRUE;
        }
        else
        {
            return
FALSE;
        }
    }
}