%PDF- %PDF-
| Direktori : /home1/lightco1/www/plugins/csviaddon/csvi/com_csvi/model/ |
| Current File : //home1/lightco1/www/plugins/csviaddon/csvi/com_csvi/model/maintenance.php |
<?php
/**
* @package CSVI
* @subpackage Maintenance
*
* @author Roland Dalmulder <contact@csvimproved.com>
* @copyright Copyright (C) 2006 - 2016 RolandD Cyber Produksi. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
* @link http://www.csvimproved.com
*/
defined('_JEXEC') or die;
/**
* Performs CSVI specific maintenance operations.
*
* @package CSVI
* @subpackage Maintenace
* @since 6.0
*/
class Com_CsviMaintenance
{
/**
* Database connector
*
* @var JDatabaseDriver
* @since 6.0
*/
private $db = null;
/**
* Logger helper
*
* @var CsviHelperLog
* @since 6.0
*/
private $log = null;
/**
* CSVI Helper.
*
* @var CsviHelperCsvi
* @since 6.0
*/
private $csvihelper = null;
/**
* Key tracker
*
* @var int
* @since 6.0
*/
private $key = 0;
/**
* Hold the message to show on a JSON run
*
* @var string
* @since 6.0
*/
private $message = '';
/**
* Set if we are running in CLI mode
*
* @var bool
* @since 6.0
*/
private $isCli = false;
/**
* Set download file
*
* @var bool
* @since 6.6.0
*/
private $downloadfile = '';
/**
* Constructor.
*
* @param JDatabaseDriver $db Joomla Database connector
* @param CsviHelperLog $log An instance of CsviHelperLog
* @param CsviHelperCsvi $csvihelper An instance of CsviHelperCsvi
* @param bool $isCli Set if we are running CLI mode
*
* @since 6.0
*/
public function __construct(JDatabaseDriver $db, CsviHelperLog $log, CsviHelperCsvi $csvihelper, $isCli = false)
{
// Load the database class
$this->db = $db;
$this->log = $log;
$this->csvihelper = $csvihelper;
$this->isCli = $isCli;
}
/**
* Load a number of maintenance tasks.
*
* @return array The list of available tasks.
*
* @since 6.0
*/
public function getOperations()
{
return array('options' => array(
'' => JText::_('COM_CSVI_MAKE_CHOICE'),
'loadpatch' => JText::_('COM_CSVI_PATCH_FILE_LABEL'),
'updateavailablefields' => JText::_('COM_CSVI_UPDATEAVAILABLEFIELDS_LABEL'),
'cleantemp' => JText::_('COM_CSVI_CLEANTEMP_LABEL'),
'icecatindex' => JText::_('COM_CSVI_ICECATINDEX_LABEL'),
'backuptemplates' => JText::_('COM_CSVI_BACKUPTEMPLATES_LABEL'),
'restoretemplates' => JText::_('COM_CSVI_RESTORETEMPLATES_LABEL'),
'exampletemplates' => JText::_('COM_CSVI_EXAMPLETEMPLATES_LABEL'),
'optimizetables' => JText::_('COM_CSVI_OPTIMIZETABLES_LABEL'),
'deletetables' => JText::_('COM_CSVI_DELETETABLES_LABEL')
)
);
}
/**
* Load the options for a selected operation.
*
* @param string $operation The operation to get the options for
*
* @return string the options for a selected operation.
*
* @since 6.0
*/
public function getOptions($operation)
{
switch ($operation)
{
case 'loadpatch':
return '
<div class="control-group">
<label for="template_name" class="control-label ">
' . JText::_('COM_CSVI_CHOOSE_PATCH_FILE_LABEL') . '
</label>
<div class="controls">
<input type="file" name="form[patch_file]" id="file" class="span5" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_CHOOSE_PATCH_FILE_DESC') . '</span>
</div>
</div>';
break;
case 'updateavailablefields':
return '<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_UPDATE_AVAILABLEFIELDS_DESC') . '</span>';
break;
case 'cleantemp':
return '<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_CLEANTEMP_DESC') . '</span>';
break;
case 'backuptemplates':
$html = '<div class="control-group ">
<label class="control-label" for="exportto">
' . JText::_('COM_CSVI_JFORM_EXPORTTO_LABEL') . '
</label>
<div class="controls">
<select id="jform_exportto" name="form[exportto]" onchange="Csvi.showExportSource(this.value)">
<option value="todownload" selected="selected">' . JText::_('COM_CSVI_EXPORT_TO_DOWNLOAD_LABEL') . '</option>
<option value="tofile">' . JText::_('COM_CSVI_EXPORT_TO_LOCAL_LABEL') . '</option>
</select>
</div>
</div>
<div class="control-group" id="localfield" style="display:none">
<label for="template_name" class="control-label ">
' . JText::_('COM_CSVI_CHOOSE_BACKUP_LOCATION_LABEL') . '
</label>
<div class="controls">
<input type="text" name="backup_location" id="backup_location" value="' . JPATH_SITE . '/tmp/com_csvi" class="input-xxlarge" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_CHOOSE_BACKUP_LOCATION_DESC') . '</span>
</div>
</div>';
// Load the list of templates
/** @var CsviModelTemplates $templateModel */
$templateModel = JModelLegacy::getInstance('Templates', 'CsviModel');
$templates = $templateModel->getTemplates();
$html .= '<div class="control-group">
<label for="template_name" class="control-label ">
' . JText::_('COM_CSVI_BACKUPTEMPLATES_LABEL') . '
</label>
<div class="controls">
<input
type="checkbox"
onclick="Joomla.checkAll(this)"
checked="checked"
title="' . JText::_('COM_CSVI_CHECK_ALL_FIELDS') . '"
value=""
name="checkall-toggle"
/> '
. JText::_('COM_CSVI_CHECK_ALL_FIELDS') . '
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_BACKUPTEMPLATES_DESC') . '</span>
</div>
</div>
<div class="span12">';
foreach ($templates as $key => $template)
{
if ($key > 0)
{
if (empty($template->value))
{
if ($key > 1)
{
$html .= '</ul></div>';
}
$html .= '<div class="span5"><label>' . $template->text . '</label>
<ul class="unstyled">';
}
else
{
$html .= '
<li>
<label>
<input type="checkbox" checked="checked" name="form[templates][]" id="cb' . $key . '" value="' . $template->value . '" />
' . $template->text . '
</label>' .
'</li>';
}
}
}
$html .= '</div>';
return $html;
break;
case 'restoretemplates':
return '
<div class="control-group">
<label for="template_name" class="control-label ">
' . JText::_('COM_CSVI_CHOOSE_RESTORE_FILE_LABEL') . '
</label>
<div class="controls">
<input type="file" name="form[restore_file]" id="file" class="span5" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_CHOOSE_RESTORE_FILE_DESC') . '</span>
</div>
</div>';
break;
case 'icecatindex':
$html = '
<div class="span12">
<h3>' . JText::_('COM_CSVI_MAINTENANCE_ICECAT') . '</h3>
<div class="control-group">
<label class="control-label" for="icecatlocation">
' . JText::_('COM_CSVI_ICECAT_LOCATION_LABEL') . '
</label>
<div class="controls">
<input type="text" id="icecatlocation" name="form[icecatlocation]" value="' . CSVIPATH_TMP . '" class="input-xxlarge" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_LOCATION_DESC') . '</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="form_icecat_gzip">
' . JText::_('COM_CSVI_ICECAT_GZIP_LABEL') . '
</label>
<div class="controls">
' . JHtml::_('select.booleanlist', 'form[icecat_gzip]', '', 1) . '
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_GZIP_DESC') . '</span>
</div>
</div>
<div>
<div class="span12">
<h3>' . JText::_('COM_CSVI_MAINTENANCE_ICECAT_FILE') . '</h3>
<div class="control-group">
<label class="control-label" for="icecatfile">
' . JText::_('COM_CSVI_ICECAT_FILE_LABEL') . '
</label>
<div class="controls">
<input type="checkbox" id="icecatfile" name="form[icecat][]" value="icecat_index" checked="checked" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_FILE_DESC') . '</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="form_loadtype">
' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_LABEL') . '
</label>
<div class="controls">
' . JHtml::_('select.booleanlist', 'form[loadtype]', '', 0, JText::_('COM_CSVI_ICECAT_FILE_SINGLE'), JText::_('COM_CSVI_ICECAT_FILE_FULL')) . '
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_DESC') . '</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="icecat_records">
' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_RECORDS_LABEL') . '
</label>
<div class="controls">
<input type="text" id="icecat_records" name="form[icecat_records]" value="1000" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_RECORDS_DESC') . '</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="icecat_wait">
' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_WAIT_LABEL') . '
</label>
<div class="controls">
<input type="text" id="icecat_wait" name="form[icecat_wait]" value="5" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_FILE_LOAD_WAIT_DESC') . '</span>
</div>
</div>
<div>
<div class="span12">
<h3>' . JText::_('COM_CSVI_MAINTENANCE_ICECAT_SUPPLIER') . '</h3>
<div class="control-group">
<label class="control-label" for="icecat_supplier">
' . JText::_('COM_CSVI_ICECAT_SUPPLIER_LABEL') . '
</label>
<div class="controls">
<input type="checkbox" id="icecat_supplier" name="form[icecat][]" value="icecat_supplier" checked="checked" />
<span class="help-block" style="display: none;">' . JText::_('COM_CSVI_ICECAT_SUPPLIER_DESC') . '</span>
</div>
</div>
<div>';
return $html;
break;
case 'deletetables':
$layout = new JLayoutFile('csvi.modal');
return $layout->render(
array(
'modal-header' => JText::_('COM_CSVI_' . $operation . '_LABEL'),
'modal-body' => JText::_('COM_CSVI_CONFIRM_TABLES_DELETE'),
'cancel-button' => true
)
);
break;
case 'optimizetables':
return JText::_('COM_CSVI_OPTIMIZETABLES_DESC');
break;
case 'exampletemplates':
return JText::_('COM_CSVI_EXAMPLETEMPLATES_DESC');
break;
default:
return '';
break;
}
}
/**
* Optimize all database tables.
*
* @param FOFInput $input The input model
* @param mixed $key A reference used by the method.
*
* @return bool Always returns true.
*
* @since 6.0
*/
public function optimizeTables(FOFInput $input, $key)
{
// Get the list of tables to optimize
$tables = $this->db->getTableList();
if ($this->isCli)
{
foreach ($tables as $table)
{
// Increment log linecounter
$this->log->incrementLinenumber();
$this->optimizeTable($table);
}
}
else
{
if (isset($tables[$key]))
{
// Increment log linecounter
$this->log->incrementLinenumber();
if ($this->optimizeTable($tables[$key]))
{
$this->message = JText::sprintf('COM_CSVI_TABLE_HAS_BEEN_OPTIMIZED', $tables[$key]);
}
else
{
$this->message = JText::sprintf('COM_CSVI_TABLE_HAS_NOT_BEEN_OPTIMIZED', $tables[$key]);
}
// Set the key for post processing
$key++;
$this->key = $key;
}
else
{
$this->key = false;
}
}
return true;
}
/**
* Optimize a table.
*
* @param string $table The name of the table to optimize
*
* @return bool True on success | False on failure.
*
* @since 6.0
*/
private function optimizeTable($table)
{
// Build the query
$q = 'OPTIMIZE TABLE ' . $this->db->quoteName($table);
$this->db->setQuery($q);
// Execute query
if ($this->db->execute())
{
$this->log->addStats('information', JText::sprintf('COM_CSVI_TABLE_HAS_BEEN_OPTIMIZED', $table), $table);
return true;
}
else
{
$this->log->addStats('incorrect', JText::sprintf('COM_CSVI_TABLE_HAS_NOT_BEEN_OPTIMIZED', $table), $table);
return false;
}
}
/**
* Post processing optimize tables.
*
* @return array Settings for continuing.
*
* @since 6.0
*/
public function onAfteroptimizeTables()
{
if ($this->key)
{
// Return data
$results = array();
$results['continue'] = true;
$results['key'] = $this->key;
}
else
{
$results['continue'] = false;
}
$results['info'] = $this->message;
return $results;
}
/**
* Update available fields.
*
* @param FOFInput $input The input model
* @param mixed $key A reference used by the method.
*
* @return bool True on success, false on failure.
*
* @since 3.3
*
* @throws \RuntimeException
*/
public function updateAvailableFields(FOFInput $input, $key)
{
$result = false;
// Check if we need to prepare the available fields
if ($key === 0)
{
$this->prepareAvailableFields();
}
// Check if we are running a cron job
list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
if ($isCli)
{
$continue = true;
while ($continue)
{
$result = $this->indexAvailableFields();
$continue = $input->get('continue');
}
}
else
{
$result = $this->indexAvailableFields();
}
return $result;
}
/**
* Prepare for available fields importing.
*
* 1. Set all tables to be indexed
* 2. Empty the available fields table
* 3. Import the extra availablefields sql file
* 4. Find what tables need to be imported and store them in the session.
*
* @return void.
*
* @since 3.5
*
* @throws \RuntimeException
*/
private function prepareAvailableFields()
{
// Set all tables to be indexed
$query = $this->db->getQuery(true)
->update($this->db->quoteName('#__csvi_availabletables'))
->set($this->db->quoteName('indexed') . ' = 0');
$this->db->setQuery($query)->execute();
// Drop the available fields first
try
{
// Delete the table
$this->db->dropTable('#__csvi_availablefields');
$this->log->addStats('delete', 'COM_CSVI_AVAILABLE_FIELDS_TABLE_DELETED', 'availablefields');
// Create table again so index is proper
if ($this->createAvailableFieldsTable())
{
// Index the custom tables used in CSVI import/export
$this->indexCustomTables();
// Do component specific updates
$override = new stdClass;
$override->value = 'custom';
$components = $this->csvihelper->getComponents();
$components[] = $override;
jimport('joomla.filesystem.file');
foreach ($components as $component)
{
// Load any component specific file
if ($component->value
&& $component->value !== 'com_csvi'
&& $component->value !== 'custom'
&& file_exists(JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/model/maintenance.php'))
{
require_once JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/model/maintenance.php';
$extensionClassname = ucfirst($component->value) . 'Maintenance';
$extensionModel = new $extensionClassname($this->db, $this->log, $this->csvihelper);
if (method_exists($extensionModel, 'updateAvailableFields'))
{
$extensionModel->updateAvailableFields();
}
}
// Process all extra available fields
$filename = JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/install/availablefields.sql';
if (JFile::exists($filename))
{
// Check if the component is installed
$ext_id = true;
if (0 === strpos($component->value, 'com_'))
{
$query = $this->db->getQuery(true)
->select($this->db->quoteName('extension_id'))
->from($this->db->quoteName('#__extensions'))
->where($this->db->quoteName('element') . ' = ' . $this->db->quote($component->value));
$this->db->setQuery($query);
$ext_id = $this->db->loadResult();
}
if ($ext_id)
{
// Increment line number
$this->log->incrementLinenumber();
$queries = JDatabaseDriver::splitSql(file_get_contents($filename));
foreach ($queries as $step => $splitQuery)
{
// Clean the string of any trailing whitespace
$splitQuery = trim($splitQuery);
if ($splitQuery)
{
$this->db->setQuery($splitQuery);
if ($this->db->execute())
{
$this->log->addStats(
'added',
JText::sprintf('COM_CSVI_CUSTOM_AVAILABLE_FIELDS_HAVE_BEEN_ADDED', JText::_('COM_CSVI_' . $component->value), $step + 1),
$component->value . '_CUSTOM'
);
}
else
{
$this->log->add(
'incorrect',
JText::sprintf('COM_CSVI_CUSTOM_AVAILABLE_FIELDS_HAVE_NOT_BEEN_ADDED', JText::_('COM_CSVI_' . $component->value), $step + 1, $splitQuery),
$component->value . '_CUSTOM'
);
}
}
}
// Execute any specific available fields that are not in an SQL file
if (file_exists(JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/model/maintenance.php'))
{
require_once JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/model/maintenance.php';
$classname = $component->value . 'Maintenance';
$addon = new $classname($this->db, $this->log, $this->csvihelper);
if (method_exists($addon, 'customAvailableFields'))
{
$addon->customAvailableFields();
}
}
}
}
}
// Increment line number
$this->log->decrementLinenumber();
}
}
catch (Exception $e)
{
$this->log->addStats('error', $e->getMessage(), 'availablefields');
}
}
/**
* Process the custom tables for import/export.
*
* @return void.
*
* @since 6.5.6
*
* @throws \RuntimeException
*/
private function indexCustomTables()
{
// Add the custom fields for each specific custom table in use
$query = $this->db->getQuery(true)
->select($this->db->quoteName('template_table'))
->from($this->db->quoteName('#__csvi_availabletables'))
->where($this->db->quoteName('task_name') . ' = ' . $this->db->quote('custom'))
->where($this->db->quoteName('component') . ' = ' . $this->db->quote('com_csvi'))
->where($this->db->quoteName('action') . ' = ' . $this->db->quote('import'));
$this->db->setQuery($query);
$importTables = $this->db->loadColumn();
$query->clear('where')
->where($this->db->quoteName('task_name') . ' = ' . $this->db->quote('custom'))
->where($this->db->quoteName('component') . ' = ' . $this->db->quote('com_csvi'))
->where($this->db->quoteName('action') . ' = ' . $this->db->quote('export'));
$this->db->setQuery($query);
$exportTables = $this->db->loadColumn();
$query = 'INSERT IGNORE INTO ' . $this->db->quoteName('#__csvi_availablefields')
. '(' . $this->db->quoteName('csvi_name') . ', '
. $this->db->quoteName('component_name') . ', '
. $this->db->quoteName('component_table') . ', '
. $this->db->quoteName('component') . ', '
. $this->db->quoteName('action') . ')';
$customFields = array();
foreach ($importTables as $importTable)
{
// Add the custom available fields for each import table
$customFields[] = '(' . $this->db->quote('skip') . ', '
. $this->db->quote('skip') . ', '
. $this->db->quote($importTable) . ', '
. $this->db->quote('com_csvi') . ', '
. $this->db->quote('import') . ')';
$customFields[] = '(' . $this->db->quote('combine') . ', '
. $this->db->quote('combine') . ', '
. $this->db->quote($importTable) . ', '
. $this->db->quote('com_csvi') . ', '
. $this->db->quote('import') . ')';
}
foreach ($exportTables as $exportTable)
{
// Add the custom available fields for each export table
$customFields[] = '(' . $this->db->quote('custom') . ', '
. $this->db->quote('custom') . ', '
. $this->db->quote($exportTable) . ', '
. $this->db->quote('com_csvi') . ', '
. $this->db->quote('export') . ')';
}
if (0 !== count($customFields))
{
$query .= ' VALUES ' . implode(', ', $customFields);
$this->db->setQuery($query)->execute();
}
}
/**
* Import the available fields in steps.
*
* @return bool True on success | False on failure.
*
* @since 3.5
*
* @throws \RuntimeException
*/
private function indexAvailableFields()
{
// Load the session data
$lines = $this->log->getLinenumber();
$lines++;
// Set the line number
$this->log->setLinenumber($lines);
$query = $this->db->getQuery(true);
$query->select(
$this->db->quoteName('csvi_availabletable_id') . ',' .
$this->db->quoteName('template_table') . ',' .
$this->db->quoteName('component') . ',' .
$this->db->quoteName('action')
)
->from($this->db->quoteName('#__csvi_availabletables'))
->where($this->db->quoteName('indexed') . ' = 0')
->where($this->db->quoteName('enabled') . ' = 1')
->group($this->db->quoteName('template_table'));
$this->db->setQuery($query, 0, 1);
$table = $this->db->loadObject();
if (is_object($table))
{
// Set the key that we started
$this->key = 1;
// Check if the table exists
$tables = $this->db->getTableList();
if (in_array($this->db->getPrefix() . $table->template_table, $tables, true))
{
// Increment line number
$this->log->incrementLinenumber();
$this->indexTable($table);
}
else
{
$this->message = $table->template_table . ' not an available table';
}
// Set the table to indexed
$query = $this->db->getQuery(true);
$query->update($this->db->quoteName('#__csvi_availabletables'))
->set($this->db->quoteName('indexed') . ' = 1')
->where($this->db->quoteName('csvi_availabletable_id') . ' = ' . (int) $table->csvi_availabletable_id);
$this->db->setQuery($query);
$this->db->execute();
}
else
{
$this->key = false;
}
return true;
}
/**
* Creates an array of custom database fields the user can use for import/export.
*
* @param string $table The table name to get the fields for
* @param bool $addname Add the table name to the list of fields
*
* @return array List of custom database fields.
*
* @since 3.0
*/
private function dbFields($table, $addname=false)
{
$customfields = array();
$q = 'SHOW COLUMNS FROM ' . $this->db->quoteName('#__' . $table);
$this->db->setQuery($q);
$fields = $this->db->loadObjectList();
if (count($fields) > 0)
{
foreach ($fields as $field)
{
if ($addname)
{
$customfields[$field->Field] = $table;
}
else
{
$customfields[$field->Field] = null;
}
}
}
return $customfields;
}
/**
* Index a single table.
*
* @param object $table The table to index
*
* @return void.
*
* @since 6.0
*
* @throws \RuntimeException
*/
public function indexTable($table)
{
// Get the primary key for the table
$primaryKey = $this->csvihelper->getPrimaryKey($table->template_table);
// Load the language
$this->csvihelper->loadLanguage($table->component, false);
$fields = $this->dbFields($table->template_table, true);
if (is_array($fields))
{
// Process all fields
foreach ($fields as $name => $value)
{
// Check if the field is a primary field
$primary = 0;
if ($primaryKey === $name)
{
$primary = 1;
}
if ($name)
{
$q = 'INSERT IGNORE INTO ' . $this->db->quoteName('#__csvi_availablefields') . ' VALUES ('
. '0,'
. $this->db->quote($name) . ','
. $this->db->quote($name) . ','
. $this->db->quote($value) . ','
. $this->db->quote($table->component) . ','
. $this->db->quote($table->action) . ','
. $this->db->quote($primary) . ')';
$this->db->setQuery($q);
if ($this->db->execute())
{
$this->log->addStats(
'added',
JText::sprintf('COM_CSVI_AVAILABLE_FIELDS_HAVE_BEEN_ADDED', $table->template_table),
'maintenance_index_availablefields'
);
$this->message = JText::sprintf('COM_CSVI_AVAILABLE_FIELDS_HAVE_BEEN_ADDED', $table->template_table);
}
else
{
$this->log->addStats('error', 'COM_CSVI_AVAILABLE_FIELDS_HAVE_NOT_BEEN_ADDED', 'maintenance_index_availablefields');
$this->message = $this->db->getErrorMsg();
}
}
}
}
}
/**
* This is called after the available fields have been updated for post-processing.
*
* @return bool Always true.
*
* @since 6.0
*/
public function onAfterUpdateAvailableFields()
{
if ($this->key)
{
// Return data
$results = array();
$results['continue'] = true;
$results['key'] = $this->key;
}
else
{
$results['continue'] = false;
}
$results['info'] = $this->message;
return $results;
}
/**
* Load a patch provided by the forum.
*
* @param FOFInput $input The FOFInput class.
*
* @return bool True on success, false on failure.
*
* throws RuntimeException
*
* @since 5.6
*/
public function loadPatch(FOFInput $input)
{
// Load the necessary libraries
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.archive');
clearstatcache();
// Get the uploaded details
$upload = $input->get('patch_file', false);
// Check if the file upload has an error
if (empty($upload))
{
$this->log->addStats('incorrect', 'COM_CSVI_NO_UPLOADED_FILE_PROVIDED', 'maintenance');
return false;
}
elseif ($upload['error'] == 0)
{
// Get some basic info
$folder = CSVIPATH_TMP . '/patch/' . time();
// Create the temp folder
if (JFolder::create($folder))
{
// Move the uploaded file to its temp location
if (JFile::copy($upload['tmp_name'], $folder . '/' . $upload['name']))
{
// Remove the temporary file
JFile::delete($upload['tmp_name']);
// Unpack the archive
if (JArchive::extract($folder . '/' . $upload['name'], $folder))
{
// File is unpacked, remove the zip file so it won't get processed
JFile::delete($folder . '/' . $upload['name']);
// File is unpacked, let's process the folder
if ($this->processFolder($folder, $folder))
{
// All good remove tempory folder
JFolder::delete($folder);
return true;
}
}
else
{
$this->log->addStats('incorrect', 'COM_CSVI_CANNOT_UNPACK_UPLOADED_FILE', 'maintenance');
throw new RuntimeException(JText::_('COM_CSVI_CANNOT_UNPACK_UPLOADED_FILE'));
}
}
}
else
{
$this->log->addStats('incorrect', JText::sprintf('COM_CSVI_CANNOT_CREATE_UNPACK_FOLDER', $folder), 'maintenance');
throw new RuntimeException(JText::sprintf('COM_CSVI_CANNOT_CREATE_UNPACK_FOLDER', $folder));
}
}
else
{
// There was a problem uploading the file
switch ($upload['error'])
{
case '1':
$this->log->addStats('incorrect', 'COM_CSVI_THE_UPLOADED_FILE_EXCEEDS_THE_MAXIMUM_UPLOADED_FILE_SIZE', 'maintenance');
break;
case '2':
$this->log->addStats('incorrect', 'COM_CSVI_THE_UPLOADED_FILE_EXCEEDS_THE_MAXIMUM_UPLOADED_FILE_SIZE', 'maintenance');
break;
case '3':
$this->log->addStats('incorrect', 'COM_CSVI_THE_UPLOADED_FILE_WAS_ONLY_PARTIALLY_UPLOADED', 'maintenance');
break;
case '4':
$this->log->addStats('incorrect', 'COM_CSVI_NO_FILE_WAS_UPLOADED', 'maintenance');
break;
case '6':
$this->log->addStats('incorrect', 'COM_CSVI_MISSING_A_TEMPORARY_FOLDER', 'maintenance');
break;
case '7':
$this->log->addStats('incorrect', 'COM_CSVI_FAILED_TO_WRITE_FILE_TO_DISK', 'maintenance');
break;
case '8':
$this->log->addStats('incorrect', 'COM_CSVI_FILE_UPLOAD_STOPPED_BY_EXTENSION', 'maintenance');
break;
default:
$this->log->addStats('incorrect', 'COM_CSVI_THERE_WAS_A_PROBLEM_UPLOADING_THE_FILE', 'maintenance');
break;
}
throw new RuntimeException(JText::_('COM_CSVI_PATH_UPLOAD_ERROR'));
}
return true;
}
/**
* Walk through a folder to process all found files.
*
* @param string $folder The name of the folder to process
* @param string $base The base folder
*
* @return bool True on success, false on failure.
*
* @since 5.6
*/
private function processFolder($folder, $base = null)
{
$foundfiles = scandir($folder);
foreach ($foundfiles as $ffkey => $ffname)
{
$src = $folder . '/' . $ffname;
// Check if it is a folder
if (is_dir($src))
{
switch ($ffname)
{
case '.':
case '..':
break;
default:
$this->processFolder($src, $base);
break;
}
}
else
{
// Create the destination name
$destFile = str_ireplace($base, JPATH_SITE, $folder) . '/' . $ffname;
// Check if the destination file exists
if (file_exists($destFile))
{
JFile::move($destFile, $destFile . '.' . date('Ymd-His'));
}
// Copy the file to the destination location
if (JFile::copy($src, $destFile))
{
$this->log->addStats('added', JText::sprintf('COM_CSVI_COPY_PATCHFILE', $src, $destFile), 'maintenance');
}
else
{
$this->log->addStats('incorrect', JText::sprintf('COM_CSVI_CANT_COPY_PATCHFILE', $src, $destFile), 'maintenance');
}
}
}
return true;
}
/**
* Clean the CSVI cache.
*
* @return bool Always returns true.
*
* @since 3.0
*/
public function cleanTemp()
{
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
$folder = CSVIPATH_TMP;
if (JFolder::exists($folder))
{
// Delete all import files left behind in the folder
JFile::delete(JFolder::files($folder, '.', false, true));
// Delete all import folders left behind in the folder
$folders = JFolder::folders($folder, '.', true, true, array('debug', 'export'));
if (!empty($folders))
{
foreach ($folders as $path)
{
JFolder::delete($path);
}
}
// Empty the export folder
JFile::delete(JFolder::files($folder . '/export', '.', false, true));
// Load the files
if (JFolder::exists(CSVIPATH_DEBUG))
{
$files = JFolder::files(CSVIPATH_DEBUG, 'com_csvi', false, true);
if ($files)
{
// Set all directory separators in the same direction
foreach ($files as &$file)
{
$file = str_replace('\\', '/', $file);
}
// Remove any debug logs that are still there but not in the database
$query = $this->db->getQuery(true)
->select(
'CONCAT('
. $this->db->quote(CSVIPATH_DEBUG . '/com_csvi.log.')
. ', '
. $this->db->quoteName('csvi_log_id')
. ', '
. $this->db->quote('.php') . ') AS ' . $this->db->quoteName('filename')
)
->from($this->db->quoteName('#__csvi_logs'))
->order($this->db->quoteName('csvi_log_id'));
$this->db->setQuery($query);
$ids = $this->db->loadColumn();
if (!is_array($ids))
{
$ids = (array) $ids;
}
// Delete all obsolete files
JFile::delete(array_diff($files, $ids));
}
}
$this->log->addStats('delete', JText::sprintf('COM_CSVI_TEMP_CLEANED', $folder, CSVIPATH_DEBUG, $folder . '/export'), 'maintenance');
}
else
{
$this->log->addStats('information', JText::sprintf('COM_CSVI_TEMP_PATH_NOT_FOUND'), 'maintenance');
}
return true;
}
/**
* Backup selected templates.
*
* @param FOFInput $input FOFInput object
*
* @return bool Always true.
*
* @since 3.0
*
* @throws CsviException
* @throws RuntimeException
* @throws UnexpectedValueException
*/
public function backupTemplates(FOFInput $input)
{
$lineNumber = 1;
$ids = $input->get('templates', array(), 'array');
if (!$ids)
{
throw new CsviException(JText::_('COM_CSVI_NO_TEMPLATES_SELECTED'));
}
$xml = new DOMDocument;
$xml->formatOutput = true;
$csvi_element = $xml->createElement('csvi');
/** @var CsviModelTemplates $templateModel */
$templateModel = JModelLegacy::getInstance('Templates', 'CsviModel', array('ignore_request' => true));
$templates = $templateModel->getItems();
$ignoreFields = array('ftpusername', 'ftppass', 'urlusername', 'urlpass', 'secret');
foreach ($templates as $template)
{
$template = (array) $template;
if (in_array($template['csvi_template_id'], $ids, true))
{
// Create the template node
$xml_template = $xml->createElement('template');
// Add the settings
$template_settings = $xml->createElement('settings');
$settings = json_decode($template['settings']);
foreach ($settings as $name => $value)
{
if (in_array($name, $ignoreFields, true))
{
$value = '';
}
$ruleElement = $xml->createElement($name);
if (is_array($value))
{
foreach ($value as $key => $subValue)
{
$subElement = $xml->createElement('option');
$subElement->appendChild($xml->createCDATASection($subValue));
$ruleElement->appendChild($subElement);
}
}
else
{
// Convert 1/0 to yes/no so 0 wont become empty
switch ($value)
{
case '0':
$val = 'no';
break;
case '1':
$val = 'yes';
break;
default:
$val = $value;
break;
}
$ruleElement->appendChild($xml->createCDATASection($val));
}
$template_settings->appendChild($ruleElement);
}
// Add the settings to the XML
$xml_template->appendChild($template_settings);
// Array of fields to export
$nodes = array(
'template_name',
'advanced',
'action',
'frontend',
'secret',
'log',
'lastrun',
'enabled',
'ordering',
);
// Add all the template options
foreach ($nodes as $ruleNode)
{
if (in_array($ruleNode, $ignoreFields, true))
{
$template[$ruleNode] = '';
}
$ruleElement = $xml->createElement($ruleNode);
$ruleElement->appendChild($xml->createCDATASection($template[$ruleNode]));
$xml_template->appendChild($ruleElement);
}
// Add the fields for this template
$fieldsModel = JModelLegacy::getInstance('Templatefields', 'CsviModel', array('ignore_request' => true));
$fieldsModel->setState('filter.csvi_template_id', $template['csvi_template_id']);
$fields = $fieldsModel->getItems();
if (count($fields) > 0)
{
$nodes = array(
'field_name',
'xml_node',
'column_header',
'default_value',
'enabled',
'sort',
'cdata',
'ordering',
);
$template_fields = $xml->createElement('fields');
foreach ($fields as $field)
{
$template_field = $xml->createElement('field');
foreach ($nodes as $node)
{
if (isset($field->$node))
{
$fieldElement = $xml->createElement($node);
$fieldElement->appendChild($xml->createCDATASection($field->$node));
$template_field->appendChild($fieldElement);
}
}
// Add the template field rules
$query = $this->db->getQuery(true)
->select(
$this->db->quoteName(
array(
'name',
'action',
'ordering',
'plugin',
'plugin_params',
)
)
)
->from($this->db->quoteName('#__csvi_rules', 'r'))
->leftJoin(
$this->db->quoteName('#__csvi_templatefields_rules', 't')
. ' ON ' . $this->db->quoteName('t.csvi_rule_id') . ' = ' . $this->db->quoteName('r.csvi_rule_id')
)
->where($this->db->quoteName('t.csvi_templatefield_id') . ' = ' . (int) $field->csvi_templatefield_id);
$this->db->setQuery($query);
$rules = $this->db->loadObjectList();
if (count($rules) > 0)
{
$ruleNodes = array(
'name',
'action',
'ordering',
'plugin',
'plugin_params',
);
$fieldRules = $xml->createElement('fieldrules');
foreach ($rules as $rule)
{
$fieldRule = $xml->createElement('rule');
foreach ($ruleNodes as $ruleNode)
{
$ruleElement = $xml->createElement($ruleNode);
if ($ruleNode === 'plugin_params')
{
$params = json_decode($rule->$ruleNode);
if (is_object($params))
{
foreach ($params as $name => $value)
{
$element_param = $xml->createElement($name);
$element_param->appendChild($xml->createCDATASection($value));
$ruleElement->appendChild($element_param);
}
}
}
else
{
$ruleElement->nodeValue = $rule->$ruleNode;
}
$fieldRule->appendChild($ruleElement);
}
$fieldRules->appendChild($fieldRule);
}
$template_field->appendChild($fieldRules);
}
$template_fields->appendChild($template_field);
}
// Add the fields to the XML
$xml_template->appendChild($template_fields);
}
// Add the template to the XML
$this->log->setLinenumber($lineNumber++);
$csvi_element->appendChild($xml_template);
}
}
$xml->appendChild($csvi_element);
$location = $input->get('exportto', 'todownload', 'string');
// Create the backup file
$filePath = JPATH_SITE . $input->get('backup_location', '/tmp/com_csvi', 'string');
$filename = 'csvi_templates_' . date('Ymd', time()) . '.xml';
$file = JPath::clean($filePath . '/' . $filename, '/');
$xml->save($file);
$this->downloadfile = '';
// If user needs to download the file
if ($location === 'todownload')
{
$this->downloadfile = JUri::root() . 'administrator/index.php?option=com_csvi&view=exports&task=downloadfile&tmpl=component&file=' . base64_encode($file);
}
else
{
$this->log->addStats('information', JText::sprintf('COM_CSVI_BACKUP_TEMPLATE_PATH', $file), 'maintenance');
}
// Store the log count
$lineNumber--;
$input->set('logcount', $lineNumber);
return true;
}
/**
* Restore templates.
*
* @param FOFInput $input FOFInput object
* @param mixed $key A reference used by the method.
* @param string $filename A local filename to use for import
*
* @return bool True on success | False on failure.
*
* @since 3.0
*/
public function restoreTemplates(FOFInput $input, $key, $filename = '')
{
$linenumber = 1;
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
if (empty($filename))
{
$upload = $input->get('restore_file', false);
// Check if the file upload has an error
if (empty($upload))
{
$this->log->addStats('incorrect', JText::_('COM_CSVI_NO_UPLOADED_FILE_PROVIDED'), 'maintenance');
return false;
}
$filename = $upload['tmp_name'];
}
$doc = new DOMDocument;
$doc->load(realpath($filename));
$data = $this->domnodeToArray($doc->documentElement);
$file = basename($filename);
// Check if it is a multi-dimensional array
if (!isset($data['template'][0]))
{
// Make the array multi-dimensional
$newtemplate = array();
$newtemplate['template'][0] = $data['template'];
$data = $newtemplate;
}
// Load the necessary tables
$templateTable = FOFTable::getAnInstance('templates');
$fieldTable = FOFTable::getAnInstance('templatefields');
$ruleTable = FOFTable::getAnInstance('rules');
$templatefieldrulesTable = FOFTable::getAnInstance('templatefields_rules');
foreach ($data as $templates)
{
foreach ($templates as $template)
{
// Store the template
$templateTable->reset();
$templateTable->set('csvi_template_id', null);
$templateTable->set('template_name', $template['template_name']);
$templateTable->set('advanced', $template['advanced']);
$templateTable->set('action', $template['action']);
$templateTable->set('frontend', $template['frontend']);
$templateTable->set('secret', $template['secret']);
$templateTable->set('log', $template['log']);
$templateTable->set('lastrun', $template['lastrun']);
$templateTable->set('enabled', $template['enabled']);
$templateTable->set('ordering', $template['ordering']);
// Reformat the settings
foreach ($template['settings'] as $name => $setting)
{
// Convert back yes/no to template readable form 1/0
switch ($template['settings'][$name])
{
case 'no':
$val = 0;
break;
case 'yes':
$val = 1;
break;
default:
$val = $template['settings'][$name];
break;
}
$template['settings'][$name] = $val;
if (is_array($setting))
{
// Make sure the option is an array
$setting['option'] = (array) $setting['option'];
$template['settings'][$name] = $setting['option'];
}
}
$templateTable->set('settings', json_encode($template['settings']));
$templateTable->store();
if (array_key_exists('fields', $template))
{
// Store the fields
$fields = $template['fields']['field'];
if (!array_key_exists(0, $template['fields']['field']))
{
$fields = array(0 => $template['fields']['field']);
}
foreach ($fields as $field)
{
$fieldTable->set('csvi_template_id', $templateTable->get('csvi_template_id'));
$fieldTable->save($field);
// Store any field related rules
if (isset($field['fieldrules']))
{
foreach ($field['fieldrules'] as $rules)
{
if (isset($rules['name']))
{
$rules = array($rules);
}
foreach ($rules as $rule)
{
$ruledata = array(
'name' => $rule['name'],
'action' => $rule['action'],
'ordering' => $rule['ordering'],
'plugin' => $rule['plugin'],
'plugin_params' => json_encode($rule['plugin_params']),
'csvi_templatefield_id' => $fieldTable->get('csvi_templatefield_id')
);
// Save the rule
$ruleTable->save($ruledata);
// Save the relation
$templatefieldrulesTable->set('csvi_templatefield_id', $fieldTable->get('csvi_templatefield_id'));
$templatefieldrulesTable->set('csvi_rule_id', $ruleTable->get('csvi_rule_id'));
$templatefieldrulesTable->store();
// Reset the relation table
$templatefieldrulesTable->reset();
$templatefieldrulesTable->csvi_templatefields_rule_id = null;
// Reset the rule table
$ruleTable->reset();
$ruleTable->csvi_rule_id = null;
}
}
}
$fieldTable->reset();
$fieldTable->csvi_templatefield_id = null;
}
}
// Increment the number of templates processed
$this->log->setLinenumber($linenumber++);
}
}
// Set the name of the file restore to logs display
$this->log->setFilename($file);
// Store the log count
$linenumber--;
$input->set('logcount', $linenumber);
return true;
}
/**
* Turn the XML file into an associative array.
*
* @param DOMElement $node The tree to turn into an array.
*
* @return array The XML layout as associative array.
*
* @see https://github.com/gaarf/XML-string-to-PHP-array
*
* @since 6.0
*/
private function domnodeToArray($node)
{
$output = array();
switch ($node->nodeType)
{
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++)
{
$child = $node->childNodes->item($i);
$v = $this->domnodeToArray($child);
if (isset($child->tagName))
{
$t = $child->tagName;
if (!isset($output[$t]))
{
$output[$t] = array();
}
if (empty($v))
{
$v = '';
}
$output[$t][] = $v;
}
elseif ($v)
{
$output = (string) $v;
}
}
if (is_array($output))
{
if ($node->attributes->length)
{
$a = array();
foreach ($node->attributes as $attrName => $attrNode)
{
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v)
{
if (is_array($v) && count($v) == 1 && $t != '@attributes')
{
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
/**
* Prepare the ICEcat index files for loading.
*
* @param FOFInput $input The input model
*
* @return bool True on success | False on failure.
*
* @since 6.0
*/
public function onBeforeIcecatIndex(FOFInput $input)
{
$session = JFactory::getSession();
$settings = new CsviHelperSettings($this->db);
$username = $settings->get('ice_username', false);
$password = $settings->get('ice_password', false);
$icecat_options = $input->get('icecat', array(), null);
$icecat_gzip = $input->get('icecat_gzip', true, 'bool');
$loadremote_index = false;
$loadremote_supplier = false;
// Check which indexes to load
if (in_array('icecat_index', $icecat_options))
{
$load_index = true;
}
else
{
$load_index = false;
}
if (in_array('icecat_supplier', $icecat_options))
{
$load_supplier = true;
}
else
{
$load_supplier = false;
}
// Check if we have a username and password
if ($username && $password)
{
// Joomla includes
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.archive');
// Check if the files are stored on the server
$location = $input->get('icecatlocation', '', 'string');
if ($load_index)
{
if (JFile::exists($location . '/icecat_index'))
{
$icecat_index_file = $location . '/icecat_index';
}
elseif (JFile::exists($location . '/icecat_index.gzip'))
{
$icecat_index_file = $location . '/icecat_index.gzip';
}
elseif (JFile::exists($location . '/icecat_index.zip'))
{
$icecat_index_file = $location . '/icecat_index.zip';
}
else
{
$loadremote_index = true;
}
}
if ($load_supplier)
{
if (JFile::exists($location . '/icecat_supplier'))
{
$icecat_supplier_file = $location . '/icecat_supplier';
}
elseif (JFile::exists($location . '/icecat_supplier.gzip'))
{
$icecat_supplier_file = $location . '/icecat_supplier.gzip';
}
elseif (JFile::exists($location . '/icecat_supplier.zip'))
{
$icecat_supplier_file = $location . '/icecat_supplier.zip';
}
else
{
$loadremote_supplier = true;
}
}
// Load the remote files if needed
if ($loadremote_index || $loadremote_supplier)
{
// Context for retrieving files
if ($icecat_gzip)
{
$gzip = "Accept-Encoding: gzip\r\n";
}
else
{
$gzip = '';
}
$context = stream_context_create(array(
'http' => array(
'header' => "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n" . $gzip
)
));
if ($load_index && $loadremote_index)
{
// ICEcat index file
$icecat_url = $settings->get('icecat.ice_index', 'http://data.icecat.biz/export/freexml.int/INT/files.index.csv');
// Load the index file from the ICEcat server to a local file
$icecat_index_file = CSVIPATH_TMP . '/icecat_index';
if ($icecat_gzip)
{
$icecat_index_file .= '.gzip';
}
$fp_url = fopen($icecat_url, 'r', false, $context);
$fp_local = fopen($icecat_index_file, 'w+');
while($content = fread($fp_url, 1024536))
{
fwrite($fp_local, $content);
}
fclose($fp_url);
fclose($fp_local);
}
if ($load_supplier && $loadremote_supplier)
{
// Load the manufacturer data
$icecat_mf = $settings->get('icecat.ice_supplier', 'http://data.icecat.biz/export/freexml.int/INT/supplier_mapping.xml');
// Load the index file from the ICEcat server to a local file
$icecat_supplier_file = CSVIPATH_TMP . '/icecat_supplier';
if ($icecat_gzip)
{
$icecat_supplier_file .= '.gzip';
}
$fp_url = fopen($icecat_mf, 'r', false, $context);
$fp_local = fopen($icecat_supplier_file, 'w+');
while($content = fread($fp_url, 1024536))
{
fwrite($fp_local, $content);
}
fclose($fp_url);
fclose($fp_local);
}
}
// Check if we need to unpack the files
if ($load_index)
{
if (substr($icecat_index_file, -3) == 'zip')
{
if (!$this->unpackIcecat($icecat_index_file, CSVIPATH_TMP))
{
$this->log->addStats('incorrect', 'COM_CSVI_ICECAT_INDEX_NOT_UNPACKED', 'maintenance');
return false;
}
else
{
$icecat_index_file = CSVIPATH_TMP . '/icecat_index';
}
}
$session->set('icecat_index_file', serialize($icecat_index_file), 'com_csvi');
}
if ($load_supplier)
{
if (substr($icecat_supplier_file, -3) == 'zip')
{
if (!$this->unpackIcecat($icecat_supplier_file, CSVIPATH_TMP))
{
$this->log->addStats('incorrect', 'COM_CSVI_ICECAT_SUPPLIER_NOT_UNPACKED', 'maintenance');
return false;
}
else
{
$icecat_supplier_file = CSVIPATH_TMP . '/icecat_supplier';
}
}
$session->set('icecat_supplier_file', serialize($icecat_supplier_file), 'com_csvi');
}
}
else
{
$this->log->addStats('incorrect', 'COM_CSVI_ICECAT_NO_USER_PASS', 'maintenance');
return false;
}
return true;
}
/**
* Load the ICEcat indexes.
*
* @param FOFInput $input The input model
* @param mixed $key A reference used by the method.
*
* @return bool True on success | False on failure.
*
* @since 6.0
*/
public function icecatIndex(FOFInput $input, $key)
{
if ($key > 0)
{
$result = $this->indexIcecat($input, $key);
}
else
{
$linenumber = $this->log->getLineNumber();
// Load the index files
$session = JFactory::getSession();
$icecat_index_file = unserialize($session->get('icecat_index_file', '', 'com_csvi'));
$icecat_supplier_file = unserialize($session->get('icecat_supplier_file', '', 'com_csvi'));
// Should we load the index file in 1 go
$loadtype = $input->get('loadtype', true, 'bool');
// Check which files to load
$icecat_options = $input->get('icecat', array(), null);
$icecat_records = $input->get('icecat_records', 1000, 'int');
$session->set('icecat_records', serialize($icecat_records), 'com_csvi');
if (in_array('icecat_index', $icecat_options))
{
$load_index = true;
}
else
{
$load_index = false;
}
if (in_array('icecat_supplier', $icecat_options))
{
$load_supplier = true;
}
else
{
$load_supplier = false;
}
// First load the supplier file, it is small and easy to do
if ($linenumber == 0 && $load_supplier && $icecat_supplier_file)
{
// Add the line number
$this->log->setLinenumber(++$linenumber);
// Empty the supplier table
$this->db->truncateTable('#__csvi_icecat_suppliers');
// Reset the supplier file
$xmlstr = file_get_contents($icecat_supplier_file);
$xml = new SimpleXMLElement($xmlstr);
$supplier_data = array();
foreach ($xml->SupplierMappings->children() as $mapping)
{
foreach ($mapping->attributes() as $attr_name => $attr_value)
{
switch($attr_name)
{
case 'supplier_id':
$supplier_id = $attr_value;
break;
case 'name':
$supplier_data[] = '(' . $this->db->quote($supplier_id) . ',' . $this->db->quote($attr_value) . ')';
}
}
foreach ($mapping->children() as $symbol)
{
$supplier_data[] = '(' . $this->db->quote($supplier_id) . ',' . $this->db->quote($symbol) . ')';
}
}
$q = "INSERT IGNORE INTO ".$this->db->quoteName('#__csvi_icecat_suppliers') . " VALUES " . implode(',', $supplier_data);
$this->db->setQuery($q);
if ($this->db->execute())
{
$input->set('linesprocessed', $this->db->getAffectedRows());
$this->log->addStats('added', 'COM_CSVI_ICECAT_SUPPLIERS_LOADED');
}
else
{
$this->log->addStats('incorrect', JText::sprintf('COM_CSVI_ICECAT_SUPPLIERS_NOT_LOADED', $this->db->getErrorMsg()));
}
}
if (!$loadtype && $load_index)
{
if ($icecat_index_file)
{
// Empty the index table
$this->db->truncateTable('#__csvi_icecat_index');
// Load the files using INFILE
$q = "LOAD DATA LOCAL INFILE " . $this->db->quote($icecat_index_file) . "
INTO TABLE " . $this->db->quoteName('#__csvi_icecat_index') . "
FIELDS TERMINATED BY '\t' ENCLOSED BY '\"'
IGNORE 1 LINES";
$this->db->setQuery($q);
// Add the line number
$this->log->setLinenumber(++$linenumber);
if ($result = $this->db->execute())
{
$input->set('linesprocessed', $input->get('linesprocessed') + $this->db->getAffectedRows());
$this->log->addStats('added', 'COM_CSVI_ICECAT_INDEX_LOADED');
}
else
{
$this->log->addStats('incorrect', JText::sprintf('COM_CSVI_ICECAT_INDEX_NOT_LOADED', $this->db->getErrorMsg()));
}
}
else
{
$this->log->addStats('incorrect', 'COM_CSVI_ICECAT_INDEX_FILE_NOT_FOUND');
}
}
else
{
// Check if we are running a cron job
list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
// Load the files in 1 go using cron
if ($isCli)
{
$continue = true;
while ($continue)
{
$result = $this->indexIcecat($input, $key);
$continue = $input->get('continue');
}
}
// Load the files in steps using gui
else
{
if ($key == 0)
{
// Empty the index table
$this->db->truncateTable('#__csvi_icecat_index');
}
$result = $this->indexIcecat($input, $key);
}
}
}
return $result;
}
/**
* Post processing index ICEcat.
*
* @return array Settings for continuing.
*
* @since 6.0
*/
public function onAftericecatIndex()
{
if ($this->key)
{
// Return data
$results = array();
$results['continue'] = true;
$results['key'] = $this->key;
}
else
{
$results['continue'] = false;
}
$results['info'] = $this->message;
return $results;
}
/**
* Unpack the ICEcat index files.
*
* @param string $archivename The full path and name of the file to extract
* @param string $extractdir The folder to copy the extracted file to
*
* @return bool True on success | False on failure.
*
* @since 3.0
*/
private function unpackIcecat($archivename, $extractdir)
{
$adapter = JArchive::getAdapter('gzip');
if ($adapter)
{
$config = JFactory::getConfig();
$tmpfname = $config->get('tmp_path') . '/' . uniqid('gzip');
$gzresult = $adapter->extract($archivename, $tmpfname);
if (JError::isError($gzresult))
{
@unlink($tmpfname);
return false;
}
$path = JPath::clean($extractdir);
JFolder::create($path);
JFile::copy($tmpfname, $path . '/' . JFile::stripExt(basename(strtolower($archivename))));
@unlink($tmpfname);
}
return true;
}
/**
* Load the ICEcat index in batches.
*
* @param FOFInput $input The input model
* @param mixed $key A reference used by the method.
*
* @return bool True on success | False on failure.
*
* @since 3.3
*/
private function indexIcecat(FOFInput $input, $key)
{
$linenumber = $this->log->getLineNumber();
// Session init
$session = JFactory::getSession();
$icecat_index_file = unserialize($session->get('icecat_index_file', '', 'com_csvi'));
$records = unserialize($session->get('icecat_records', '', 'com_csvi'));
$finished = false;
$continue = true;
if ($icecat_index_file)
{
// Sleep to please the server
sleep($input->get('icecat_wait', 5));
// Load the records line by line
$query = $this->db->getQuery(true)
->insert($this->db->quoteName('#__csvi_icecat_index'))
->columns(
$this->db->quoteName('path') . ','
. $this->db->quoteName('product_id') . ','
. $this->db->quoteName('updated') . ','
. $this->db->quoteName('quality') . ','
. $this->db->quoteName('supplier_id') . ','
. $this->db->quoteName('prod_id') . ','
. $this->db->quoteName('catid') . ','
. $this->db->quoteName('m_prod_id') . ','
. $this->db->quoteName('ean_upc') . ','
. $this->db->quoteName('on_market') . ','
. $this->db->quoteName('country_market') . ','
. $this->db->quoteName('model_name') . ','
. $this->db->quoteName('product_view') . ','
. $this->db->quoteName('high_pic') . ','
. $this->db->quoteName('high_pic_size') . ','
. $this->db->quoteName('high_pic_width') . ','
. $this->db->quoteName('high_pic_height') . ','
. $this->db->quoteName('m_supplier_id') . ','
. $this->db->quoteName('m_supplier_name')
);
if (($handle = fopen($icecat_index_file, "r")) !== false)
{
// Position pointers
$row = 0;
// Position file pointer
fseek($handle, $key);
// Start processing
while ($continue)
{
if ($row < $records)
{
$data = fgetcsv($handle, 2048, "\t");
if ($data)
{
$row++;
$lines = array();
foreach ($data as $item)
{
if (empty($item))
{
$lines[] = 'NULL';
}
else
{
$lines[] = $this->db->quote($item);
}
}
$query->values(implode(',', $lines));
}
else
{
$finished = true;
$continue = false;
}
}
else
{
$continue = false;
}
}
// Store the data
$this->db->setQuery($query);
if ($this->db->execute())
{
$this->log->setLineNumber(++$linenumber);
$this->log->addStats('added', 'COM_CSVI_ICECAT_INDEX_LOADED');
// Store for future use
if (!$finished)
{
$this->key = ftell($handle);
$this->message = JText::sprintf('COM_CSVI_PROCESS_LINES', $row);
}
else
{
$this->log->addStats('added', 'COM_CSVI_ICECAT_INDEX_LOADED');
// Clear the session
$session->clear('icecat_index_file', 'com_csvi');
$session->clear('icecat_supplier_file', 'com_csvi');
$session->clear('icecat_records', 'com_csvi');
$session->clear('form', 'com_csvi');
}
$result = true;
}
else
{
$result = false;
}
fclose($handle);
return $result;
}
else
{
return false;
}
}
else
{
return false;
}
}
/**
* Clean up because the user has cancelled the operation.
*
* @return bool Returns true.
*
* @since 6.0
*/
public function cancelOperation()
{
// Clean the session
$session = JFactory::getSession();
$session->clear('icecat_index_file', 'com_csvi');
$session->clear('icecat_supplier_file', 'com_csvi');
return true;
}
/**
* Delete the CSVI tables.
*
* @return bool Returns true.
*
* @since 6.0
*/
public function deleteTables()
{
$tables = array(
'csvi_availablefields',
'csvi_availabletables',
'csvi_currency',
'csvi_icecat_index',
'csvi_icecat_suppliers',
'csvi_logdetails',
'csvi_logs',
'csvi_mapheaders',
'csvi_maps',
'csvi_processed',
'csvi_related_categories',
'csvi_related_products',
'csvi_rules',
'csvi_processes',
'csvi_settings',
'csvi_tasks',
'csvi_templatefields',
'csvi_templatefields_rules',
'csvi_templates',
'csvi_template_fields_combine',
'csvi_template_fields_replacement'
);
foreach ($tables as $tablename)
{
$this->db->dropTable($this->db->getPrefix() . $tablename);
}
return true;
}
/**
* Post process table deletion.
*
* @return bool Returns true.
*
* @since 6.0
*/
public function onAfterDeleteTables()
{
// Store the message to show
$this->csvihelper->enqueueMessage(JText::_('COM_CSVI_ALL_TABLES_DELETED'));
// Since we have no tables left and user plans to uninstall, we need to redirect to the extension manager
$cancel = array('url' => 'index.php?option=com_installer&view=manage');
JFactory::getApplication()->input->set('canceloptions', $cancel);
return array('cancel' => true);
}
/**
* Install any available example template.
*
* @param FOFInput $input The input model
*
* @return bool True on success | false on failure.
*
* @since 6.4.0
*/
public function exampleTemplates(FOFInput $input)
{
// Get a list of example templates to install
$components = $this->csvihelper->getComponents();
jimport('joomla.filesystem.file');
foreach ($components as $component)
{
// Process all extra available fields
$filename = JPATH_ADMINISTRATOR . '/components/com_csvi/addon/' . $component->value . '/install/templates.xml';
if (JFile::exists($filename))
{
// Check if the component is installed
if (substr($component->value, 0, 4) == 'com_')
{
$query = $this->db->getQuery(true)
->select($this->db->quoteName('extension_id'))
->from($this->db->quoteName('#__extensions'))
->where($this->db->quoteName('element') . ' = ' . $this->db->quote($component->value));
$this->db->setQuery($query);
$ext_id = $this->db->loadResult();
}
else
{
$ext_id = true;
}
if ($ext_id)
{
$this->log->add('Processing template file ' . $filename);
// Install the templates
if ($this->restoreTemplates($input, 0, $filename))
{
$this->log->addStats('added', JText::sprintf('COM_CSVI_ADDED_EXAMPLE_TEMPLATEFILE', JText::_('COM_CSVI_' . $component->value)));
}
}
}
}
}
/**
* Create available fields table.
*
* @return bool Returns true.
*
* @since 6.5.0
*/
private function createAvailableFieldsTable()
{
$query = "CREATE TABLE IF NOT EXISTS `#__csvi_availablefields` (
`csvi_availablefield_id` INT(11) NOT NULL AUTO_INCREMENT,
`csvi_name` VARCHAR(255) NOT NULL,
`component_name` VARCHAR(55) NOT NULL,
`component_table` VARCHAR(55) NOT NULL,
`component` VARCHAR(55) NOT NULL,
`action` VARCHAR(6) NOT NULL,
`isprimary` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`csvi_availablefield_id`),
UNIQUE INDEX `component_name_table` (`component_name`, `component_table`, `component`, `action`)
) CHARSET=utf8 COMMENT='Available fields for CSVI'";
$this->db->setQuery($query);
try
{
$this->db->execute();
$this->log->addStats('created', 'COM_CSVI_AVAILABLE_FIELDS_TABLE_CREATED', 'availablefields');
}
catch (Exception $e)
{
$this->log->addStats('error', $e->getMessage(), 'availablefields');
return false;
}
return true;
}
/**
* Post processing of backup templates.
*
* @return array Settings for continuing.
*
* @since 6.6.0
*/
public function onAfterBackupTemplates()
{
return array('downloadfile' => $this->downloadfile);
}
}