Seditio Source
Root |
./othercms/ips_4.3.4/applications/convert/sources/Library/Nexus.php
<?php

/**
 * @brief        Converter Library Nexus 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        6 May 2016
 */

namespace IPS\convert\Library;

/* 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
_Nexus extends \IPS\convert\Library
{
   
/**
     * @brief    Application
     */
   
public $app = 'nexus';

   
/**
     * Returns an array of items that we can convert, including the amount of rows stored in the Community Suite as well as the recommend value of rows to convert per cycle
     *
     * @return    array
     */
   
public function menuRows()
    {
       
$return        = array();
       
$classname    = get_class( $this->software );

        foreach(
$this->getConvertableItems() as $k => $v )
        {
            switch(
$k )
            {
                case
'convertNexusCustomerFields':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_customer_fields',
                       
'step_method'    => 'convertNexusCustomerFields',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_fields' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array(),
                       
'link_type'        => 'nexus_customer_fields'
                   
);
                    break;
               
                case
'convertNexusCustomers':
                   
$dependencies = array();
                    if (
in_array( 'convertNexusCustomerFields', $this->getConvertableItems() ) )
                    {
                       
$dependencies[] = 'convertNexusCustomerFields';
                    }
                   
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_customers',
                       
'step_method'    => 'convertNexusCustomers',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customers' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => $dependencies,
                       
'link_type'        => 'nexus_customers',
                    );
                    break;
               
                case
'convertNexusCustomerAddresses':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_customer_addresses',
                       
'step_method'    => 'convertNexusCustomerAddresses',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => array( 'convertNexusCustomers' ),
                       
'link_type'        => 'nexus_customer_addresses',
                    );
                    break;
               
                case
'convertNexusCustomerHistory':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_customer_history',
                       
'step_method'    => 'convertNexusCustomerHistory',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'core_member_history', array( 'log_app=?', 'nexus' ) )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => array( 'convertNexusCustomers' ),
                       
'link_type'        => 'nexus_customer_history',
                    );
                    break;
               
                case
'convertNexusAlternateContacts':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_alternate_contacts',
                       
'step_method'    => 'convertNexusAlternateContacts',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_alternate_contacts' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => array( 'convertNexusCustomers' ),
                       
'link_type'        => 'nexus_alternate_contacts'
                   
);
                    break;
               
                case
'convertNexusNotes':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_notes',
                       
'step_method'    => 'convertNexusNotes',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_notes' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 1500,
                       
'dependencies'    => array( 'convertNexusCustomers' ),
                       
'linK_type'        => 'nexus_notes'
                   
);
                    break;
               
                case
'convertNexusPackageGroups':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_package_groups',
                       
'step_method'    => 'convertNexusPackageGroups',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_package_groups' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array(),
                       
'link_type'        => 'nexus_package_groups'
                   
);
                    break;
               
                case
'convertNexusPackageFields':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_package_fields',
                       
'step_method'    => 'convertNexusPackageFields',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_package_fields' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array(),
                       
'link_type'        => 'nexus_package_fields'
                   
);
                    break;
               
                case
'convertNexusPackages':
                   
$dependencies = array();
                    foreach( array(
'convertNexusPackageGroups', 'convertNexusPackageFields' ) as $dependency )
                    {
                       
$canConvert = $this->getConvertableItems();
                        if ( isset(
$canConvert[ $dependency ] ) )
                        {
                           
$dependencies[] = $dependency;
                        }
                    }
                   
                   
$return[ $k ] = array(
                       
'step_title'        => 'convert_nexus_packages',
                       
'step_method'        => 'convertNexusPackages',
                       
'ips_rows'            => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages' )->first(),
                       
'source_rows'        => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'            => 100,
                       
'dependencies'        => $dependencies,
                       
'link_type'            => 'nexus_packages',
                       
'requires_rebuild'    => TRUE
                   
);
                    break;
               
                case
'convertNexusReviews':
                   
$return[ $k ] = array(
                       
'step_title'        => 'convert_nexus_reviews',
                       
'step_method'        => 'convertNexusReviews',
                       
'ips_rows'            => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_reviews' )->first(),
                       
'source_rows'        => $this->software->sourceRows( $v['table'], $v['where'] ),
                       
'per_cycle'            => 1500,
                       
'dependencies'        => array( 'convertNexusPackages' ),
                       
'link_type'            => 'nexus_reviews',
                       
'requires_rebuild'    => TRUE
                   
);
                    break;
               
                case
'convertNexusCoupons':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_coupons',
                       
'step_method'    => 'convertNexusCoupons',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_coupons' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => array( 'convertNexusPackages' ),
                       
'link_type'        => 'nexus_coupons'
                   
);
                    break;
               
                case
'convertNexusInvoices':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_invoices',
                       
'step_method'    => 'convertNexusInvoices',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 1000,
                       
'dependencies'    => array( 'convertNexusCustomers', 'convertNexusPackages' ),
                       
'link_type'        => 'nexus_invoices',
                    );
                    break;
               
                case
'convertNexusTransactions':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_transactions',
                       
'step_method'    => 'convertNexusTransactions',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 1000,
                       
'dependencies'    => array( 'convertNexusCustomers', 'convertNexusInvoices' ),
                       
'link_type'        => 'nexus_transactions',
                    );
                    break;
               
                case
