0byt3m1n1-V2
Path:
/
home
/
academiac
/
www
/
administrator
/
components
/
com_csvi
/
models
/
[
Home
]
File: importfile.php
<?php /** * Import file model * * @author Roland Dalmulder * @link http://www.csvimproved.com * @copyright Copyright (C) 2006 - 2013 RolandD Cyber Produksi. All rights reserved. * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html * @version $Id: importfile.php 2549 2013-11-26 01:42:51Z RolandD $ */ defined('_JEXEC') or die; jimport( 'joomla.application.component.model' ); /** * Import file Model */ class CsviModelImportfile extends JModel { // Private variables /** @var integer for keeping track when the script started */ private $_starttime = 0; /** @var array - Indexed array of field names (mixed case) */ private $_supported_fields = array(); /** @var array - Associative array of field_name (lower case) => field default value */ private $_field_defaults = array(); /** @var array - Associative array of field_name (lower case) => field published? value */ private $_field_published = array(); /** @var integer the database ID for the vendor */ private $_vendor_id = null; /** @var bool sets if the default value should be used or not */ private $_skip_default_value = null; /** @var array contains a list of vendor currencies */ private $_vendor_currencies = array(); /** @var object contains the ICEcat helper */ private $_icecat = null; // Protected variables /** @var object contains the data to import */ protected $csvi_data = null; /** @var object contains the fields to import */ protected $_csvifields = null; /** @var array contains the available fields */ protected $_avfields = null; /** @var array contains the ICEcat data */ protected $icecat_data = null; /** @var array contains the fields to combine */ protected $combine_fields = array(); /** @var array contains the combine settings */ protected $combine_settings = array(); /** @var string contains the name of the last import field */ protected $_lastfield = null; /** * Compile a list of helper files needed to include * * @copyright * @author RolandD * @todo Make the image class loader smarter * @see * @access public * @param * @return array list of helper files to include * @since 3.0 */ public function getHelperFiles() { $jinput = JFactory::getApplication()->input; $data = $jinput->get('jform', array(), null); $helpers = array(); $upload_parts = array(); // Get the file extension of the import file switch (strtolower($data['general']['source'])) { case 'fromupload': $upload['name'] = $_FILES['jform']['name']['general']['import_file']; $upload['type'] = $_FILES['jform']['type']['general']['import_file']; $upload['tmp_name'] = $_FILES['jform']['tmp_name']['general']['import_file']; $upload['error'] = $_FILES['jform']['error']['general']['import_file']; if (isset($upload['name'])) $upload_parts = pathinfo($upload['name']); break; case 'fromserver': $upload_parts = pathinfo($data['general']['local_csv_file']); break; case 'fromurl': $upload_parts = pathinfo($data['general']['urlfile']); break; case 'fromftp': $upload_parts = pathinfo($data['general']['ftpfile']); break; } // Set the file helper if (!array_key_exists('extension', $upload_parts)) return false; else { switch ($upload_parts['extension']) { case 'xml': $helpers[] = $upload_parts['extension']; $fileclass = 'Xml'; break; case 'xls': $helpers[] = $upload_parts['extension']; $helpers[] = 'excel_reader2'; $fileclass = 'Xls'; break; case 'ods': $helpers[] = $upload_parts['extension']; $helpers[] = 'ods_reader'; $fileclass = 'Ods'; break; default: // Treat any unknown type as CSV $helpers[] = 'csv'; $fileclass = 'Csv'; break; } // Set the file class name $jinput->set('fileclass', $fileclass.'File'); // Do we need to load the image helper switch ($data['options']['operation']) { case 'productimport': case 'categoryimport': case 'mediaimport': $helpers[] = 'images'; break; } // Add the helpers to the session $session = JFactory::getSession(); $option = $jinput->get('option'); $session->set($option.'.helper_files', serialize($helpers)); return $helpers; } } /** * Make preparations for the import * * @copyright * @author RolandD * @todo Fix storing of log when file cannot be retrieved from FTP * @todo Fix the template name * @see * @access public * @param * @return bool true on file OK | false on file NOK * @since 3.0 */ public function getPrepareImport() { $jinput = JFactory::getApplication()->input; $db = JFactory::getDbo(); // Get the form data $session = JFactory::getSession(); $option = $jinput->get('option'); $data = $jinput->get('jform', array(), null); // Set the template name $query = $db->getQuery(true); $query->select('name'); $query->from('#__csvi_template_settings'); $query->where('id = '.$jinput->get('select_template', '', null)); $db->setQuery($query); $data['template_name'] = $db->loadResult(); $template = new CsviTemplate($data); $jinput->set('template', $template); $session->set($option.'.global.template', serialize($template)); // Initiate the log $csvilog = new CsviLog(); $jinput->set('csvilog', $csvilog); // Create a new Import ID in the logger $csvilog->setId(); // Set to collect debug info $csvilog->setDebug($template->get('collect_debug_info', 'general')); // Retrieve the available fields $availablefields = $this->getModel('Availablefields'); $this->_avfields = $availablefields->getAvailableFields($template->get('operation', 'options'), $template->get('component', 'options')); $session->set($option.'.avfields', serialize($this->_avfields)); // Needed for file class $jinput->set('avfields', $this->_avfields); // Set some log info $csvilog->SetAction('import'); $csvilog->SetActionType($template->get('operation', 'options'), $template->get('template_name')); // Process the file to import if ($template->get('im_mac', 'general', false)) { // Auto detect line-endings to also support Mac line-endings ini_set('auto_detect_line_endings', true); } // Process the file to import $fileclass = $jinput->get('fileclass', null, null); $csvifile = new $fileclass; if ($csvifile->validateFile()) { $csvifile->processFile(); if (!$csvifile->fp) { return false; } else { // Load column headers if ($template->get('use_column_headers', 'general')) { $csvifile->loadColumnHeaders(); $session->set($option.'.csvicolumnheaders', serialize($jinput->get('columnheaders', array(), 'array'))); } else if ($template->get('skip_first_line', 'general')) { // Move 1 row forward as we are skipping the first line $csvifile->next(); } // Load the fields if ($this->_retrieveConfigFields($csvifile)) $session->set($option.'.csvifields', serialize($jinput->get('csvifields', null, 'array'))); else { JError::raiseNotice(0, JText::_('COM_CSVI_CANNOT_LOAD_FIELDS')); return false; } // Write out some import settings $this->_importDetails(); // Store the file position $session->set($option.'.filepos', serialize($csvifile->getFilePos())); // Empty the data first so we don't break the session $csvifile->clearData(); // Store the CSVI file handler $session->set($option.'.csvifile', serialize($csvifile)); // Store the CSVI log handler $session->set($option.'.csvilog', serialize($csvilog)); // Store the preview handler $session->set($option.'.csvipreview', serialize($template->get('show_preview', 'general'))); // Set the combine separator $this->combine_settings['separator'] = ' '; $this->combine_settings['fieldname'] = null; // Unpublish any products if needed if ($template->get('unpublish_before_import', 'product', 0)) $this->_unpublishProducts(); return true; } } else { return false; } } /** * Make preparations to do an import * * @copyright * @author RolandD * @todo Fix the setting of the file position on subsequent imports * @see finishProcess * @access public * @param * @return * @since 3.0 */ public function getDoImport() { $jinput = JFactory::getApplication()->input; // Set the system limits $this->_systemLimits(); // Open the file $csvifile = $jinput->get('csvifile', null, null); if ($csvifile->processFile()) { // Set the file pointer $session = JFactory::getSession(); $option = $jinput->get('option'); $csvifile->setFilePos(unserialize($session->get($option.'.filepos', 0))); // Set the line counter $jinput->set('currentline', 1); // Set the fields found in the file $this->_csvifields = $jinput->get('csvifields', null, 'array'); return true; } else return false; } /** * Start the import * * @copyright * @author RolandD * @todo Separate view for preview * @todo Rewrite memory usage for debug * @see * @access public * @param * @return * @since 3.0 */ public function getProcessData() { $jinput = JFactory::getApplication()->input; // Set some variables $data_preview = array(); $processdata = true; $redirect = false; // Load the log $csvilog = $jinput->get('csvilog', null, null); // Load the settings $settings = new CsviSettings(); // Load the template $template = $jinput->get('template', null, null); // Load the file $csvifile = $jinput->get('csvifile', null, null); // Set the table path $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR.'/tables/'.$template->get('component', 'options')); // Load the import routine $routine = $this->getModel($template->get('operation', 'options')); if ($routine) { // Start processing data while ($processdata) { // Pass the total log line to the logger $csvilog->setLinenumber(($jinput->get('currentline', 0, 'int')+$jinput->get('totalline', 0, 'int'))); // If the number of lines is set to 0, do unlimited import if (($settings->get('import.import_nolines', 0) == 0) || $jinput->get('cron', false, 'bool')) { $nolines = $jinput->get('currentline', 0, 'int')+1; } else $nolines = $settings->get('import.import_nolines'); if ($jinput->get('currentline', 0, 'int') <= $nolines) { // For XML files, it may be necessary to refresh the headers before reading the next record if ($csvifile->extension == 'xml' && $template->get('refresh_xml_headers', 'general')) { $csvifile->loadColumnHeaders(); if ($this->_retrieveConfigFields($csvifile) == false) { // Error found - Finish processing $redirect = $this->finishProcess(false); $processdata = false; continue; } } // Load the data $this->csvi_data = $csvifile->ReadNextLine(); if ($this->csvi_data == false) { if ($jinput->get('csvipreview', false, 'bool')) { // Set the headers $headers = array(); foreach ($this->_csvifields as $fieldname => $value) { if ($value['published']) { if (isset($routine->$fieldname) || empty($routine->$fieldname)) $headers[] = $fieldname; } } $jinput->set('headers_preview', $headers); // Set the data $jinput->set('data_preview', $data_preview); // Clean the session $this->getCleanPreview(); $processdata = false; continue; } else { // Finish processing $this->finishProcess(true); $processdata = false; } } else { // Check if we need to add any extra fields if (count($this->_csvifields) > count($this->csvi_data)) { foreach ($this->_csvifields as $fieldname => $details) { if (!array_key_exists($details['order'], $this->csvi_data)) { if (!empty($details['default_value'])) { $this->csvi_data[$details['order']] = $details['default_value']; } } } // Check if the fields are now equal if (count($this->_csvifields) > count($this->csvi_data)) { $message = JText::sprintf('COM_CSVI_INCORRECT_COLUMN_COUNT', count($this->_csvifields), count($this->csvi_data)); $message .= '<br />'.JText::_('COM_CSVI_FIELDS').'<br />'; $message .= '<table class="adminlist"><thead><tr><th>Position</th><th>Configuration</th><th>Import file</th></tr></thead><tfoot></tfoot>'; $message .= '<tbody>'; foreach($this->_csvifields as $fieldname => $field_details) { $message .= '<tr><td>'.$field_details['order'].'</td><td>'.$fieldname.'</td><td>'; if (isset($this->csvi_data[$field_details['order']])) $message .= $this->csvi_data[$field_details['order']]; $message .= '</td></tr>'; } $message .= '</tbody></table>'; $csvilog->AddStats('incorrect', $message, true); // Finish processing $this->finishProcess(true); $processdata = false; } } // Load ICEcat data if user wants to $this->getIcecat(); // Validate the fields $csvi_data = new JObject(); foreach ($this->_csvifields as $name => $details) { if ($details['published']) { $datafield = $this->validateInput($details['name'], $details['replace']); if ($datafield !== false) { // Check if we are dealing with the last field if ($details == $this->_lastfield) $details['combine'] = false; // See if we are combining the field if ($details['combine']) $this->setCombineField($datafield, $name); else { // Check if there are any fields to be combined if (!empty($this->combine_fields)) { // Get the fieldname the combine is for $name = $this->combine_settings['fieldname']; // Add the current data $this->setCombineField($datafield); // Get the combined data $datafield = $this->getCombineField(); } } // Set the new value $csvi_data->$name = $datafield; } } } $jinput->set('csvi_data', $csvi_data); if ($this->_checkLimits()) { // Notify the debug log what line we are one $csvilog->addDebug(JText::sprintf('COM_CSVI_DEBUG_PROCESS_LINE', ($jinput->get('currentline', 0, 'int')+$jinput->get('totalline', 0, 'int')))); // Start processing record if ($routine->getStart()) { if ($jinput->get('csvipreview', false, 'bool')) { $this->loadSettings(); // Update preview data foreach ($this->_csvifields as $fieldname => $value) { if ($value['published']) { if (isset($routine->$fieldname)) $preview_data[$value['order']] = $routine->$fieldname; else if (empty($routine->$fieldname)) $preview_data[$value['order']] = ''; } } $data_preview[$jinput->get('currentline', 0, 'int')] = $preview_data; if ($jinput->get('currentline', 0, 'int') == $settings->get('import.import_preview', 5)) { // Set the headers $headers = array(); foreach ($this->_csvifields as $fieldname => $value) { if ($value['published']) { if (isset($routine->$fieldname) || empty($routine->$fieldname)) $headers[] = $fieldname; } } $jinput->set('headers_preview', $headers); // Set the data $jinput->set('data_preview', $data_preview); // Clean the session $this->getCleanPreview(); $processdata = false; continue; } } else { // Now we import the rest of the records $routine->getProcessRecord(); } // Increase the number of records processed $jinput->set('recordsprocessed', $jinput->get('recordsprocessed', 0, 'int')+1); } else { // The routine reports a problem, usually unmet conditions // Finish processing $this->finishProcess(true); // Stop from processing any further, no time left $processdata = false; } // Increase linenumber $jinput->set('currentline', $jinput->get('currentline', 0, 'int')+1); } else { // Finish processing $this->finishProcess(false); // Stop from processing any further, no time left $processdata = false; } } } // Prepare for page reload else { // Finish processing $this->finishProcess(false); // Stop from processing any further, no time left $processdata = false; } } // Post Processing if (method_exists($routine, 'getPostProcessing')) { $routine->getPostProcessing(array_keys($this->_csvifields)); } } else { $csvilog->AddStats('incorrect', 'COM_CSVI_NO_VALID_CLASS_FOUND'); // Finish processing $this->finishProcess(true); } } /** * Clean the session * * @copyright * @author RolandD * @todo * @see * @access public * @param * @return void * @since 3.0 */ public function getCleanSession() { $jinput = JFactory::getApplication()->input; // Store the log results first $log = $this->getModel('log'); $log->getStoreLogResults(); // Get session handler $session = JFactory::getSession(); $option = $jinput->get('option'); // Unset all session values $session->clear($option.'.csvicolumnheaders'); $session->clear($option.'.csvifields'); $session->clear($option.'.avfields'); $session->clear($option.'.csvifile'); $session->clear($option.'.filepos'); $session->clear($option.'.recordsprocessed'); $session->clear($option.'.template_id'); $session->clear($option.'.totalline'); $session->clear($option.'.csvilog'); $session->clear($option.'.global.template'); $session->clear($option.'.csvisettings'); $session->clear($option.'.helper_files'); } /** * Clean the session after preview * * @copyright * @author RolandD * @todo * @see * @access public * @param * @return void * @since 3.0 */ private function getCleanPreview() { $jinput = JFactory::getApplication()->input; // Get session handler $session = JFactory::getSession(); $option = $jinput->get('option'); // Load the correct position if ($jinput->get('csvipreview', false, 'bool')) { $template = $jinput->get('template', null, null); $csvifile = $jinput->get('csvifile', null, null); // Move back to the beginning $csvifile->rewind(); // Move 1 row forward as this is the column header if ($template->get('use_column_headers', 'general') || $template->get('skip_first_line', 'general')) { $csvifile->next(true); } // Get the current position $filepos = $csvifile->getFilePos(); } else $filepos = 0; // Unset all session values $session->set($option.'.filepos', serialize($filepos)); $session->set($option.'.recordsprocessed', serialize(0)); $session->set($option.'.csvipreview', serialize(false)); } /** * Sets the system limits to user defined values * * Sets the system limits to user defined values to allow for longer and * bigger uploaded files * * @copyright * @author RolandD * @todo Allow 0 or -1 value * @see * @access private * @param * @return * @since 3.0 */ private function _systemLimits() { $jinput = JFactory::getApplication()->input; // Set the start time of the script $this->_starttime = time(); // Get the logger $csvilog = $jinput->get('csvilog', null, null); $template = $jinput->get('template', null, null); // See if we need to use the new limits if ($template->get('use_system_limits', 'limit')) { $csvilog->addDebug('Setting system limits:'); // Apply the new memory limits $execution_time = $template->get('max_execution_time'); if (strlen($exection_time) > 0) { $csvilog->addDebug('Setting max_execution_time to '.$execution_time.' seconds'); @ini_set('max_execution_time', $execution_time); } $memory_limit = $template->get('memory_limit', 'limit'); if ($memory_limit == '-1') { $csvilog->addDebug('Setting memory_limit to '.$memory_limit); @ini_set('memory_limit', $memory_limit); } else if (strlen($memory_limit) > 0) { $csvilog->addDebug('Setting memory_limit to '.$memory_limit.'M'); @ini_set('memory_limit', $memory_limit.'M'); } $post_size = $template->get('post_max_size', 'limit'); if (strlen($post_size) > 0) { $csvilog->addDebug('Setting post_max_size to '.$post_size.'M'); @ini_set('post_max_size', $post_size.'M'); } $file_size = $template->get('upload_max_filesize', 'limit'); if (strlen($file_size) > 0) { $csvilog->addDebug('Setting upload_max_filesize to '.$file_size.'M'); @ini_set('upload_max_filesize', $file_size.'M'); } } } /** * Function to check if execution time is going to be passed. * * Memory can only be checked if the function memory_get_usage is available. * If the function is not available always return true. This could lead to * out of memory failure. * * @copyright * @author RolandD * @todo * @see http://www.php.net/memory_get_usage * @access private * @param * @return bool true when limits are not reached|false when limit is reached * @since 3.0 */ private function _checkLimits() { $jinput = JFactory::getApplication()->input; $csvilog = $jinput->get('csvilog', null, null); // Check for maximum execution time $timepassed = time() - $this->_starttime; if (($timepassed + 5) > ini_get('max_execution_time') && ini_get('max_execution_time') > 0) { $csvilog->AddStats('information', JText::sprintf('COM_CSVI_MAXIMUM_EXECUTION_LIMIT_EXCEEDED', $timepassed)); return false; } // Check for maximum memory usage if (!function_exists('memory_get_usage')) return true; else { // Get the size of the statistics $statslength = 0; if (isset($csvilog->stats)) { foreach ($csvilog->stats as $type => $value) { if (isset($value['message'])) $statslength += strlen($value['message']); } } $statslength = round($statslength/(1024*1024)); // Get the size of the debug message $debuglength = round(strlen($csvilog->debug_message)/(1024*1024)); // Get the size of the active memory in use $activelength = round(memory_get_usage()/(1024*1024)); // Combine memory limits $totalmem = $activelength + $statslength + $debuglength; // Set the memory limit $jinput->set('maxmem', $totalmem); // Check if we are passing the memory limit if (($totalmem * 1.5) > (int)ini_get('memory_limit')) { $csvilog->AddStats('information', JText::_('COM_CSVI_MAXIMUM_MEMORY_LIMIT_EXCEEDED', $totalmem)); return false; } // All is good return true return true; } } /** * Print out import details * * @copyright * @author RolandD * @todo * @see * @access private * @param * @return * @since 3.0 */ private function _importDetails() { $jinput = JFactory::getApplication()->input; // Get the logger $csvilog = $jinput->get('csvilog', null, null); // Get the template settings to see if we need a preview $template = $jinput->get('template', null, null); $csvilog->addDebug(JText::_('COM_CSVI_CSVI_VERSION_TEXT').JText::_('COM_CSVI_CSVI_VERSION')); if (function_exists('phpversion')) $csvilog->addDebug(JText::sprintf('COM_CSVI_PHP_VERSION', phpversion())); // General settings $csvilog->addDebug(JText::_('COM_CSVI_GENERAL_SETTINGS')); // Show which template is used $csvilog->addDebug(JText::sprintf('COM_CSVI_TEMPLATE_NAME', $template->get('template_name'))); // Auto detect delimiters $auto_detect = ($template->get('auto_detect_delimiters', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_AUTO_DETECT_DELIMITERS', $auto_detect)); if ($auto_detect == JText::_('COM_CSVI_NO')) { // Check delimiter char $csvilog->addDebug(JText::sprintf('COM_CSVI_USING_DELIMITER', $template->get('field_delimiter', 'general'))); // Check enclosure char $csvilog->addDebug(JText::sprintf('COM_CSVI_USING_ENCLOSURE', $template->get('text_enclosure', 'general'))); } // Show import settings // Show template type $csvilog->addDebug(JText::sprintf('COM_CSVI_CHOSEN_IMPORT_TYPE', JText::_('COM_CSVI_'.$template->get('operation', 'options')))); // Use column headers as configuration $use_header = ($template->get('use_column_headers', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_USE_HEADER', $use_header)); // Refresh xml headers for every record $refresh_xml_headers = ($template->get('refresh_xml_headers', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_REFRESH_XML_HEADER', $use_header)); // Skip first line $skip_first = ($template->get('skip_first_line', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_SKIP_FIRST_LINE', $skip_first)); // Ignore non-existing products $ignore_non_exist = ($template->get('ignore_non_exist', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_IGNORE_NON_EXIST', $ignore_non_exist)); // Overwrite existing data $overwrite = ($template->get('overwrite_existing_data', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_OVERWRITE_EXISTING_DATA', $overwrite)); // Skip default value $skip_default = ($template->get('skip_default_value', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_SKIP_DEFAULT_VALUE', $skip_default)); // Show preview $use_preview = ($template->get('show_preview', 'general')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_USING_PREVIEW', $use_preview)); // Products // Unpublish products before import $unpublish = ($template->get('unpublish_before_import', 'product')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_UNPUBLISH_BEFORE_IMPORT', $unpublish)); // Categories // Append categories $append_cats = ($template->get('append_categories', 'product')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_APPEND_CATEGORIES', $append_cats)); // Images // General options $process_image = ($template->get('process_image', 'image', false)) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_PROCESS_IMAGE', $process_image)); // Create image name $create_name = ($template->get('auto_generate_image_name', 'image')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_CREATE_IMAGE_NAME', $create_name)); // Generate image name $csvilog->addDebug(JText::sprintf('COM_CSVI_IMAGE_BASED_ON', $template->get('type_generate_image_name', 'image'))); // Image name format $csvilog->addDebug(JText::sprintf('COM_CSVI_IMAGE_NAME_FORMAT', $template->get('auto_generate_image_name_ext', 'image'))); // Full image // Convert image $csvilog->addDebug(JText::sprintf('COM_CSVI_CONVERT_IMAGE', $template->get('convert_type', 'image'))); // Save images on server $on_server = ($template->get('save_images_on_server', 'image')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_SAVE_IMAGES_ON_SERVER', $on_server)); // Thumbnail image // Automatic thumbnail creation $auto_thumb = ($template->get('thumb_create', 'image')) ? JText::_('COM_CSVI_YES') : JText::_('COM_CSVI_NO'); $csvilog->addDebug(JText::sprintf('COM_CSVI_AUTOMATIC_THUMBS', $auto_thumb)); if ($auto_thumb == JText::_('COM_CSVI_YES')) { // Thumbnail format $csvilog->addDebug(JText::sprintf('COM_CSVI_FORMAT_THUMBS', $template->get('thumb_extension', 'image'))); // Thumbnail width x height $csvilog->addDebug(JText::sprintf('COM_CSVI_DIMENSION_THUMBS', $template->get('thumb_width', 'image'), $template->get('thumb_height', 'image'))); } // Show the file paths $csvilog->addDebug(JText::sprintf('COM_CSVI_DEBUG_FILE_PATH_PRODUCT_IMAGES', $template->get('file_location_product_images', 'path'))); $csvilog->addDebug(JText::sprintf('COM_CSVI_DEBUG_FILE_PATH_CATEGORY_IMAGES', $template->get('file_location_category_images', 'path'))); $csvilog->addDebug(JText::sprintf('COM_CSVI_DEBUG_FILE_PATH_MEDIA', $template->get('file_location_media', 'path'))); // Show the max execution time $csvilog->addDebug(JText::sprintf('COM_CSVI_DEBUG_MAX_EXECUTION_TIME', ini_get('max_execution_time'))); } /** * Unpublish products before import * * @copyright * @author RolandD * @todo * @see prepareImport() * @access private * @param * @return * @since 3.0 */ private function _unpublishProducts() { $jinput = JFactory::getApplication()->input; $csvilog = $jinput->get('csvilog', null, null); $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->update('#__virtuemart_products'); $query->set('published = 0'); $db->setQuery($query); if ($db->query()) $csvilog->addDebug(JText::_('COM_CSVI_PRODUCT_UNPUBLISH_BEFORE_IMPORT')); else $csvilog->addDebug(JText::_('COM_CSVI_COULD_NOT_UNPUBLISH_BEFORE_IMPORT'), true); } /** * Builds arrays of field names and default values to be used during the creation of the headers list * The creation of the headers from the data file may need to be carried out for every row when processing * XML files and so efficiency is important for performance. * * Note: The array supported_fields should not be used as the basis for these arrays because it is a list of * all available fields and some of these fields may not be mapped in the template. */ public function _fieldArrays() { $jinput = JFactory::getApplication()->input; $template = $jinput->get('template', null, null); $db = JFactory::getDBO(); $this->_supportedfields = array(); $this->_field_defaults = array(); $this->_field_published = array(); if ($template->get('use_column_headers', 'general')) { // Check if there are any avfields if (empty($this->_avfields)) { $option = $jinput->get('option'); $session = JFactory::getSession(); $this->_avfields = unserialize($session->get($option.'.avfields')); } $supportedfields = array_flip($this->_avfields); foreach ($supportedfields as $name => $value) { $this->_supported_fields[] = $name; $this->_field_defaults[strtolower($name)] = null; $this->_field_published[strtolower($name)] = 1; } } // Use the template fields assigned to the template else { $import_fields = $template->get('import_fields'); if (isset($import_fields['_selected_name'])) { $count = count($import_fields['_selected_name']); for ($rows = 0; $rows < $count; $rows++) { $this->_supported_fields[] = $import_fields['_selected_name'][$rows]; $this->_field_defaults[strtolower($import_fields['_selected_name'][$rows])] = $import_fields['_default_value'][$rows]; $this->_field_published[strtolower($import_fields['_selected_name'][$rows])] = $import_fields['_process_field'][$rows]; } } } // Create the inverted array used to lookup the field name using lowercase $this->_supportedfields = array(); foreach( $this->_supported_fields as $key => $value ) { $this->_supportedfields[strtolower($value)] = $key; } } /** * Get the configuration fields the user wants to use * * The configuration fields can be taken from the uploaded file or from * the database. Depending on the template settings. * * @copyright * @author RolandD * @todo Expand the no support fields message on line 398 * @see Templates() * @access private * @param * @return bool true|false true when there are config fields|false when there are no or unsupported fields * @since 3.0 */ private function _retrieveConfigFields($csvifile=false) { $jinput = JFactory::getApplication()->input; $db = JFactory::getDbo(); $template = $jinput->get('template', null, null); $csvilog = $jinput->get('csvilog', null, null); if (!$csvifile) $csvifile = $jinput->get('csvifile', '', 'string'); if (empty($this->_supportedfields)) $this->_fieldArrays(); $columnheaders = $jinput->get('columnheaders', array(), 'array'); $csvifields = array(); $nosupport = array(); $csvilog->addDebug(JText::_('COM_CSVI_DEBUG_LOAD_CONFIG_FIELDS')); if ($template->get('use_column_headers', 'general')) { // The user has column headers in the file $jinput->set('error_found', false); if ($columnheaders) { foreach ($columnheaders as $order => $name) { // Trim the name in case the name contains any preceding or trailing spaces $name = strtolower(trim($name)); // Check if the fieldname is supported // No special field checking for Product Type Names upload if (array_key_exists($name, $this->_supportedfields)) { $csvilog->addDebug('Field: '.$name); $mixed_name = $this->_supported_fields[$this->_supportedfields[$name]]; $csvifields[$mixed_name]['name'] = $mixed_name; $csvifields[$mixed_name]['order'] = $order; $csvifields[$mixed_name]['default_value'] = (array_key_exists($name, $this->_field_defaults)) ? $this->_field_defaults[$name] : null; $csvifields[$mixed_name]['published'] = (array_key_exists($name, $this->_field_published)) ? $this->_field_published[$name] : 'Y'; $csvifields[$mixed_name]['combine'] = false; $csvifields[$mixed_name]['replace'] = null; } else { // Check if the user has any field that is not supported if (strlen($name) == 0) $name = JText::_('COM_CSVI_FIELD_EMPTY'); // Field is not supported, let's skip it $csvifields[$name]['name'] = $name; $csvifields[$name]['order'] = $order; $csvifields[$name]['default_value'] = null; $csvifields[$name]['published'] = 'N'; $csvifields[$name]['combine'] = false; $csvifields[$name]['replace'] = null; // Unset the column header so we can check if any fields are left over unset($columnheaders[$order]); // Collect the fieldnames to report them $nosupport[] = $name; } } //if (empty($columnheaders)) { // $csvilog->AddStats('incorrect', JText::_('COM_CSVI_NO_COLUMN_HEADERS_FOUND')); // $jinput->set('error_found', true); // return false; //} if (!empty($nosupport)) { // Ensure the error message matches the file type switch($csvifile->extension) { case 'xml': case 'sql': $csvilog->AddStats('nosupport', implode(',', $nosupport).JText::_('COM_CSVI_FIELD_NOT_INCLUDED')); break; default: $csvilog->AddStats('nosupport', JText::sprintf('COM_CSVI_NO_SUPPORT', '<ul><li>'.implode('</li><li>', $nosupport).'</li></ul>')); break; } $csvilog->AddStats('information', JText::_('COM_CSVI_UNSUPPORTED_FIELDS')); } $csvilog->addDebug(JText::_('COM_CSVI_USING_FILE_FOR_CONFIGURATION')); } else { $csvilog->AddStats('incorrect', JText::_('COM_CSVI_NO_COLUMN_HEADERS_FOUND')); $jinput->set('error_found', true); return false; } } // Use the fields assigned to the template else { $fields = $template->get('import_fields'); if (!empty($fields)) { foreach ($fields['_selected_name'] as $fid => $name) { // Check if we are handling a combine field if ($name == 'combine') $name .= $fid; // Collect the data $csvifields[$name]['name'] = $name; $csvifields[$name]['order'] = $fid; $csvifields[$name]['default_value'] = $fields['_default_value'][$fid]; $csvifields[$name]['published'] = $fields['_process_field'][$fid]; $csvifields[$name]['combine'] = $fields['_combine_field'][$fid]; $csvifields[$name]['replace'] = $fields['_replace_field'][$fid]; if (!$csvifields[$name]['published']) $name .= ' ('.JText::_('COM_CSVI_FIELD_SKIPPED').')'; $csvilog->addDebug(JText::sprintf('COM_CSVI_IMPORT_FIELD', $name)); } $csvilog->addDebug(JText::_('COM_CSVI_USE_DATABASE_FOR_CONFIGURATION')); } else { $csvilog->AddStats('incorrect', JText::_('NO_COLUMN_HEADERS_FOUND')); return false; } } // Make the fields to process global $jinput->set('csvifields', $csvifields); return true; } /** * Handle the end of the import * * @copyright * @author RolandD * @todo Optimize adding ID to session * @see * @access private * @param * @return * @since 3.0 */ public function finishProcess($finished=false) { $jinput = JFactory::getApplication()->input; $template = $jinput->get('template', null, null); $csvifile = $jinput->get('csvifile', null, null); $csvilog = $jinput->get('csvilog', null, null); // Adjust the current line, since it is not processing $jinput->set('currentline', $jinput->get('currentline', 0, 'int')-1); // Session init $session = JFactory::getSession(); $option = $jinput->get('option'); if ($finished) { // Close the file if (is_object($csvifile)) $csvifile->closeFile(true); // Clean the session $this->getCleanSession(); // Add the ID to the session as we need it for the redirect to the result page $session->set($option.'.run_id', $csvilog->getId()); $jinput->set('run_id', $csvilog->getId()); } else { // Flush the log details // Store the log results first $log = $this->getModel('log'); $log->getStoreLogResults(); // Create session variables $session->set($option.'.global.template', serialize($template)); $session->set($option.'.csvicolumnheaders', serialize($jinput->get('columnheaders', null, 'array'))); $session->set($option.'.csvifields', serialize($this->_csvifields)); $session->set($option.'.csvifile', serialize($csvifile)); $session->set($option.'.csvilog', serialize($csvilog)); $session->set($option.'.filepos', serialize($csvifile->getFilePos())); $session->set($option.'.recordsprocessed', serialize($jinput->get('recordsprocessed', 0, 'int'))); $session->set($option.'.totalline', serialize($jinput->get('currentline', 0, 'int') + $jinput->get('totalline', 0, 'int'))); // Close the file $csvifile->closeFile(false); } } /** * Create a proxy for including other models * * @copyright * @author RolandD * @todo * @see * @access protected * @param * @return * @since 3.0 */ protected function getModel($model) { return $this->getInstance($model, 'CsviModel'); } /** * Load some settings we need for the functions * This will make the data available to the child product * * @copyright * @author RolandD * @todo * @see * @access private * @param * @return * @since 3.0 */ protected function loadSettings() { $jinput = JFactory::getApplication()->input; // Load the settings $template = $jinput->get('template', null, null); $this->_avfields = $jinput->get('avfields', array(), 'array'); $this->_skip_default_value = $template->get('skip_default_value', 'general'); // Set the last field, needed for the combine function $this->_lastfield = end($jinput->get('csvifields', array(), 'array')); } /** * Load the data to import * * @copyright * @author RolandD * @todo * @see * @access protected * @param * @return * @since 3.4 */ protected function loadData() { $jinput = JFactory::getApplication()->input; $this->csvi_data = $jinput->get('csvi_data', null, null); } /** * Get the product currency from the vendor * * If the user does not use product currency we take the one from the current vendor * * @copyright * @author RolandD * @todo * @see * @access private * @param integer $vendor_id the database ID of the vendor * @return string the 3 letter product currency * @since 3.0 */ protected function productCurrency($vendor_id) { $jinput = JFactory::getApplication()->input; $csvilog = $jinput->get('csvilog', null, null); $csvilog->addDebug(JText::_('COM_CSVI_DEBUG_PRODUCT_CURRENCY')); if (array_key_exists($vendor_id, $this->_vendor_currencies)) { $product_currency = strtoupper($this->_vendor_currencies[$vendor_id]); } else { $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select('vendor_currency'); $query->from('#__virtuemart_vendors'); $query->where('virtuemart_vendor_id = '.$vendor_id); $db->setQuery($query); $product_currency = $db->loadResult(); $csvilog->addDebug(JText::_('COM_CSVI_DEBUG_PRODUCT_CURRENCY'), true); // Add the vendor currency to the cache $this->_vendor_currencies[$vendor_id] = $product_currency; } return $product_currency; } /** * Validate input data * * Checks if the field has a value, if not check if the user wants us to * use the default value * * @copyright * @author RolandD * @todo * @see * @access protected * @param string $fieldname the fieldname to validate * @param int $replaceid the ID of the replacement rule * @return true returns validated value | return false if the column count does not match * @since */ protected function validateInput($fieldname, $replaceid=null) { $jinput = JFactory::getApplication()->input; $csvilog = $jinput->get('csvilog', null, null); $template = $jinput->get('template', null, null); $newvalue = ''; // Check if the user wants ICEcat data if ($template->get('use_icecat', 'product', false, 'bool') && !empty($this->icecat_data) && (array_key_exists($fieldname, $this->icecat_data))) { $csvilog->addDebug(JText::sprintf('COM_CSVI_USE_ICECAT_FIELD', $fieldname)); $newvalue = $this->icecat_data[$fieldname]; } else if (isset($this->_csvifields[$fieldname])) { // Check if the field has a value if (array_key_exists($this->_csvifields[$fieldname]["order"], $this->csvi_data) && strlen($this->csvi_data[$this->_csvifields[$fieldname]["order"]]) > 0) { $csvilog->addDebug(JText::_('COM_CSVI_USE_FIELD_VALUE')); $newvalue = trim($this->csvi_data[$this->_csvifields[$fieldname]["order"]]); } // Field has no value, check if we can use default value else if (!$this->_skip_default_value) { $csvilog->addDebug(JText::_('COM_CSVI_USE_DEFAULT_VALUE')); $newvalue = $this->_csvifields[$fieldname]["default_value"]; } else { $csvilog->addDebug(JText::_('COM_CSVI_USE_NO_VALUE')); return ''; } } else return false; // Replace the value and return if (!empty($newvalue) && !empty($replaceid)) return CsviHelper::replaceValue($replaceid, $newvalue); else return $newvalue; } /** * Replace commas with periods for correct DB insertion of the prices * * @copyright * @author RolandD * @todo Handle multiple separators by removing them * @see * @access protected * @param string $value the value to clean up * @return string the cleaned up value with dots as separator * @since 3.0 */ protected function toPeriod($value) { $clean = str_replace(",", ".", $value); $lastpos = strrpos($clean, '.'); return str_replace('.', '' , substr($clean, 0, $lastpos)).substr($clean, $lastpos); } /** * Format a datetime format * * Format of the date is day/month/year or day-month-year. * * @copyright * @author RolandD * @todo use JDate * @see * @access protected * @param string $date the date to convert * @return integer UNIX timestamp if date is valid otherwise return 0 * @since */ protected function convertDate($date) { $new_date = preg_replace('/-|\./', '/', $date); $date_parts = explode('/', $new_date); if ((count($date_parts) == 3) && ($date_parts[0] > 0 && $date_parts[0] < 32 && $date_parts[1] > 0 && $date_parts[1] < 13 && (strlen($date_parts[2]) == 4))) { $old_date = mktime(0,0,0,$date_parts[1],$date_parts[0],$date_parts[2]); } else $old_date = 0; $date = JFactory::getDate($old_date); return $date->toMySQL(); } /** * Add the query statistics to the log * * @copyright * @author RolandD * @todo * @see * @access protected * @param * @return * @since 3.0 */ protected function queryResult() { $db = JFactory::getDBO(); return substr($db->getQuery(), 0, strpos($db->getQuery(),' ')); } /** * Clean up a price to only exist of numbers * * @copyright * @author RolandD * @todo * @see * @access protected * @param string $price the price to clean * @return float cleaned up price * @since */ protected function cleanPrice($price) { return JFilterInput::clean($this->toPeriod($price), 'float'); } /** * Load the ICEcat data for a product * * @copyright * @author RolandD * @todo * @see * @access protected * @param * @return * @since 3.0 */ protected function getIcecat() { $jinput = JFactory::getApplication()->input; $template = $jinput->get('template', null, null); if ($template->get('use_icecat', 'product')) { $csvilog = $jinput->get('csvilog', null, null); // Load the ICEcat helper if (is_null($this->_icecat)) $this->_icecat = new IcecatHelper(); // Clean the data holder $this->icecat_data = null; // Check conditions // 1. Do we have an MPN $mpn = $this->validateInput($template->get('mpn_column_name', 'product', 'product_sku')); if ($mpn) { $csvilog->addDebug(JText::sprintf('COM_CSVI_ICECAT_FOUND_REFERENCE', $mpn)); // 2. Do we have a manufacturer name $mf_name = $this->validateInput('manufacturer_name'); $csvilog->addDebug(JText::sprintf('COM_CSVI_ICECAT_FOUND_MF_NAME', $mf_name)); if ($mf_name) { // Load the ICEcat data $this->icecat_data = $this->_icecat->getData($mpn, $mf_name); } else { $csvilog->addDebug(JText::_('COM_CSVI_ICECAT_NO_MANUFACTURER')); return false; } } else { $csvilog->addDebug(JText::_('COM_CSVI_ICECAT_NO_REFERENCE')); return false; } } return false; } /** * Set a field to combine * * @copyright * @author RolandD * @todo * @see * @access protected * @param string $data the data to be combined * @param string $fieldname the name of the current field * @return * @since 3.0 */ protected function setCombineField($data, $fieldname=null) { if (!empty($data)) { // Add the data to the array $this->combine_fields[] = $data; // Set the fieldname the data is for if (empty($this->combine_settings['fieldname'])) $this->combine_settings['fieldname'] = $fieldname; switch ($fieldname) { case 'category_path': $jinput = JFactory::getApplication()->input; $template = $jinput->get('template', null, null); $this->combine_settings['separator'] = $template->get('category_separator', 'general', '/'); break; } } } /** * Get the combined fields * * @copyright * @author RolandD * @todo * @see * @access protected * @param * @return string the space separated combined data * @since 3.0 */ protected function getCombineField() { // Get the combined data $data = implode($this->combine_settings['separator'], $this->combine_fields); // Empty some settings $this->combine_fields = array(); $this->combine_settings['fieldname'] = null; $this->combine_settings['separator'] = ' '; // Return the data return $data; } }
©
2018.