Index: trunk/core/units/general/cat_dbitem_export.php =================================================================== diff -u -N -r6093 -r6583 --- trunk/core/units/general/cat_dbitem_export.php (.../cat_dbitem_export.php) (revision 6093) +++ trunk/core/units/general/cat_dbitem_export.php (.../cat_dbitem_export.php) (revision 6583) @@ -364,34 +364,86 @@ function getCustomSQL() { $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); - + $custom_sql = ''; foreach ($this->customFields as $custom_id => $custom_name) { $custom_sql .= 'custom_data.'.$ml_formatter->LangFieldName('cust_'.$custom_id).' AS cust_'.$custom_name.', '; } - + return preg_replace('/(.*), /', '\\1', $custom_sql); } - + + function getPlainExportSQL($count_only = false) { + if ($count_only && isset($this->exportOptions['ForceCountSQL'])) return $this->exportOptions['ForceCountSQL']; + if (!$count_only && isset($this->exportOptions['ForceSelectSQL'])) return $this->exportOptions['ForceSelectSQL']; + + $items_list =& $this->Application->recallObject($this->curItem->Prefix.'.export-items-list', $this->curItem->Prefix.'_List'); + $items_list->SetPerPage(-1); + return $items_list->GetSelectSQL($count_only); + + + if ($this->exportOptions['export_ids'] === false) + { + // get links from current category & all it's subcategories + $join_clauses = Array(); + + $custom_sql = $this->getCustomSQL(); + if ($custom_sql) { + $custom_table = $this->Application->getUnitOption($this->curItem->Prefix.'-cdata', 'TableName'); + $join_clauses[$custom_table.' custom_data'] = 'custom_data.ResourceId = item_table.ResourceId'; + } + + $sql = 'SELECT item_table.*'.($custom_sql ? ', '.$custom_sql : '').' + FROM '.$this->curItem->TableName.' item_table'; + + foreach ($join_clauses as $table_name => $join_expression) { + $sql .= ' LEFT JOIN '.$table_name.' ON '.$join_expression; + } + $sql .= ' WHERE 1'; + + $sql .= ' ORDER BY item_table.'.$this->curItem->IDField.' ASC'; // NEW + } + else { + // get only selected links + $sql = 'SELECT item_table.* + FROM '.$this->curItem->TableName.' item_table + WHERE '.$this->curItem->IDField.' IN ('.implode(',', $this->exportOptions['export_ids']).')'; + } + + if (!$count_only) + { + $sql .= ' LIMIT '.$this->exportOptions['start_from'].','.EXPORT_STEP; + } + else { + $sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql); + } + + return $sql; + } + function getExportSQL($count_only = false) { + if (!$this->Application->getUnitOption($this->curItem->Prefix, 'CatalogItem')) { + return $this->GetPlainExportSQL($count_only); // in case this is not a CategoryItem + } + if ($this->exportOptions['export_ids'] === false) { // get links from current category & all it's subcategories $join_clauses = Array(); - + $custom_sql = $this->getCustomSQL(); if ($custom_sql) { $custom_table = $this->Application->getUnitOption($this->curItem->Prefix.'-cdata', 'TableName'); $join_clauses[$custom_table.' custom_data'] = 'custom_data.ResourceId = item_table.ResourceId'; } - + $join_clauses[TABLE_PREFIX.'CategoryItems ci'] = 'ci.ItemResourceId = item_table.ResourceId'; $join_clauses[TABLE_PREFIX.'Category c'] = 'c.CategoryId = ci.CategoryId'; - + $sql = 'SELECT item_table.*, ci.CategoryId'.($custom_sql ? ', '.$custom_sql : '').' FROM '.$this->curItem->TableName.' item_table'; - + foreach ($join_clauses as $table_name => $join_expression) { $sql .= ' LEFT JOIN '.$table_name.' ON '.$join_expression; } @@ -475,7 +527,7 @@ $this->curItem->SetDBFieldsFromHash($record_info); $this->setCurrentID(); $this->curItem->raiseEvent('OnAfterItemLoad', $this->curItem->GetID() ); - + $data_array = Array(); foreach ($this->exportFields as $export_field) { @@ -650,7 +702,7 @@ } $this->curItem->Clear(); $this->customFields = $this->Application->getUnitOption($event->Prefix, 'CustomFields'); - + if (isset($record_data)) { $this->setImportData($record_data); } @@ -679,7 +731,7 @@ if (is_null($lang_prefix)) { $lang_prefix = 'l'.$this->Application->GetVar('m_lang').'_'; } - + foreach ($this->curItem->CategoryPath as $category_index => $category_name) { if (!$category_name) continue; $category_key = crc32( implode(':', array_slice($this->curItem->CategoryPath, 0, $category_index + 1) ) ); @@ -766,7 +818,7 @@ else { $where_clause .= '(item_table.`'.$field_name.'` = '.$this->Conn->qstr($field_value).') AND '; } - + } $where_clause = preg_replace('/(.*) AND $/', '\\1', $where_clause); @@ -777,7 +829,7 @@ $parent_path = $this->getParentPath($category_id); $where_clause = '(c.ParentPath LIKE "'.$parent_path.'%") AND '.$where_clause; } - + $cdata_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName'); $sql = 'SELECT '.$this->curItem->IDField.' FROM '.$this->curItem->TableName.' item_table @@ -828,11 +880,11 @@ /*function saveLog($msg) { static $first_time = true; - + $fp = fopen(FULL_PATH.'/sqls.log', $first_time ? 'w' : 'a'); fwrite($fp, $msg."\n"); fclose($fp); - + $first_time = false; }*/ @@ -1069,6 +1121,277 @@ { return unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options')); } + + /** + * Sets correct available & export fields + * + * @param kEvent $event + */ + function prepareExportColumns(&$event) + { + $object =& $event->getObject( Array('skip_autoload' => true) ); + + $available_columns = Array(); + + if ($this->Application->getUnitOption($event->Prefix, 'CatalogItem')) { + // category field (mixed) + $available_columns['__CATEGORY__CategoryPath'] = 'CategoryPath'; + + if ($event->Special == 'import') { + // category field (separated fields) + $max_level = $this->Application->ConfigValue('MaxImportCategoryLevels'); + $i = 0; + while ($i < $max_level) { + $available_columns['__CATEGORY__Category'.($i + 1)] = 'Category'.($i + 1); + $i++; + } + } + } + + // db fields + foreach ($object->Fields as $field_name => $field_options) + { + if (!$object->SkipField($field_name)) + { + $available_columns[$field_name] = $field_name.(getArrayValue($field_options, 'required') ? '*' : ''); + } + } + + $handler =& $this->Application->recallObject($event->Prefix.'_EventHandler'); + $available_columns = array_merge_recursive2($available_columns, $handler->getCustomExportColumns($event)); + + // custom fields + foreach ($object->customFields as $custom_id => $custom_name) + { + $available_columns['__CUSTOM__'.$custom_name] = $custom_name; + } + + // columns already in use + $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + if ($items_info) + { + list($item_id, $field_values) = each($items_info); + $export_keys = $field_values['ExportColumns']; + $export_keys = $export_keys ? explode('|', substr($export_keys, 1, -1) ) : Array(); + } + else { + $export_keys = Array(); + } + + $export_columns = Array(); + foreach ($export_keys as $field_key) + { + $field_name = $this->getExportField($field_key); + $export_columns[$field_key] = $field_name; + unset($available_columns[$field_key]); + } + + $options = $object->GetFieldOptions('ExportColumns'); + $options['options'] = $export_columns; + $object->SetFieldOptions('ExportColumns', $options); + + $options = $object->GetFieldOptions('AvailableColumns'); + $options['options'] = $available_columns; + $object->SetFieldOptions('AvailableColumns', $options); + + $this->updateImportFiles($event); + $this->PrepareExportPresets($event); + } + + function PrepareExportPresets(&$event) + { + $object =& $event->getObject( Array('skip_autoload' => true) ); + $options = $object->GetFieldOptions('ExportPresets'); + + $user =& $this->Application->recallObject('u'); + $export_settings = $user->getPersistantVar('export_settings'); + if (!$export_settings) return ; + $export_settings = unserialize($export_settings); + + if (!isset($export_settings[$event->Prefix])) return ; + + + $export_presets = array(''=>''); + foreach ($export_settings[$event->Prefix] as $key => $val) { + $export_presets[implode('|', $val['ExportColumns'])] = $key; + } + + $options['options'] = $export_presets; + $object->SetFieldOptions('ExportPresets', $options); + } + + function getExportField($field_key) + { + $prepends = Array('__CUSTOM__', '__CATEGORY__'); + foreach ($prepends as $prepend) + { + if (substr($field_key, 0, strlen($prepend) ) == $prepend) + { + $field_key = substr($field_key, strlen($prepend), strlen($field_key) ); + break; + } + } + return $field_key; + } + + /** + * Updates uploaded files list + * + * @param kEvent $event + */ + function updateImportFiles(&$event) + { + if ($event->Special != 'import') { + return false; + } + + $object =& $event->getObject(); + + $import_filenames = Array(); + + if ($folder_handle = opendir(EXPORT_PATH)) { + while (false !== ($file = readdir($folder_handle))) { + if (is_dir(EXPORT_PATH.'/'.$file) || substr($file, 0, 1) == '.' || strtolower($file) == 'cvs' || strtolower($file) == 'dummy' || filesize(EXPORT_PATH.'/'.$file) == 0) continue; + + $file_size = formatSize( filesize(EXPORT_PATH.'/'.$file) ); + $import_filenames[$file] = $file.' ('.$file_size.')'; + } + closedir($folder_handle); + } + + $options = $object->GetFieldOptions('ImportLocalFilename'); + $options['options'] = $import_filenames; + $object->SetFieldOptions('ImportLocalFilename', $options); + } + + /** + * Returns module folder + * + * @param kEvent $event + * @return string + */ + function getModuleFolder(&$event) + { + return $this->Application->getUnitOption($event->Prefix, 'ModuleFolder'); + } + + /** + * Export form validation & processing + * + * @param kEvent $event + */ + function OnExportBegin(&$event) + { + $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + if (!$items_info) + { + $items_info = unserialize( $this->Application->RecallVar($event->getPrefixSpecial().'_ItemsInfo') ); + $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); + } + + list($item_id, $field_values) = each($items_info); + + $object =& $event->getObject( Array('skip_autoload' => true) ); + $object->SetFieldsFromHash($field_values); + $field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!! + + $object->setID($item_id); + $this->setRequiredFields($event); + + $export_object =& $this->Application->recallObject('CatItemExportHelper'); + + // save export/import options + if ($event->Special == 'export') + { + $export_ids = $this->Application->RecallVar($event->Prefix.'_export_ids'); + $export_cats_ids = $this->Application->RecallVar($event->Prefix.'_export_cats_ids'); + + // used for multistep export + $field_values['export_ids'] = $export_ids ? explode(',', $export_ids) : false; + $field_values['export_cats_ids'] = $export_cats_ids ? explode(',', $export_cats_ids) : Array( $this->Application->GetVar('m_cat_id') ); + } + + $field_values['ExportColumns'] = $field_values['ExportColumns'] ? explode('|', substr($field_values['ExportColumns'], 1, -1) ) : Array(); + $field_values['start_from'] = 0; + + $this->Application->HandleEvent($nevent, $event->Prefix.':OnBeforeExportBegin', array('options'=>$field_values)); + $field_values = $nevent->getEventParam('options'); + + $export_object->saveOptions($event, $field_values); + + if( $export_object->verifyOptions($event) ) + { + if ($object->GetDBField('ExportSavePreset')) { + $name = $object->GetDBField('ExportPresetName'); + $user =& $this->Application->recallObject('u'); + $export_settings = $user->getPersistantVar('export_settings'); + $export_settings = $export_settings ? unserialize($export_settings) : array(); + $export_settings[$event->Prefix][$name] = $field_values; + $user->setPersistantVar('export_settings', serialize($export_settings)); + } + + $progress_t = $this->Application->RecallVar('export_progress_t'); + if ($progress_t) { + $this->Application->RemoveVar('export_progress_t'); + } + else { + $progress_t = $export_object->getModuleFolder($event).'/'.$event->Special.'_progress'; + } + $event->redirect = $progress_t; + } + else + { + // make uploaded file local & change source selection + $filename = getArrayValue($field_values, 'ImportFilename'); + if ($filename) { + $export_object->updateImportFiles($event); + $object->SetDBField('ImportSource', 2); + $field_values['ImportSource'] = 2; + $object->SetDBField('ImportLocalFilename', $filename); + $field_values['ImportLocalFilename'] = $filename; + $export_object->saveOptions($event, $field_values); + } + + $event->status = erFAIL; + $event->redirect = false; + } + } + + /** + * set required fields based on import or export params + * + * @param kEvent $event + */ + function setRequiredFields(&$event) + { + $required_fields['common'] = Array('FieldsSeparatedBy', 'LineEndings', 'CategoryFormat'); + + $required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns'); + + $object =& $event->getObject(); + if ($object->GetDBField('ExportSavePreset')) { + $required_fields['export'][] = 'ExportPresetName'; + } + + $required_fields['import'] = Array('FieldTitles', 'ImportSource', 'CheckDuplicatesMethod'); // ImportFilename, ImportLocalFilename + + if ($event->Special == 'import') + { + $import_source = Array(1 => 'ImportFilename', 2 => 'ImportLocalFilename'); + $used_field = $import_source[ $object->GetDBField('ImportSource') ]; + + $required_fields[$event->Special][] = $used_field; + $object->Fields[$used_field]['error_field'] = 'ImportSource'; + + if ($object->GetDBField('FieldTitles') == 2) $required_fields[$event->Special][] = 'ExportColumns'; // manual field titles + } + + $required_fields = array_merge($required_fields['common'], $required_fields[$event->Special]); + foreach ($required_fields as $required_field) { + $object->setRequired($required_field, true); + } + } + } ?>