<?php

/**
 * @package		SP Transfer
 * @subpackage	Components
 * @copyright	SP CYEND - All rights reserved.
 * @author		SP CYEND
 * @link		http://www.cyend.com
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 */
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

// import the Joomla modellist library
jimport('joomla.application.component.model');

class SPTransferModelCom extends JModel {

    protected $jAp;
    protected $tableLog;
    protected $destination_db;
    protected $destination_query;
    protected $destination_table;
    protected $table_name;
    protected $source_db;
    protected $source_query;
    protected $user;
    protected $params;
    protected $task;
    protected $factory;
    protected $source;
    protected $id;
    protected $alias;

    function __construct($config = array()) {
        parent::__construct($config);
        $this->factory = new CYENDFactory();
        $this->source = new CYENDSource();
        $this->jAp = & JFactory::getApplication();
        $this->tableLog = $this->factory->getTable('Log', 'SPTransferTable');
        $this->destination_db = $this->getDbo();
        $this->destination_query = $this->destination_db->getQuery(true);
        $this->source_db = $this->source->source_db;
        $this->source_query = $this->source_db->getQuery(true);
        $this->user = JFactory::getUser();
        $this->params = JComponentHelper::getParams($this->factory->getComponentName());
        $this->alias = 'alias';
        $this->id = 'id';
    }

    public function init($task) {
        $this->task = $task;
        $this->task->state = 2;
    }