'convertNexusPurchases':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_purchases',
                       
'step_method'    => 'convertNexusPurchases',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 1000,
                       
'dependencies'    => array( 'convertNexusCustomers', 'convertNexusPackages', 'convertNexusInvoices' ),
                       
'link_type'        => 'nexus_purchases'
                   
);
                    break;
               
                case
'convertNexusFraudRules':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_fraud_rules',
                       
'step_method'    => 'convertNexusFraudRules',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_fraud_rules' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 2000,
                       
'dependencies'    => array(),
                       
'link_type'        => 'nexus_fraud_rules',
                    );
                    break;
               
                case
'convertNexusSupportDepartments':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_support_departments',
                       
'step_method'    => 'convertNexusSupportDepartments',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_departments' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array( 'convertNexusPackages' ),
                    );
                    break;
               
                case
'convertNexusSupportFields':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_support_fields',
                       
'step_method'    => 'convertNexusSupportFields',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_fields' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array( 'convertNexusSupportDepartments' ),
                       
'link_type'        => 'nexus_support_fields',
                    );
                    break;
               
                case
'convertNexusSupportStatuses':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_support_statuses',
                       
'step_method'    => 'convertNexusSupportStatuses',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_statuses' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array(),
                       
'link_type'        => 'nexus_support_statuses',
                    );
                    break;
               
                case
'convertNexusSupportSeverities':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_support_severities',
                       
'step_method'    => 'convertNexusSupportSeverities',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_severities' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array( 'convertNexusSupportDepartments' ),
                       
'link_type'        => 'nexus_support_severities'
                   
);
                    break;
               
                case
'convertNexusSupportStockActions':
                   
$return[ $k ] = array(
                       
'step_title'    => 'convert_nexus_support_stock_actions',
                       
'step_method'    => 'convertNexusSupportStockActions',
                       
'ips_rows'        => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_stock_actions' )->first(),
                       
'source_rows'    => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'        => 100,
                       
'dependencies'    => array( 'convertNexusSupportDepartments' ),
                       
'link_type'        => 'nexus_support_stock_actions'
                   
);
                    break;
               
                case
'convertNexusSupportRequests':
                   
$return[ $k ] = array(
                       
'step_title'        => 'convert_nexus_support_requests',
                       
'step_method'        => 'convertNexusSupportRequests',
                       
'ips_rows'            => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests' )->first(),
                       
'source_rows'        => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'            => 1500,
                       
'dependencies'        => array( 'convertNexusCustomers', 'convertNexusSupportDepartments', 'convertNexusSupportFields' ),
                       
'link_type'            => 'nexus_support_requests',
                       
'requires_rebuild'    => TRUE
                   
);
                    break;
               
                case
'convertNexusSupportReplies':
                   
$return[ $k ] = array(
                       
'step_title'        => 'convert_nexus_support_replies',
                       
'step_method'        => 'convertNexusSupportReplies',
                       
'ips_rows'            => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies' )->first(),
                       
'source_rows'        => $this->software->countRows( $v['table'], $v['where'] ),
                       
'per_cycle'            => 2000,
                       
'dependencies'        => array( 'convertNexusSupportRequests' ),
                       
'link_type'            => 'nexus_support_replies',
                       
'requires_rebuild'    => TRUE
                   
);
                    break;
            }
        }

       
$return = $this->software->extraMenuRows( $return );

        return
$return;
    }
   
   
/**
     * Returns an array of tables that need to be truncated when Empty Local Data is used
     *
     * @param    string    The method to truncate.
     * @return    array
     */
   
protected function truncate( $method )
    {
       
$return        = array();
       
$classname    = get_class( $this->software );

        if(
$classname::canConvert() === NULL )
        {
            return array();
        }
       
        foreach(
$classname::canConvert() as $k => $v )
        {
            switch(
$k )
            {
                case
'convertNexusCustomerFields':
                   
$return['convertNexusCustomerFields'] = array( 'nexus_customer_fields' => NULL );
                    break;
               
                case
'convertNexusCustomers':
                   
$return['convertNexusCustomers'] = array( 'nexus_customers' => array( "member_id<>?", \IPS\Member::loggedIn()->member_id ) );
                    break;
               
                case
'convertNexusCustomerAddresses':
                   
$return['convertNexusCustomerAddresses'] = array( 'nexus_customer_addresses' => NULL );
                    break;
               
                case
'convertNexusCustomerHistory':
                   
$return['convertNexusCustomerHistory'] = array( 'core_member_history' => array( 'log_app=?', 'nexus' ) );
                    break;
               
                case
'convertNexusAlternateContacts':
                   
$return['convertNexusAlternateContacts'] = array( 'nexus_alternate_contacts' => NULL );
                    break;
               
                case
'convertNexusNotes':
                   
$return['convertNexusNotes'] = array( 'nexus_notes' => NULL );
                    break;
               
                case
'convertNexusPackageGroups':
                   
$return['convertNexusPackageGroups'] = array( 'nexus_package_groups' => NULL );
                    break;
               
                case
'convertNexusPackageFields':
                   
$return['convertNexusPackageFields'] = array( 'nexus_package_fields' => NULL );
                    break;
               
                case
'convertNexusPackages':
                   
$return['convertNexusPackages'] = array(
                       
'nexus_packages'            => NULL,
                       
'nexus_package_images'        => NULL,
                       
'nexus_package_base_prices'    => NULL,
                       
'nexus_packages_ads'        => NULL,
                       
'nexus_packages_hosting'    => NULL,
                       
'nexus_packages_products'    => NULL,
                    );
                    break;
               
                case
'convertNexusReviews':
                   
$return['convertNexusReviews'] = array( 'nexus_reviews' => NULL );
                    break;
               
                case
'convertNexusCoupons':
                   
$return['convertNexusCoupons'] = array( 'nexus_coupons' => NULL );
                    break;
               
                case
'convertNexusInvoices':
                   
$return['convertNexusInvoices'] = array( 'nexus_invoices' => NULL );
                    break;
               
                case
'convertNexusTransactions':
                   
$return['convertNexusTransactions'] = array( 'nexus_transactions' => NULL );
                    break;
               
                case
'convertNexusPurchases':
                   
$return['convertNexusPurchases'] = array( 'nexus_purchases' => NULL );
                    break;
               
                case
'convertNexusFraudRules':
                   
$return['convertNexusFraudRules'] = array( 'nexus_fraud_rules' => NULL );
                    break;
               
                case
'convertNexusSupportDepartments':
                   
$return['convertNexusSupportDepartments'] = array( 'nexus_support_departments' => NULL );
                    break;
               
                case
'convertNexusSupportFields':
                   
$return['convertNexusSupportFields'] = array( 'nexus_support_fields' => NULL );
                    break;
               
                case
'convertNexusSupportStatuses':
                   
$return['convertNexusSupportStatuses'] = array( 'nexus_support_statuses' => NULL );
                    break;
               
                case
'convertNexusSupportSeverities':
                   
$return['convertNexusSupportSeverities'] = array( 'nexus_support_severities' => NULL );
                    break;
               
                case
'convertNexusSupportStockActions':
                   
$return['convertNexusSupportStockActions'] = array( 'nexus_support_stock_actions' => NULL );
                    break;
               
                case
'convertNexusSupportRequests':
                   
$return['convertNexusSupportRequests'] = array( 'nexus_support_requests' => NULL );
                    break;
               
                case
'convertNexusSupportReplies':
                   
$return['convertNexusSupportReplies'] = array( 'nexus_support_replies' => NULL );
                    break;
            }
        }

        return
$return[ $method ];
    }
   
   
/**
     * This is how the insert methods will work - basically like 3.x, but we should be using the actual classes to insert the data unless there is a real world reason not too.
     * Using the actual routines to insert data will help to avoid having to resynchronize and rebuild things later on, thus resulting in less conversion time being needed overall.
     * Anything that parses content, for example, may need to simply insert directly then rebuild via a task over time, as HTML Purifier is slow when mass inserting content.
     */
   
    /**
     * A note on logging -
     * If the data is missing and it is unlikely that any source software would be able to provide this, we do not need to log anything and can use default data (for example, group_layout in convertLeaderGroups).
     * If the data is missing and it is likely that a majority of the source software can provide this, we should log a NOTICE and use default data (for example, a_casesensitive in convertAcronyms).
     * If the data is missing and it is required to convert the item, we should log a WARNING and return FALSE.
     * If the conversion absolutely cannot proceed at all (filestorage locations not writable, for example), then we should log an ERROR and throw an \IPS\convert\Exception to completely halt the process and redirect to an error screen showing the last logged error.
     */
   
    /**
     * Convert a customer
     *
     * @param    array        Data to insert
     * @param    array        Custom Field Data
     * @return    int|bool    The ID of the inserted customer, or FALSE on failure
     */
   