    public function categories($ids = null) {
        // Initialize
        $factory = $this->factory;
        //$source = $this->source;
        $jAp = $this->jAp;
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        //$destination_query = $this->destination_query;
        $source_db = $this->source_db;
        //$source_query = $this->source_query;
        $destination_table = $this->destination_table;
        //$user = $this->user;
        $params = $this->params;
        $task = $this->task;

        $factory->writeLog('<h2>' . JText::_($task->extension_name) . ' - ' . JText::_($task->extension_name . '_CATEGORIES') . '</h2>');

        // Load items
        $query = 'SELECT source_id
            FROM #__sptransfer_log
            WHERE tables_id = ' . (int) $task->id . ' AND state >= 2
            ORDER BY id ASC';
        $destination_db->setQuery($query);
        $result = $destination_db->query();
        if (!$result) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->$destination_db()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $temp = $destination_db->loadResultArray();

        $query = 'SELECT * 
            FROM #__categories
            WHERE extension LIKE "' . $task->extension_name . '"';
        if (!is_null($temp[0]))
            $query .= ' AND id NOT IN (' . implode(',', $temp) . ')';
        if (!is_null($ids[0]))
            $query .= ' AND id IN (' . implode(',', $ids) . ')';
        $query .= ' ORDER BY id ASC';
        $source_db->setQuery($query);
        if (!$source_db->query()) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $items = $source_db->loadAssocList();

        //percentage
        $percTotal = count($items);
        if ($percTotal < 100)
            $percKlasma = 0.1;
        if ($percTotal > 100 && $percTotal < 2000)
            $percKlasma = 0.05;
        if ($percTotal > 2000)
            $percKlasma = 0.01;
        $percTen = $percKlasma * $percTotal;
        $percCounter = 0;
        if ($percTotal == 0) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_TRANSFER) . '</p>';
            $factory->writeLog($message);
        }

        // Loop to save items
        foreach ($items as $item) {

            //percentage
            $percCounter += 1;
            if (@($percCounter % $percTen) == 0) {
                $perc = round(( 100 * $percCounter ) / $percTotal);
                $message = $perc . '% ' . JText::_('COM_SPTRANSFER_MSG_PROCESSED') . '<br/>';
                $factory->writeLog($message);
            }

            //log            
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => $task->id, "source_id" => $item['id']));
            $tableLog->created = null;
            $tableLog->note = "";
            $tableLog->source_id = $item['id'];
            $tableLog->destination_id = $item['id'];
            $tableLog->state = 1;
            $tableLog->tables_id = $task->id;

            // Create record
            $destination_db->setQuery(
                    "INSERT INTO #__categories" .
                    " (id)" .
                    " VALUES (" . $destination_db->quote($item['id']) . ")"
            );
            if (!$destination_db->query()) {
                if ($params->get("new_ids", 0) == 1) {
                    $destination_db->setQuery(
                            "INSERT INTO #__categories" .
                            " (title)" .
                            " VALUES (" . $destination_db->quote('sp_transfer') . ")"
                    );
                    if (!$destination_db->query()) {
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                        $factory->writeLog($message);
                        $tableLog->note = $message;
                        $tableLog->store();
                        continue;
                    }
                    $destination_db->setQuery(
                            "SELECT id FROM #__categories" .
                            " WHERE title LIKE " . $destination_db->quote('sp_transfer')
                    );
                    $destination_db->query();
                    $tableLog->destination_id = $destination_db->loadResult();
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_NEW_IDS', $item['id'], $tableLog->destination_id) . '</p>';
                    $item['id'] = $tableLog->destination_id;
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                } elseif ($params->get("new_ids", 0) == 0) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                    $tableLog->store();
                    continue;
                }
            }

            // Reset
            $destination_table->reset();

            //Replace existing item
            if ($params->get("new_ids", 0) == 2)
                $destination_table->load($item['id']);

            // Bind
            if (!$destination_table->bind($item)) {
                // delete record
                $destination_db->setQuery(
                        "DELETE FROM #__categories" .
                        " WHERE id = " . $destination_db->quote($item['id'])
                );
                if (!$destination_db->query()) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                }
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_BIND', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            // Store
            if (!$destination_table->store()) {
                if ($params->get("duplicate_alias", 0)) {
                    $destination_table->{$this->alias} .= '-sp-' . rand(100, 999);
                    if (!$destination_table->store()) {
                        // delete record
                        $destination_db->setQuery(
                                "DELETE FROM #__categories" .
                                " WHERE id = " . $destination_db->quote($item['id'])
                        );
                        if (!$destination_db->query()) {
                            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                            $factory->writeLog($message);
                        }
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                        $factory->writeLog($message);
                        $tableLog->note = $message;
                        $tableLog->store();
                        continue;
                    }
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_DUPLICATE_ALIAS', $item['id'], $destination_table->{$this->alias}) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                } else {
                    // delete record
                    $destination_db->setQuery(
                            "DELETE FROM #__categories" .
                            " WHERE id = " . $destination_db->quote($item['id'])
                    );
                    if (!$destination_db->query()) {
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                        $factory->writeLog($message);
                    }
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                    $tableLog->store();
                    continue;
                }
            }

            //Log
            $tableLog->state = 2;
            $tableLog->store();
        } //Main loop end
        // Rebuild the hierarchy.
        if (!$destination_table->rebuild()) {
            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_REBUILD', $destination_table->getError()) . '</p>';
            $factory->writeLog($message);
            return false;
        }

        // Clear the component's cache
        $cache = JFactory::getCache('com_categories');
        $cache->clean();
    }

    public function items($ids = null) {
        // Initialize
        $factory = $this->factory;
        //$source = $this->source;
        $jAp = $this->jAp;
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        //$destination_query = $this->destination_query;
        $source_db = $this->source_db;
        //$source_query = $this->source_query;
        $destination_table = $this->destination_table;
        //$user = $this->user;
        $params = $this->params;
        $task = $this->task;
        $table_name = $this->task->name;
        $id = $this->id;

        $factory->writeLog('<h2>' . JText::_($task->extension_name) . ' - ' . JText::_($task->extension_name . '_' . $task->name) . '</h2>');

        // Load items
        $query = 'SELECT source_id
            FROM #__sptransfer_log
            WHERE tables_id = ' . (int) $task->id . ' AND state >= 2
            ORDER BY id ASC';
        $destination_db->setQuery($query);
        if (!$destination_db->query()) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->$destination_db()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $temp = $destination_db->loadResultArray();

        $query = $this->task->query;
        if (!is_null($temp[0]))
            $query .= ' AND id NOT IN (' . implode(',', $temp) . ')';
        if (!is_null($ids[0]))
            $query .= ' AND id IN (' . implode(',', $ids) . ')';
        $query .= ' ORDER BY id ASC';
        $source_db->setQuery($query);
        $result = $source_db->query();
        if (!$result) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $items = $source_db->loadAssocList();

        //percentage
        $percTotal = count($items);
        if ($percTotal < 100)
            $percKlasma = 0.1;
        if ($percTotal > 100 && $percTotal < 2000)
            $percKlasma = 0.05;
        if ($percTotal > 2000)
            $percKlasma = 0.01;
        $percTen = $percKlasma * $percTotal;
        $percCounter = 0;
        if ($percTotal == 0) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_TRANSFER) . '</p>';
            $factory->writeLog($message);
        }

        // Loop to save items
        foreach ($items as $item) {

            //percentage
            $percCounter += 1;
            if (@($percCounter % $percTen) == 0) {
                $perc = round(( 100 * $percCounter ) / $percTotal);
                $message = $perc . '% ' . JText::_('COM_SPTRANSFER_MSG_PROCESSED') . '<br/>';
                $factory->writeLog($message);
            }

            //log            
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => $task->id, "source_id" => $item['id']));
            $tableLog->created = null;
            $tableLog->note = "";
            $tableLog->source_id = $item['id'];
            $tableLog->destination_id = $item['id'];
            $tableLog->state = 1;
            $tableLog->tables_id = $task->id;

            // Create record
            $destination_db->setQuery(
                    "INSERT INTO #__" . $table_name .
                    " (" . $id . ")" .
                    " VALUES (" . $destination_db->quote($item['id']) . ")"
            );
            if (!$destination_db->query()) {
                if ($params->get("new_ids", 0) == 1) {
                    $destination_db->setQuery(
                            "INSERT INTO #__" . $table_name .
                            " (" . $id . ")" .
                            " VALUES (" . $destination_db->quote(0) . ")"
                    );
                    if (!$destination_db->query()) {
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                        $factory->writeLog($message);
                        $tableLog->note = $message;
                        $tableLog->store();
                        continue;
                    }
                    $destination_db->setQuery(
                            "SELECT id FROM #__" . $table_name .
                            " ORDER BY id DESC "
                    );
                    $destination_db->query();
                    $tableLog->destination_id = $destination_db->loadResult();
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_NEW_IDS', $item['id'], $tableLog->destination_id) . '</p>';
                    $item['id'] = $tableLog->destination_id;
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                } elseif ($params->get("new_ids", 0) == 0) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                    $tableLog->store();
                    continue;
                }
            }

            // Reset
            $destination_table->reset();

            //Replace existing item
            if ($params->get("new_ids", 0) == 2)
                $destination_table->load($item['id']);

            // Bind
            if (!$destination_table->bind($item)) {
                // delete record
                $destination_db->setQuery(
                        "DELETE FROM #__" . $table_name .
                        " WHERE " . $id . " = " . $destination_db->quote($item['id'])
                );
                if (!$destination_db->query()) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                }
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_BIND', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            // Store
            if (!$destination_table->store()) {
                if ($params->get("duplicate_alias", 0)) {
                    $destination_table->{$this->alias} .= '-sp-' . rand(100, 999);
                    if (!$destination_table->store()) {
                        // delete record
                        $destination_db->setQuery(
                                "DELETE FROM #__" . $table_name .
                                " WHERE " . $id . " = " . $destination_db->quote($item['id'])
                        );
                        if (!$destination_db->query()) {
                            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                            $factory->writeLog($message);
                        }
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                        $factory->writeLog($message);
                        $tableLog->note = $message;
                        $tableLog->store();
                        continue;
                    }
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_DUPLICATE_ALIAS', $item['id'], $destination_table->{$this->alias}) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                } else {
                    // delete record
                    $destination_db->setQuery(
                            "DELETE FROM #__" . $table_name .
                            " WHERE " . $id . " = " . $destination_db->quote($item['id'])
                    );
                    if (!$destination_db->query()) {
                        $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                        $factory->writeLog($message);
                    }
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                    $factory->writeLog($message);
                    $tableLog->note = $message;
                    $tableLog->store();
                    continue;
                }
            }

            //add extra coding
            $this->tableLog = $tableLog;
            switch ($task->extension_name . '_' . $task->name) {
                case 'com_users_users':
                    $this->com_users_users();
                    break;
                case 'com_content_content':
                    $this->com_content_content();
                    break;
                case 'com_banners_banners':
                    $this->com_banners_banners();
                    break;
                case 'com_modules_modules':
                    $this->com_modules_modules();
                    break;
            }

            //Log
            $tableLog->state = $this->task->state; //state for success;
            $tableLog->store();
        } //Main loop end
    }

    public function categories_fix($ids = null) {
        // Initialize
        $factory = $this->factory;
        //$source = $this->source;
        $jAp = $this->jAp;
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        //$destination_query = $this->destination_query;
        $source_db = $this->source_db;
        //$source_query = $this->source_query;
        $destination_table = $this->destination_table;
        //$user = $this->user;
        //$params = $this->params;
        $task = $this->task;
        //$id = $this->id;

        $factory->writeLog('<h2>' . JText::_($task->extension_name) . ' - ' . JText::_($task->extension_name . '_CATEGORIES') . ' - ' . JText::_('COM_SPTRANSFER_FIX') . '</h2>');

        // Load items
        $query = 'SELECT destination_id
            FROM #__sptransfer_log
            WHERE tables_id = ' . (int) $task->id . ' AND ( state = 2 OR state = 3 )';
        if (!is_null($ids[0]))
            $query .= ' AND source_id IN (' . implode(',', $ids) . ')';
        $query .= ' ORDER BY id ASC';
        $destination_db->setQuery($query);
        if (!$destination_db->query()) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $temp = $destination_db->loadResultArray();

        // Return if empty
        if (is_null($temp[0])) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_FIX) . '</p>';
            $factory->writeLog($message);
            return;
        }

        $query = 'SELECT * 
            FROM #__categories
            WHERE extension LIKE "' . $task->extension_name . '"
            AND parent_id > 0';
        $query .= ' AND id IN (' . implode(',', $temp) . ')';
        $query .= ' ORDER BY id ASC';
        $destination_db->setQuery($query);
        $result = $destination_db->query();
        if (!$result) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $items = $destination_db->loadAssocList();

        //percentage
        $percTotal = count($items);
        if ($percTotal < 100)
            $percKlasma = 0.1;
        if ($percTotal > 100 && $percTotal < 2000)
            $percKlasma = 0.05;
        if ($percTotal > 2000)
            $percKlasma = 0.01;
        $percTen = $percKlasma * $percTotal;
        $percCounter = 0;
        if ($percTotal == 0) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_TRANSFER) . '</p>';
            $factory->writeLog($message);
        }

        // Loop to save items
        foreach ($items as $item) {
            //percentage
            $percCounter += 1;
            if (@($percCounter % $percTen) == 0) {
                $perc = round(( 100 * $percCounter ) / $percTotal);
                $message = $perc . '% ' . JText::_('COM_SPTRANSFER_MSG_PROCESSED') . '<br/>';
                $factory->writeLog($message);
            }

            // Set destination_id
            //created_user_id
            if ($item['created_user_id'] > 0) {
                $tableLog->load(array("tables_id" => 3, "source_id" => $item['created_user_id']));
                if ($tableLog->source_id != $tableLog->destination_id) {
                    $item['created_user_id'] = $tableLog->destination_id;
                }
            }
            //modified_user_id
            /*
              if ($item['modified_user_id'] > 0) {
              $tableLog->load(array("tables_id" => 3, "source_id" => $item['modified_user_id']));
              if ($tableLog->source_id != $tableLog->destination_id) {
              $item['modified_user_id'] = $tableLog->destination_id;
              }
              }
             * 
             */

            //parent_id
            if ($item['parent_id'] > 1) {
                $tableLog->reset();
                $tableLog->id = null;
                $tableLog->load(array("tables_id" => $task->id, "source_id" => $item['parent_id']));
                if ($tableLog->source_id == $tableLog->destination_id) {
                    $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
                    $tableLog->state = 4;
                    $tableLog->store();
                    continue;
                }
                $item['parent_id'] = $tableLog->destination_id;
            } else {
                $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
                $tableLog->state = 4;
                $tableLog->store();
                continue;
            }

            //log            
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
            $tableLog->created = null;
            $tableLog->state = 3;
            $tableLog->tables_id = $task->id;

            // Reset
            $destination_table->reset();

            // Bind
            if (!$destination_table->bind($item)) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_BIND', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            // Store
            if (!$destination_table->store()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            //Log
            $tableLog->state = 4;
            $tableLog->store();
        } //Main loop end   
        // Rebuild the hierarchy.
        if (!$destination_table->rebuild()) {
            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_REBUILD', $destination_table->getError()) . '</p>';
            $factory->writeLog($message);
            return false;
        }

        // Clear the component's cache
        $cache = JFactory::getCache('com_categories');
        $cache->clean();
    }

    public function items_fix($ids = null) {
        // Initialize
        $factory = $this->factory;
        //$source = $this->source;
        $jAp = $this->jAp;
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        //$destination_query = $this->destination_query;
        $source_db = $this->source_db;
        //$source_query = $this->source_query;
        $destination_table = $this->destination_table;
        //$user = $this->user;
        //$params = $this->params;
        $task = $this->task;
        //$id = $this->id;

        $factory->writeLog('<h2>' . JText::_($task->extension_name) . ' - ' . JText::_($task->extension_name . '_' . $task->name) . ' - ' . JText::_('COM_SPTRANSFER_FIX') . '</h2>');

        // Load items
        $query = 'SELECT destination_id
            FROM #__sptransfer_log
            WHERE tables_id = ' . (int) $task->id . ' AND ( state = 2 OR state = 3 )';
        if (!is_null($ids[0]))
            $query .= ' AND source_id IN (' . implode(',', $ids) . ')';
        $query .= ' ORDER BY id ASC';
        $destination_db->setQuery($query);
        if (!$destination_db->query()) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $source_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $temp = $destination_db->loadResultArray();

        // Return if empty
        if (is_null($temp[0])) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_FIX) . '</p>';
            $factory->writeLog($message);
            return;
        }

        $query = $this->task->query;
        $query .= ' AND id IN (' . implode(',', $temp) . ')';
        $query .= ' ORDER BY id ASC';
        $destination_db->setQuery($query);
        $result = $destination_db->query();
        if (!$result) {
            $jAp->enqueueMessage(JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()), 'error');
            $message = '<p><b><font color="red">' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_QUERY', $destination_db->getErrorMsg()) . '</font></b></p>';
            $factory->writeLog($message);
            return false;
        }
        $items = $destination_db->loadAssocList();

        //percentage
        $percTotal = count($items);
        if ($percTotal < 100)
            $percKlasma = 0.1;
        if ($percTotal > 100 && $percTotal < 2000)
            $percKlasma = 0.05;
        if ($percTotal > 2000)
            $percKlasma = 0.01;
        $percTen = $percKlasma * $percTotal;
        $percCounter = 0;
        if ($percTotal == 0) {
            $message = '<p>' . JText::_(COM_SPTRANSFER_NOTHING_TO_TRANSFER) . '</p>';
            $factory->writeLog($message);
        }

        // Loop to save items
        foreach ($items as $item) {
            //percentage
            $percCounter += 1;
            if (@($percCounter % $percTen) == 0) {
                $perc = round(( 100 * $percCounter ) / $percTotal);
                $message = $perc . '% ' . JText::_('COM_SPTRANSFER_MSG_PROCESSED') . '<br/>';
                $factory->writeLog($message);
            }

            //add extra coding
            $this->tableLog = $tableLog;
            switch ($task->extension_name . '_' . $task->name) {
                case 'com_users_usergroups':
                    $item = $this->com_users_usergroups_fix($item);
                    break;
                case 'com_users_viewlevels':
                    $item = $this->com_users_viewlevels_fix($item);
                    break;
                case 'com_users_users':
                    $item = $this->com_users_users_fix($item);
                    break;
                case 'com_banners_banners':
                    $item = $this->com_banners_banners_fix($item);
                    break;
                case 'com_menus_menu':
                    $item = $this->com_menus_menu_fix($item);
                    break;
                case 'com_modules_modules':
                    $this->com_modules_modules_fix($item);
                    break;
            }

            // Set destination_id
            //created_by
            if ($item['created_by'] > 0) {
                $tableLog->load(array("tables_id" => 3, "source_id" => $item['created_by']));
                if ($tableLog->source_id != $tableLog->destination_id) {
                    $item['created_by'] = $tableLog->destination_id;
                }
            }

            //modified_by
            /*
              if ($item['modified_by'] > 0) {
              $tableLog->load(array("tables_id" => 3, "source_id" => $item['modified_by']));
              if ($tableLog->source_id != $tableLog->destination_id) {
              $item['modified_by'] = $tableLog->destination_id;
              }
              }
             * 
             */

            //catid
            if ($item['catid'] > 1) {

                $tableLog->reset();
                $tableLog->id = null;
                $tableLog->load(array("tables_id" => $this->task->category, "source_id" => $item['catid']));
                if ($tableLog->source_id == $tableLog->destination_id) {
                    $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
                    $tableLog->state = 4;
                    $tableLog->store();
                    continue;
                }
                $item['catid'] = $tableLog->destination_id;
            } /*else {
                $tableLog->reset();
                $tableLog->id = null;
                $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
                $tableLog->state = 4;
                $tableLog->store();
                continue;
            }
             * 
             */

            //log            
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
            $tableLog->created = null;
            $tableLog->state = 3;
            $tableLog->tables_id = $task->id;

            // Reset
            $destination_table->reset();

            // Bind
            if (!$destination_table->bind($item)) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_BIND', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            // Store
            if (!$destination_table->store()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_STORE', $item['id'], $destination_table->getError()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }

            //Log
            $tableLog->state = 4;
            $tableLog->store();
        } //Main loop end   
    }

    private function com_users_users() {
        $tableLog = $this->tableLog;
        $factory = $this->factory;
        $source_db = $this->source_db;
        $destination_db = $this->destination_db;

        // User Usergroup Map
        $query = 'SELECT group_id'
                . ' FROM #__user_usergroup_map '
                . ' WHERE user_id = ' . (int) $tableLog->source_id
        ;
        $source_db->setQuery($query);
        $source_db->query();
        $group_ids = $source_db->loadResultArray();
        foreach ($group_ids as $group_id) {
            $query = "INSERT INTO #__user_usergroup_map" .
                    " (user_id,group_id)" .
                    " VALUES (" . $destination_db->quote($tableLog->destination_id) . ',' . $destination_db->quote($group_id) . ")";
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $tableLog->source_id, $destination_db->getErrorMsg()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }
        }

        // User Profiles
        $query = 'SELECT *'
                . ' FROM #__user_profiles '
                . ' WHERE user_id = ' . (int) $tableLog->source_id
        ;
        $source_db->setQuery($query);
        $source_db->query();
        $profiles = $source_db->loadObjectList();
        foreach ($profiles as $profile) {
            $query = "INSERT INTO #__user_profiles" .
                    " (user_id,profile_key,profile_value,ordering)" .
                    " VALUES (" . $destination_db->quote($profile->user_id) .
                    ',' . $destination_db->quote($profile->profile_key) .
                    ',' . $destination_db->quote($profile->profile_value) .
                    ',' . $destination_db->quote($profile->ordering) .
                    ")";
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $tableLog->source_id, $destination_db->getErrorMsg()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }
        }
    }
    
    private function com_users_usergroups_fix($item) {
        $tableLog = $this->tableLog;

        //parent_id
        if ($item['parent_id'] > 0) {
            $tableLog->load(array("tables_id" => $this->task->id, "source_id" => $item['parent_id']));
            if ($tableLog->source_id != $tableLog->destination_id) {
                $item['parent_id'] = $tableLog->destination_id;
            }
        }
        return $item;
    }

    private function com_users_users_fix($item) {
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        $source_db = $this->source_db;
        $factory = $this->factory;
        $task = $this->task;

        // check for existing username
        $query = 'SELECT id'
                . ' FROM #__users '
                . ' WHERE username = ' . $destination_db->Quote($item['username'])
                . ' AND id != ' . (int) $item['id'];
        $destination_db->setQuery($query);
        $xid = intval($destination_db->loadResult());
        if ($xid && $xid != intval($item['id'])) {
            $item['username'] .= '-sp-' . rand();
            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_DUPLICATE_USERNAME', $item['id'], $item['username']) . '</p>';
            $factory->writeLog($message);
            $tableLog->note = $message;
            $query = "UPDATE #__users";
            $query .= " SET ";
            foreach ($item as $key => $value) {
                $query .= $destination_db->quoteName($key) . "=" . $destination_db->quote($value) . ",";
            }
            $query = chop($query, ",");
            $query .= " WHERE `id` =" . (int) $item['id'];
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                // delete record
                $destination_db->setQuery(
                        "DELETE FROM #__users" .
                        " WHERE id = " . $destination_db->quote($item['id'])
                );
                if (!$destination_db->query()) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                    return;
                }
            }
        }

        // check for existing email
        $query = 'SELECT id'
                . ' FROM #__users '
                . ' WHERE email = ' . $destination_db->Quote($item['email'])
                . ' AND id != ' . (int) $item['id']
        ;
        $destination_db->setQuery($query);
        $xid = intval($destination_db->loadResult());
        if ($xid && $xid != intval($this->id)) {
            $item['email'] .= '-sp-' . rand();
            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_DUPLICATE_EMAIL', $item['id'], $item['email']) . '</p>';
            $factory->writeLog($message);
            $tableLog->note = $message;
            $query = "UPDATE #__users";
            $query .= " SET ";
            foreach ($item as $key => $value) {
                $query .= $destination_db->quoteName($key) . "=" . $destination_db->quote($value) . ",";
            }
            $query = chop($query, ",");
            $query .= " WHERE `id` =" . (int) $item['id'];
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                // delete record
                $destination_db->setQuery(
                        "DELETE FROM #__users" .
                        " WHERE id = " . $destination_db->quote($item['id'])
                );
                if (!$destination_db->query()) {
                    $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_DELETE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                    $factory->writeLog($message);
                    return;
                }
            }
        }

        //usergroups map
        $query = 'SELECT group_id'
                . ' FROM #__user_usergroup_map '
                . ' WHERE user_id = ' . (int) $item['id'];
        $destination_db->setQuery($query);
        $destination_db->query();
        $group_ids = $destination_db->loadResultArray();
        $query = 'DELETE FROM #__user_usergroup_map '
                . ' WHERE user_id = ' . (int) $item['id'];
        $destination_db->setQuery($query);
        $destination_db->query();        
        foreach ($group_ids as $group_id) {
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => 1, "source_id" => $group_id));
            $query = "INSERT INTO #__user_usergroup_map" .
                    " (user_id,group_id)" .
                    " VALUES (" . $destination_db->quote($item['id']) . ',' . $destination_db->quote($tableLog->destination_id) . ")";
            $destination_db->setQuery($query);
            $destination_db->query();
        }
        
        return $item;
    }

    private function com_users_viewlevels_fix($item) {
        $tableLog = $this->tableLog;

        $rules = json_decode($item['rules']);
        foreach ($rules as $k => $rule) {
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => 1, "source_id" => $rule));
            $rules2[$k] = (int) $tableLog->destination_id;
            if ($rules2[$k] == 0)
                $rules2[$k] = 1;
        }
        $item['rules'] = json_encode($rules2);

        return $item;
    }
    
    private function com_content_content() {
        $tableLog = $this->tableLog;
        $source_db = $this->source_db;
        $destination_db = $this->destination_db;

        //featured
        $query = 'SELECT *
                FROM #__content_frontpage
                WHERE content_id = ' . (int) $tableLog->source_id;
        $source_db->setQuery($query);
        $source_db->query();
        $result = $source_db->loadAssoc();
        if (!is_null($result)) {
            $destination_db->setQuery(
                    "INSERT INTO #__content_frontpage
                        (content_id, ordering)
                        VALUES (" . $tableLog->destination_id . " , " . $result['ordering'] . ")"
            );
            $destination_db->query();
        } else {
            $destination_db->setQuery(
                    "DELETE FROM #__content_frontpage
                        WHERE content_id = " . $destination_db->quote($tableLog->destination_id)
            );
            $destination_db->query();
        }

        //rating
        $query = 'SELECT *
                FROM #__content_rating
                WHERE content_id = ' . (int) $tableLog->source_id;
        $source_db->setQuery($query);
        $source_db->query();
        $result = $source_db->loadAssoc();
        if (!is_null($result)) {
            $destination_db->setQuery(
                    "INSERT INTO #__content_rating
                        (content_id, rating_sum, rating_count, lastip)
                        VALUES (" . $tableLog->destination_id . " , " . $result['rating_sum'] . " , " . $result['rating_count'] . " , '" . $result['lastip'] . "')"
            );
            $destination_db->query();
        }
    }

    private function com_banners_banners() {
        $tableLog = $this->tableLog;
        $source_db = $this->source_db;
        $destination_db = $this->destination_db;

        //banner tracks
        $query = 'SELECT *
                FROM #__banner_tracks
                WHERE banner_id = ' . (int) $tableLog->source_id;
        $source_db->setQuery($query);
        $source_db->query();
        $result = $source_db->loadAssoc();
        if (!is_null($result)) {
            $query = "INSERT INTO #__banner_tracks
                        (track_date, track_type, banner_id, count)
                        VALUES (" . $destination_db->quote($result['track_date']) . " , " .
                    $destination_db->quote($result['track_type']) . " , " .
                    $destination_db->quote($tableLog->destination_id) . " , " .
                    $destination_db->quote($result['count']) .
                    ")";
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $tableLog->source_id, $destination_db->getErrorMsg()) . '</p>';
                $this->factory->writeLog($message);
            }
        }
    }

    private function com_banners_banners_fix($item) {
        $tableLog = $this->tableLog;

        //cid
        if ($item['cid'] > 0) {
            $tableLog->load(array("tables_id" => 13, "source_id" => $item['cid']));
            if ($tableLog->source_id != $tableLog->destination_id) {
                $item['cid'] = $tableLog->destination_id;
            }
        }
        return $item;
    }

    private function com_menus_menu_fix($item) {
        $tableLog = $this->tableLog;
        $destination_db = $this->destination_db;
        $source_db = $this->source_db;
        $task = $this->task;

        //menutype
        $menutype_table = $this->factory->getTable('MenuType', 'JTable');
        $menutype_table->load(array("menutype" => $item['menutype']));
        if (!is_null($menutype_table->id)) {
            $query = 'SELECT menutype FROM #__menu_types WHERE menutype LIKE "' . $item['menutype'] . '-sp-%"';
            $destination_db->setQuery($query);
            $destination_db->query();
            $item['menutype'] = $destination_db->loadResult();
        }

        //component_id
        $query = "SELECT component_id FROM #__menu WHERE id = " . (int) $item['id'];
        $destination_db->setQuery($query);
        $destination_db->query();
        $extension_id = $destination_db->loadResult();
        $query = "SELECT name FROM #__extensions WHERE extension_id = " . (int) $extension_id;
        $source_db->setQuery($query);
        $source_db->query();
        $name = $source_db->loadResult();
        $query = 'SELECT extension_id FROM #__extensions WHERE name LIKE "' . $name . '"';
        $destination_db->setQuery($query);
        $destination_db->query();
        $item['component_id'] = $destination_db->loadResult();

        //parent_id
        if ($item['parent_id'] > 1) {
            $tableLog->reset();
            $tableLog->id = null;
            $tableLog->load(array("tables_id" => $task->id, "source_id" => $item['parent_id']));
            $item['parent_id'] = $tableLog->destination_id;
        }
        
        //link
        $link_1 = preg_split('/[&=]/',str_replace('index.php?', '', $item['link']));
        foreach ($link_1 as $key => $value) {          
            if ($key % 2 == 0) {
              $link[$value] = $link_1[$key + 1];
            }            
        }


        $query = 'SELECT id FROM #__sptransfer_tables'.
                ' WHERE extension_name LIKE '.$destination_db->quote($link['option']);
        if ( ($link['view'] == 'category') || ($link['view'] == 'categories') ) {
            $query .= " AND name LIKE 'categories'";
        } else {
            $query .= " AND name  NOT LIKE 'categories'";
        }
        $destination_db->setQuery($query);
        $destination_db->query();
        $table_id = $destination_db->loadResult();
        $tableLog->reset();
        $tableLog->id = null;
        $tableLog->load(array("tables_id" => $table_id, "source_id" => $link['id']));
        $item['link'] = str_replace('id='.$link['id'], 'id='.$tableLog->destination_id, $item['link']);

        return $item;
    }

    private function com_modules_modules($item) {
        $destination_db = $this->destination_db;
        $tableLog = $this->tableLog;
        $source_db = $this->source_db;
        $factory = $this->factory;

        // Modules_Menu
        //First delete
        $destination_db->setQuery(
                "DELETE FROM #__modules_menu
                    WHERE moduleid = " . $destination_db->quote($tableLog->destination_id)
        );
        $destination_db->query();
        //Then insert
        $query = 'SELECT *'
                . ' FROM #__modules_menu '
                . ' WHERE moduleid = ' . (int) $tableLog->source_id
        ;
        $source_db->setQuery($query);
        $source_db->query();
        $modules_menus = $source_db->loadAssocList();
        foreach ($modules_menus as $modules_menu) {
            $query = "INSERT INTO #__modules_menu" .
                    " (moduleid,menuid)" .
                    " VALUES (" . $destination_db->quote($tableLog->destination_id) . ',' . $destination_db->quote($modules_menu['menuid']) . ")";
            $destination_db->setQuery($query);
            if (!$destination_db->query()) {
                $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_CREATE', $item['id'], $destination_db->getErrorMsg()) . '</p>';
                $factory->writeLog($message);
                $tableLog->note = $message;
                $tableLog->store();
                continue;
            }
        }
    }

    private function com_modules_modules_fix($item) {              
        $destination_db = $this->destination_db;
        $source_db = $this->source_db;
        $tableLog = $this->tableLog;
        $factory = $this->factory;
        $task = $this->task;

        // Set destination_id
        $tableLog->reset();
        $tableLog->id = null;
        $tableLog->load(array("tables_id" => 16, "source_id" => $item['menuid']));
        $item['menuid'] = $tableLog->destination_id;
        $menuid = $tableLog->source_id;
        if ($tableLog->source_id == $tableLog->destination_id) {
            $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
            $tableLog->state = 4;
            $tableLog->store();
            return;
        }

        //log            
        $tableLog->reset();
        $tableLog->id = null;
        $tableLog->load(array("tables_id" => $task->id, "destination_id" => $item['id']));
        $tableLog->created = null;
        $tableLog->state = 3;
        $tableLog->tables_id = $task->id;

        // update
        $query = 'UPDATE #__modules_menu '
                . ' SET menuid = ' . (int) $item['menuid']
                . ' WHERE moduleid = ' . (int) $tableLog->destination_id
                . ' AND menuid = ' . (int) $menuid;
        ;
        $destination_db->setQuery($query);
        $destination_db->query();
        $source_db->loadResult();
        if (!$destination_db->query()) {
            $message = '<p>' . JText::sprintf('COM_SPTRANSFER_MSG_ERROR_UPDATE', $item['user_id'], $destination_db->getErrorMsg()) . '</p>';
            $factory->writeLog($message);
            $tableLog->note = $message;
            $tableLog->store();
            return;
        }
    }

}