public function convertNexusCustomer( $info, $fields=array() )
    {
        if ( !isset(
$info['member_id'] ) )
        {
           
$this->software->app->log( 'nexus_customer_missing_ids', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }
        else
        {
           
$sourceId = $info['member_id'];
           
            try
            {
               
$info['member_id'] = $this->software->app->getLink( $info['member_id'], 'core_members', TRUE );
            }
            catch( \
OutOfRangeException $e )
            {
               
$this->software->app->log( 'nexus_customer_missing_member', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['member_id'] );
                return
FALSE;
            }
        }
       
        if ( !isset(
$info['cm_first_name'] ) )
        {
           
$info['cm_first_name'] = '';
        }
       
        if ( !isset(
$info['cm_last_name'] ) )
        {
           
$info['cm_last_name'] = '';
        }
       
        if ( !isset(
$info['cm_phone'] ) )
        {
           
$info['cm_phone'] = '';
        }
       
        if ( isset(
$info['cm_profiles'] ) )
        {
            if (
is_array( $info['cm_profiles'] ) )
            {
               
$info['cm_profiles'] = json_encode( $info['cm_profiles'] );
            }
        }
        else
        {
           
$info['cm_profiles'] = '';
        }
       
       
$info = array_merge( $info, $this->_formatCustomerFields( $fields ) );

        \
IPS\Db::i()->replace( 'nexus_customers', $info );
       
$this->software->app->addLink( $info['member_id'], $sourceId, 'nexus_customers' );
       
        return
$info['member_id'];
    }
   
   
/**
     * Format Customer Fields for saving
     *
     * @param    array        The fields
     * @return    array        Formatted Fields
     */
   
protected function _formatCustomerFields( $fields )
    {
       
$return = array();
        foreach(
$fields as $key => $value )
        {
            if (
is_array( $value ) )
            {
               
$value = json_encode( $value );
            }
           
            try
            {
               
$id = $this->software->app->getLink( str_replace( 'field_', '', $key ), 'nexus_customer_fields' );
               
               
$return['field_' . $id] = $value;
            }
            catch( \
OutOfRangeException $e )
            {
                continue;
            }
        }
       
        return
$return;
    }
   
   
/**
     * Convert a note
     *
     * @param    array        Info
     * @return    int|bool    The newly inserted note ID, or FALSE on failure
     */
   
public function convertNexusNote( $info )
    {
       
$hasId = TRUE;
        if ( !isset(
$info['note_id'] ) )
        {
           
$hasId = FALSE;
        }
       
        if ( isset(
$info['note_member'] ) )
        {
            try
            {
               
$info['note_member'] = $this->software->app->getLink( $info['note_member'], 'core_members', TRUE );
            }
            catch( \
OutOfRangeException $e )
            {
               
$this->software->app->log( "nexus_note_missing_member", __METHOD__, \IPS\convert\App::LOG_WARNING, ( $hasId ) ? $info['note_id'] : NULL );
                return
FALSE;
            }
        }
        else
        {
           
$this->software->app->log( 'nexus_note_missing_member', __METHOD__, \IPS\convert\App::LOG_WARNING, ( $hasId ) ? $info['note_id'] : NULL );
            return
FALSE;
        }
       
        if ( empty(
$info['note_text'] ) )
        {
           
$this->software->app->log( 'nexus_note_missing_content', __METHOD__, \IPS\convert\App::LOG_WARNING, ( $hasId ) ? $info['note_id'] : NULL );
            return
FALSE;
        }
       
        if ( isset(
$info['note_author'] ) )
        {
            try
            {
               
$info['note_author'] = $this->software->app->getLink( $info['note_author'], 'core_members', TRUE );
            }
            catch( \
OutOfRangeException $e )
            {
               
$info['note_author'] = 0;
            }
        }
        else
        {
           
$info['note_author'] = 0;
        }
       
        if ( isset(
$info['note_date'] ) )
        {
            if (
$info['note_date'] instanceof \IPS\DateTime )
            {
               
$info['note_date'] = $info['note_date']->getTimestamp();
            }
        }
        else
        {
           
$info['note_date'] = time();
        }
       
        if (
$hasId )
        {
           
$id = $info['note_id'];
            unset(
$info['note_id'] );
        }
       
       
$inserted_id = \IPS\Db::i()->insert( 'nexus_notes', $info );
       
        if (
$hasId )
        {
           
$this->software->app->addLink( $inserted_id, $id, 'nexus_notes' );
        }
       
        return
$inserted_id;
    }
   
   
/**
     * Convert a package group
     *
     * @param    array        Info
     * @param    string|NULL    Path to the groups cover photo, or NULL
     * @param    string|NULL    Raw filedata for the groups cover photo, or NULL
     * @return    int|bool    THe ID of the newly inserted package group, or FALSE on failure
     */
   
public function convertNexusPackageGroup( $info, $filepath=NULL, $filedata=NULL )
    {
        if ( !isset(
$info['pg_id'] ) )
        {
           
$this->software->app->log( 'nexus_package_group_missing_ids', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }
       
        if ( isset(
$info['pg_name'] ) )
        {
           
$name = $info['pg_name'];
            unset(
$info['pg_name'] );
        }
        else
        {
           
$name = "Untitled Package Group {$info['pg_id']}";
        }
       
        if ( !isset(
$info['pg_seo_name'] ) )
        {
           
$info['pg_seo_name'] = \IPS\Http\Url::seoTitle( $name );
        }
       
        if ( !isset(
$info['pg_position'] ) )
        {
           
$position = \IPS\Db::i()->select( 'MAX(pg_position)', 'nexus_package_groups' )->first();
           
           
$info['pg_position'] = $position + 1;
        }
       
        if ( isset(
$info['pg_parent'] ) )
        {
           
$info['pg_conv_parent'] = $info['pg_parent'];
        }
        else
        {
           
$info['pg_parent'] = 0;
        }
       
        if ( isset(
$info['pg_image'] ) AND ( !is_null( $filepath ) OR !is_null( $filedata ) ) )
        {
            if (
is_null( $filedata ) AND !is_null( $filepath ) )
            {
               
$filedata = @file_get_contents( rtrim( $filepath, '/' ) . '/' . $info['pg_image'] );
                unset(
$filepath );
            }
           
            if (
$filedata )
            {
                try
                {
                   
$file = \IPS\File::create( 'nexus_PackageGroups', $info['pg_image'], $filedata );
                   
$info['pg_image'] = (string) $file;
                }
                catch( \
Exception $e )
                {
                   
$info['pg_image'] = '';
                }
            }
            else
            {
               
$info['pg_image'] = '';
            }
        }
        else
        {
           
$info['pg_image'] = '';
        }
       
       
$id = $info['pg_id'];
        unset(
$info['pg_id'] );
       
       
$insertedId = \IPS\Db::i()->insert( 'nexus_package_groups', $info );
       
$this->software->app->addLink( $insertedId, $id, 'nexus_package_groups' );

       
/* Custom Lang */
       
\IPS\Lang::saveCustom( 'nexus', "nexus_pgroup_{$insertedId}", $name );
       
        \
IPS\Db::i()->update( 'nexus_package_groups', array( 'pg_parent' => $insertedId ), array( "pg_conv_parent=?", $id ) );
       
        return
$insertedId;
    }

   
/**
     * Convert a package
     *
     * @param    array        $info        Info
     * @param    string        $filePath    Path to images
     * @return    int|bool        The ID of the newly inserted package, or FALSE on failure
     */
   
public function convertNexusPackage( $info, $filePath=NULL )
    {
       
/* !Required: ID */
       
if ( !isset( $info['p_id'] ) )
        {
           
$this->software->app->log( 'nexus_package_missing_id', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }

        if ( isset(
$info['p_name'] ) )
        {
           
$name = $info['p_name'];
            unset(
$info['p_name'] );
        }
        else
        {
           
$name = "Untitled Package {$info['p_id']}";
        }

        if ( isset(
$info['p_description'] ) )
        {
           
$description = $info['p_description'];
            unset(
$info['p_description'] );
        }
        else
        {
           
$description = '';
        }

       
/* !Required: Price */
       
if( !isset( $info['p_base_price'] ) )
        {
           
$this->software->app->log( 'nexus_package_missing_price', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['p_id'] );
            return
FALSE;
        }

       
/* !Required: Package Group */
       
if( !isset( $info['p_group'] ) )
        {
           
$this->software->app->log( 'nexus_package_missing_group', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['p_id'] );
            return
FALSE;
        }
       
$info['p_group'] = $this->software->app->getLink( $info['p_group'], 'nexus_package_groups' );

        if( isset(
$info['p_support_severity'] ) )
        {
           
$info['p_support_severity'] = $this->software->app->getLink( $info['p_support_severity'], 'nexus_support_severities' );
        }

       
/* Viewable User Groups */
       
if( isset( $info['p_member_group'] ) AND $info['p_member_group'] != '*' )
        {
           
$e = explode( ',', $info['p_member_group'] );
           
$newGroups = [];

           
array_walk( $info['p_member_group'], function( &$group, $key, &$newGroups )
            {
                try
                {
                   
$newGroups[] = $this->software->app->getLink( $group, 'core_groups', TRUE );
                }
                catch( \
OutOfRangeException $ex ) { }
            },
$newGroups );

           
$info['p_member_group'] = $info['p_member_group'];
        }

       
/* Primary User Group */
       
if( isset( $info['p_primary_group'] ) )
        {
           
$info['p_primary_group'] = $this->software->app->getLink( $info['p_primary_group'], 'core_groups', TRUE );
        }

       
/* Secondary User Groups */
       
if( isset( $info['p_secondary_group'] ) )
        {
           
$e = explode( ',', $info['p_secondary_group'] );
           
$newSecondaryGroups = [];

           
array_walk( $info['p_secondary_group'], function( $group, $key, &$newSecondaryGroups )
            {
                try
                {
                   
$newSecondaryGroups[] = $this->software->app->getLink( $group, 'core_groups', TRUE );
                }
                catch( \
OutOfRangeException $ex ) { }
            },
$newSecondaryGroups );
        }

       
/* Associable Packages */
       
if( isset( $info['p_associable'] ) )
        {
            try
            {
               
$info['p_associable'] = $this->software->app->getLink( $info['p_associable'], 'nexus_packages' );
            }
            catch( \
OutOfRangeException $ex )
            {
               
$info['conv_p_associable'] = $info['p_associable'];
                unset(
$info['p_associable'] );
            }
        }

        if ( !isset(
$info['p_position'] ) )
        {
            try
            {
               
$position = \IPS\Db::i()->select( 'MAX(p_position)', 'nexus_packages' )->first();
               
$info['p_position'] = $position + 1;
            }
            catch( \
UnderflowException $e ) { }
        }

       
/* Default Currency */
       
$currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
       
$price = new \IPS\nexus\Money( $info['p_base_price'], $currency );
       
$basePrice = [ $currency => [ 'amount' => $price->amount, 'currency' => $currency ] ];
        unset(
$info['p_base_price'] );

       
/* Renewal costs & terms */
       
if( isset( $info['p_renew_options'] ) AND count( $info['p_renew_options'] ) )
        {
           
$newOptions = array();

            foreach(
$info['p_renew_options'] as $value )
            {
               
$price = new \IPS\nexus\Money( $value['price'], $currency );
               
$renewPrice = [ $currency => [ 'amount' => $price->amount, 'currency' => $currency ] ];
               
$newOptions[] = array(
                   
'cost' => $renewPrice,
                   
'term' => $value['term'],
                   
'unit' => $value['unit'],
                   
'add' => isset( $value['add'] ) ? $value['add'] : false
               
);
            }

           
$info['p_renew_options'] = json_encode( $newOptions );
        }

       
/* Discounts */
        //@TODO

       
$productImages = isset( $info['p_images'] ) ? $info['p_images'] : NULL;
        unset(
$info['p_images'] );

       
$package = array(
           
'p_name' => $name,
           
'p_seo_name' => \IPS\Http\url::seoTitle( $name ),
           
'p_group' => 0,
           
'p_stock' => -1,
           
'p_reg' => 0,
           
'p_store' => 1,
           
'p_member_groups' => '*',
           
'p_allow_upgrading' => 0,
           
'p_upgrade_charge' => 0,
           
'p_allow_downgrading' => 0,
           
'p_downgrade_refund' => 0,
           
'p_base_price' => json_encode( $basePrice ),
           
'p_tax' => 0,
           
'p_renewal_days' => 0,
           
'p_primary_group' => 0,
           
'p_secondary_group' => '',
           
'p_return_primary' => 1,
           
'p_return_secondary' => 0,
           
'p_position' => 0,
           
'p_associable' => '',
           
'p_force_assoc' => 0,
           
'p_assoc_error' => NULL,
           
'p_discounts' => '[]',
           
'p_page' => NULL,
           
'p_support' => 0,
           
'p_support_department' => 0,
           
'p_support_severity' => 0,
           
'p_featured' => 0,
           
'p_upsell' => 0,
           
'p_notify' => '',
           
'p_type' => 'product',
           
'p_custom' => 0,
           
'p_reviewable' => 0,
           
'p_review_moderate' => 0,
           
'p_image' => NULL,
           
'p_methods' => '*',
           
'p_renew_options' => '',
           
'p_group_renewals' => 0,
           
'p_rebuild_thumb' => 0,
           
'p_renewal_days_advance' => -1,
           
'p_date_added' => time(),
           
'p_reviews' => 0,
           
'p_rating' => 0,
           
'p_unapproved_reviews' => NULL,
           
'p_hidden_reviews' => NULL,
           
'p_grace_period' => 0,
           
'p_conv_associable' => 0
       
);

       
/* Save Package Data */
       
$insertedId = \IPS\Db::i()->insert( 'nexus_packages', $this->_getValues( $package, $info ) );
       
$originalId = $info['p_id'];
        unset(
$info['p_id'] );

       
/* Images */
       
$images = NULL;

        if(
$productImages )
        {
           
$default = 0;
            foreach(
$productImages as $image )
            {
                if ( ( isset(
$image['data'] ) AND is_null( $image['data'] ) ) AND !is_null( $filePath ) )
                {
                   
$filedata = @file_get_contents( rtrim( $filePath, '/' ) . '/' . $image['filename'] );
                    unset(
$filepath );
                }

                if (
$filedata )
                {
                    try
                    {
                       
$file = \IPS\File::create( 'nexus_Products', $image['filename'], $filedata );
                       
$images[] = [ 'image_product' => $insertedId, 'image_location' => (string) $file, 'image_primary' => ( $default ? 0 : 1 ) ];
                       
$default++;
                    }
                    catch( \
Exception $e ) {}
                }
            }

           
/* Insert Images */
           
if( is_array( $images ) AND count( $images ) )
            {
                \
IPS\Db::insert( 'nexus_package_images', $images );
            }
        }

       
/* Product Data */
       
if( $package['p_type'] == 'product' )
        {
           
$product = array(
                       
'p_id' => $insertedId,
                       
'p_physical' => 0,
                       
'p_subscription' => 0,
                       
'p_shipping' => '*',
                       
'p_weight' => 0,
                       
'p_lkey' => 0,
                       
'p_lkey_identifier' => 'name',
                       
'p_lkey_uses' => -1,
                       
'p_show' => 1,
                       
'p_length' => 0,
                       
'p_width' => 0,
                       
'p_height' => 0
                   
);

           
/* Save Product Data */
           
\IPS\Db::i()->insert( 'nexus_packages_products', $this->_getValues( $product, $info ) );

           
/* Add Link */
           
$this->software->app->addLink( $insertedId, $originalId, 'nexus_packages_products' );
        }

       
/* Base Price */
       
if ( !\IPS\Db::i()->checkForColumn( 'nexus_package_base_prices', $currency ) )
        {
            \
IPS\Db::i()->addColumn( 'nexus_package_base_prices', array(
               
'name'    => $currency,
               
'type'    => 'FLOAT'
           
) );
        }
        \
IPS\Db::i()->insert( 'nexus_package_base_prices', array( 'id' => $insertedId, $currency => $price->amount ) );

       
/* Custom lang strings */
       
\IPS\Lang::saveCustom( 'nexus', "nexus_package_{$insertedId}", $name );
        \
IPS\Lang::saveCustom( 'nexus', "nexus_package_{$insertedId}_desc", $description );

       
/* Add Link */
       
$this->software->app->addLink( $insertedId, $originalId, 'nexus_packages' );

       
/* Update associations */
       
\IPS\Db::i()->update( 'nexus_packages', array( 'p_associable' => $insertedId ), array( 'p_conv_associable=?', $originalId ) );

        return
$insertedId;
    }

   
/**
     * Convert an invoice
     *
     * @param    array        $info    Info
     * @return    int|bool        The ID of the newly inserted invoice, or FALSE on failure
     */
   
public function convertNexusInvoice( $info )
    {
       
/* !Required: ID */
       
if ( !isset( $info['i_id'] ) )
        {
           
$this->software->app->log( 'nexus_invoices_missing_id', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }

       
/* !Required: Items */
       
if ( !isset( $info['i_items'] ) OR !is_array( $info['i_items'] ) )
        {
           
$this->software->app->log( 'nexus_invoices_missing_items', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['i_id'] );
            return
FALSE;
        }

       
/* Default Currency */
       
$currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
       
$price = new \IPS\nexus\Money( $info['i_total'], $currency );
       
$info['i_total'] = $price->amount;

       
/* ITEMS */
       
$newItems = array();
        foreach(
$info['i_items'] as $item )
        {
           
$item['itemID'] = $this->software->app->getLink( $item['itemID'], 'nexus_packages' );
           
$newItems[] = $item;
        }
       
$info['i_items'] = json_encode( $newItems );

       
/* Find member */
       
try
        {
           
$info['i_member'] = $this->software->app->getLink( $info['i_member'], 'core_members', TRUE );
        }
        catch( \
Exception $e )
        {
            unset(
$info['i_member'] );
        }

        if( isset(
$info['i_status_extra'] ) )
        {
           
$info['i_status_extra'] = json_encode( $info['i_status_extra'] );
        }

       
/* Invoice */
       
$invoice = array(
           
'i_status' => \IPS\nexus\Invoice::STATUS_PENDING,
           
'i_title' => 'Converted Invoice '. $info['i_id'],
           
'i_member' => 0,
           
'i_items' => '[]',
           
'i_total' => $price->amount,
           
'i_date' => time(),
           
'i_return_uri' => '',
           
'i_paid' => 0,
           
'i_status_extra' => '[]',
           
'i_discount' => 0,
           
'i_renewal_ids' => '',
           
'i_po' => '',
           
'i_notes' => NULL,
           
'i_shipaddress' => NULL,
           
'i_billaddress' => NULL,
           
'i_currency' => $currency,
           
'i_guest_data' => NULL,
           
'i_billcountry' => NULL
         
);

       
/* Save Invoice Data */
       
$insertedId = \IPS\Db::i()->insert( 'nexus_invoices', $this->_getValues( $invoice, $info ) );

       
/* Add Link */
       
$this->software->app->addLink( $insertedId, $info['i_id'], 'nexus_invoices' );

        return
$insertedId;
    }

   
/**
     * Convert a transaction
     *
     * @param    array        $info    Info
     * @return    int|bool        The ID of the newly inserted transaction, or FALSE on failure
     */
   
public function convertNexusTransaction( $info )
    {
       
/* !Required: ID */
       
if ( !isset( $info['t_id'] ) )
        {
           
$this->software->app->log( 'nexus_transactions_missing_id', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }

       
/* !Required: MemberID */
       
if ( !isset( $info['t_member'] ) )
        {
           
$this->software->app->log( 'nexus_transactions_missing_member_id', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['t_id'] );
            return
FALSE;
        }

       
/* !Required: InvoiceID */
       
if ( !isset( $info['t_invoice'] ) )
        {
           
$this->software->app->log( 'nexus_transactions_missing_invoice_id', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['t_id'] );
            return
FALSE;
        }

       
/* !Required: Amount */
       
if ( !isset( $info['t_amount'] ) )
        {
           
$this->software->app->log( 'nexus_transactions_missing_amount', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['t_id'] );
            return
FALSE;
        }

       
/* Map IDs */
       
$info['t_invoice'] = $this->software->app->getLink( $info['t_invoice'], 'nexus_invoices' );
        try
        {
           
$info['t_member'] = $this->software->app->getLink( $info['t_member'], 'core_members', TRUE );
        }
        catch( \
OutOfRangeException $ex)
        {
           
$this->software->app->log( 'nexus_transactions_missing_member', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['t_id'] );
            return
FALSE;
        }

       
/* Default Currency */
       
$currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
       
$price = new \IPS\nexus\Money( $info['t_amount'], $currency );
       
$info['t_amount'] = $price->amount;

       
$transaction = array(
           
't_member' => 0,
           
't_invoice' => 0,
           
't_method' => 0,
           
't_status' => \IPS\nexus\Transaction::STATUS_PENDING,
           
't_amount' => 0,
           
't_date' => time(),
           
't_extra' => '[]',
           
't_fraud' => '',
           
't_gw_id' => '',
           
't_ip' => '::1',
           
't_fraud_blocked' => 0,
           
't_currency' => $currency,
           
't_partial_refund' => 0.000,
           
't_auth' => NULL,
           
't_billing_agreement' => NULL
       
);

       
/* Save Transaction Data */
       
$insertedId = \IPS\Db::i()->insert( 'nexus_transactions', $this->_getValues( $transaction, $info ) );

       
/* Add Link */
       
$this->software->app->addLink( $insertedId, $info['t_id'], 'nexus_transactions' );

        return
$insertedId;
    }

   
/**
     * Convert a purchase
     *
     * @param    array        $info    Info
     * @return    int|bool        The ID of the newly inserted purchase, or FALSE on failure
     */
   
public function convertNexusPurchase( $info )
    {
       
/* !Required: ID */
       
if ( !isset( $info['ps_id'] ) )
        {
           
$this->software->app->log( 'nexus_purchases_missing_id', __METHOD__, \IPS\convert\App::LOG_WARNING );
            return
FALSE;
        }

       
/* !Required: MemberID */
       
if ( !isset( $info['ps_member'] ) )
        {
           
$this->software->app->log( 'nexus_purchases_missing_member_id', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['ps_id'] );
            return
FALSE;
        }

       
/* !Required: InvoiceID */
       
if ( !isset( $info['ps_original_invoice'] ) )
        {
           
$this->software->app->log( 'nexus_purchases_missing_invoice_id', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['ps_id'] );
            return
FALSE;
        }

       
/* Map IDs */
       
$info['ps_original_invoice'] = $this->software->app->getLink( $info['ps_original_invoice'], 'nexus_invoices' );
       
$info['ps_item_id'] = $this->software->app->getLink( $info['ps_item_id'], 'nexus_packages' );
       
        try
        {
           
$info['ps_member'] = $this->software->app->getLink( $info['ps_member'], 'core_members', TRUE );
        }
        catch( \
OutOfRangeException $ex)
        {
           
$this->software->app->log( 'nexus_purchases_missing_member', __METHOD__, \IPS\convert\App::LOG_WARNING, $info['ps_id'] );
            return
FALSE;
        }

       
/* Commission payments */
       
if( isset( $info['ps_pay_to'] ) )
        {
           
$info['ps_pay_to'] = $this->software->app->getLink( $info['ps_pay_to'], 'core_members', TRUE );
        }

       
/* Parent Purchases */
       
if( isset( $info['ps_parent'] ) )
        {
            try
            {
               
$info['ps_parent'] = $this->software->app->getLink( $info['ps_parent'], 'nexus_purchases' );
            }
            catch( \
OutOfRangeException $ex )
            {
               
$info['ps_conv_parent'] = $info['ps_parent'];
                unset(
$info['ps_parent'] );
            }
        }

        if( !isset(
$info['ps_extra'] ) )
        {
           
$info['ps_extra'] = array();
        }

       
/* Old Primary Group */
       
if( isset( $info['ps_extra']['nexus']['old_primary_group'] ) )
        {
           
$info['ps_extra']['nexus']['old_primary_group'] = $this->software->app->getLink( $info['ps_extra']['nexus']['old_primary_group'], 'core_groups', TRUE );
        }

       
/* Old Secondary User Groups */
       
if( isset( $info['ps_extra']['nexus']['old_secondary_groups'] ) AND is_array( $info['ps_extra']['nexus']['old_secondary_groups'] ) )
        {
           
$newSecondaryGroups = [];

           
array_walk( $info['ps_extra']['nexus']['old_secondary_groups'], function( $group, $key, &$newSecondaryGroups )
            {
                try
                {
                   
$newSecondaryGroups[] = $this->software->app->getLink( $group, 'core_groups', TRUE );
                }
                catch( \
OutOfRangeException $ex ) { }
            },
$newSecondaryGroups );

           
$info['ps_extra']['nexus']['old_secondary_groups'] = $newSecondaryGroups;
        }

       
$info['ps_extra'] = json_encode( $info['ps_extra'] );

       
/* Default Currency */
       
$currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
        if( isset(
$info['ps_renewal_price'] ) )
        {
           
$price = new \IPS\nexus\Money( $info['ps_renewal_price'], $currency );
           
$info['ps_renewal_price'] = $price->amount;
        }

       
$purchase = array(
           
'ps_member' => 0,
           
'ps_name' => 'Converted Purchase ' . $info['ps_id'],
           
'ps_active' => 0,
           
'ps_cancelled' => 0,
           
'ps_start' => 0,
           
'ps_expire' => 0,
           
'ps_renewals' => 0,
           
'ps_renewal_price' => 0.00,
           
'ps_renewal_unit' => 0,
           
'ps_app' => 'nexus',
           
'ps_type' => 'package',
           
'ps_item_id' => 0,
           
'ps_item_uri' => '',
           
'ps_admin_uri' => '',
           
'ps_custom_fields' => '[]',
           
'ps_extra' => '[]',
           
'ps_parent' => 0,
           
'ps_invoice_pending' => 0,
           
'ps_invoice_warning_sent' => 1,
           
'ps_pay_to' => NULL,
           
'ps_commission' => NULL,
           
'ps_original_invoice' => 0,
           
'ps_tax' => 0,
           
'ps_can_reactivate' => 1,
           
'ps_grouped_renewals' => '',
           
'ps_renewal_currency' => $currency,
           
'ps_show' => 1,
           
'ps_grace_period' => 0,
           
'ps_billing_agreement' => NULL,
           
'ps_conv_parent' => 0
       
);

       
/* Save Purchase Data */
       
$insertedId = \IPS\Db::i()->insert( 'nexus_purchases', $this->_getValues( $purchase, $info ) );

       
/* Add Link */
       
$this->software->app->addLink( $insertedId, $info['ps_id'], 'nexus_purchases' );

       
/* Update associations */
       
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_parent' => $insertedId ), array( 'ps_conv_parent=?', $info['ps_id'] ) );

        return
$insertedId;
    }

   
/**
     * Get values from an array that exist in the source array
     *
     * @param    array        $defaults    Default populated array
     * @param    array        $source        User-supplied array
     * @return    array
     */
   
protected function _getValues( array $defaults, array $source )
    {
       
array_walk( $defaults, function( &$value, $key, $source )
        {
            if( isset(
$source[ $key ] ) )
            {
               
$value = $source[ $key ];
            }
        },
$source );

        return
$defaults;
    }
}