Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1247660
cat_dbitem_export.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Nov 21, 5:47 PM
Size
30 KB
Mime Type
text/x-php
Expires
Sun, Nov 23, 5:47 PM (1 d, 10 h)
Engine
blob
Format
Raw Data
Handle
810681
Attached To
rINP In-Portal
cat_dbitem_export.php
View Options
<?php
define
(
'EXPORT_STEP'
,
200
);
// export by 200 items (e.g. links)
define
(
'IMPORT_CHUNK'
,
10240
);
// 10240); //30720); //50120); // 5 KB
define
(
'IMPORT_TEMP'
,
1
);
define
(
'IMPORT_LIVE'
,
2
);
class
kCatDBItemExportHelper
extends
kHelper
{
var
$false
=
false
;
var
$cache
=
Array
();
/**
* Allows to find out what items are new in cache
*
* @var Array
*/
var
$cacheStatus
=
Array
();
var
$cacheTable
=
''
;
var
$exportFields
=
Array
();
/**
* Export options
*
* @var Array
*/
var
$exportOptions
=
Array
();
/**
* Item beeing currenly exported
*
* @var kCatDBItem
*/
var
$curItem
=
null
;
/**
* Dummy category object
*
* @var CategoriesItem
*/
var
$dummyCategory
=
null
;
/**
* Pointer to opened file
*
* @var resource
*/
var
$filePointer
=
null
;
function
kCatDBItemExportHelper
()
{
parent
::
kHelper
();
$this
->
cacheTable
=
TABLE_PREFIX
.
'ImportCache'
;
}
/**
* Returns value from cache if found or false otherwise
*
* @param string $type
* @param int $key
* @return mixed
*/
function
getFromCache
(
$type
,
$key
)
{
return
getArrayValue
(
$this
->
cache
,
$type
,
$key
);
}
/**
* Adds value to be cached
*
* @param string $type
* @param int $key
* @param mixed $value
*/
function
addToCache
(
$type
,
$key
,
$value
,
$is_new
=
true
)
{
// if (!isset($this->cache[$type])) $this->cache[$type] = Array();
$this
->
cache
[
$type
][
$key
]
=
$value
;
if
(
$is_new
)
{
$this
->
cacheStatus
[
$type
][
$key
]
=
true
;
}
}
function
storeCache
(
$cache_types
)
{
$cache_types
=
explode
(
','
,
$cache_types
);
$values_sql
=
''
;
foreach
(
$cache_types
as
$cache_type
)
{
$sql_mask
=
'('
.
$this
->
Conn
->
qstr
(
$cache_type
).
',%s,%s),'
;
$cache
=
getArrayValue
(
$this
->
cacheStatus
,
$cache_type
);
if
(!
$cache
)
$cache
=
Array
();
foreach
(
$cache
as
$var_name
=>
$cache_status
)
{
$var_value
=
$this
->
cache
[
$cache_type
][
$var_name
];
$values_sql
.=
sprintf
(
$sql_mask
,
$this
->
Conn
->
qstr
(
$var_name
),
$this
->
Conn
->
qstr
(
$var_value
)
);
}
}
$values_sql
=
preg_replace
(
'/(.*),$/'
,
'
\\
1'
,
$values_sql
);
if
(
$values_sql
)
{
$sql
=
'INSERT INTO '
.
$this
->
cacheTable
.
'(`CacheName`,`VarName`,`VarValue`) VALUES '
.
$values_sql
;
$this
->
Conn
->
Query
(
$sql
);
}
}
function
loadCache
()
{
$sql
=
'SELECT * FROM '
.
$this
->
cacheTable
;
$records
=
$this
->
Conn
->
Query
(
$sql
);
$this
->
cache
=
Array
();
foreach
(
$records
as
$record
)
{
$this
->
addToCache
(
$record
[
'CacheName'
],
$record
[
'VarName'
],
$record
[
'VarValue'
],
false
);
}
}
/**
* Fill required fields with dummy values
*
* @param kEvent $event
*/
function
fillRequiredFields
(&
$event
,
&
$object
,
$set_status
=
false
)
{
if
(
$object
==
$this
->
false
)
{
$object
=&
$event
->
getObject
();
}
$has_empty
=
false
;
$fields
=
array_keys
(
$object
->
Fields
);
foreach
(
$fields
as
$field_name
)
{
$field_options
=&
$object
->
Fields
[
$field_name
];
if
(
isset
(
$object
->
VirtualFields
[
$field_name
])
||
!
getArrayValue
(
$field_options
,
'required'
)
)
continue
;
if
(
$object
->
GetDBField
(
$field_name
)
)
continue
;
$formatter_class
=
getArrayValue
(
$field_options
,
'formatter'
);
if
(
$formatter_class
)
// not tested
{
$formatter
=&
$this
->
Application
->
recallObject
(
$formatter_class
);
$sample_value
=
$formatter
->
GetSample
(
$field_name
,
$field_options
,
$object
);
}
$has_empty
=
true
;
$object
->
SetDBField
(
$field_name
,
isset
(
$sample_value
)
&&
$sample_value
?
$sample_value
:
'no value'
);
}
if
(
$set_status
&&
$has_empty
)
{
$object
->
SetDBField
(
'Status'
,
0
);
}
}
/**
* Verifies that all user entered export params are correct
*
* @param kEvent $event
*/
function
verifyOptions
(&
$event
)
{
if
(
$this
->
Application
->
RecallVar
(
$event
->
getPrefixSpecial
().
'_ForceNotValid'
))
{
$this
->
Application
->
StoreVar
(
$event
->
getPrefixSpecial
().
'_ForceNotValid'
,
0
);
return
false
;
}
$this
->
fillRequiredFields
(
$event
,
$this
->
false
);
$object
=&
$event
->
getObject
();
$cross_unique_fields
=
Array
(
'FieldsSeparatedBy'
,
'FieldsEnclosedBy'
);
if
((
$object
->
GetDBField
(
'CategoryFormat'
)
==
1
)
||
(
$event
->
Special
==
'import'
))
// in one field
{
$object
->
setRequired
(
'CategorySeparator'
,
true
);
$cross_unique_fields
[]
=
'CategorySeparator'
;
}
$ret
=
$object
->
Validate
();
// check if cross unique fields has no same values
foreach
(
$cross_unique_fields
as
$field_index
=>
$field_name
)
{
if
(
getArrayValue
(
$object
->
FieldErrors
,
$field_name
,
'pseudo'
)
==
'required'
)
continue
;
$check_fields
=
$cross_unique_fields
;
unset
(
$check_fields
[
$field_index
]);
foreach
(
$check_fields
as
$check_field
)
{
if
(
$object
->
GetDBField
(
$field_name
)
==
$object
->
GetDBField
(
$check_field
))
{
$object
->
SetError
(
$check_field
,
'unique'
);
}
}
}
if
(
$event
->
Special
==
'import'
)
{
$this
->
exportOptions
=
$this
->
loadOptions
(
$event
);
$automatic_fields
=
(
$object
->
GetDBField
(
'FieldTitles'
)
==
1
);
$object
->
setRequired
(
'ExportColumns'
,
!
$automatic_fields
);
$category_prefix
=
'__CATEGORY__'
;
if
(
$automatic_fields
&&
(
$this
->
exportOptions
[
'SkipFirstRow'
])
)
{
$this
->
openFile
(
$event
);
$this
->
exportOptions
[
'ExportColumns'
]
=
$this
->
readRecord
();
$this
->
closeFile
();
// remove additional (non-parseble columns)
foreach
(
$this
->
exportOptions
[
'ExportColumns'
]
as
$field_index
=>
$field_name
)
{
if
(!
$this
->
validateField
(
$field_name
,
$object
))
{
unset
(
$this
->
exportOptions
[
'ExportColumns'
][
$field_index
]);
}
}
$category_prefix
=
''
;
}
// 1. check, that we have column definitions
if
(!
$this
->
exportOptions
[
'ExportColumns'
])
{
$object
->
setError
(
'ExportColumns'
,
'required'
);
$ret
=
false
;
}
else
{
// 1.1. check that all required fields are present in imported file
$missing_columns
=
Array
();
foreach
(
$object
->
Fields
as
$field_name
=>
$field_options
)
{
if
(
$object
->
SkipField
(
$field_name
))
continue
;
if
(
getArrayValue
(
$field_options
,
'required'
)
&&
!
in_array
(
$field_name
,
$this
->
exportOptions
[
'ExportColumns'
])
)
{
$missing_columns
[]
=
$field_name
;
$object
->
setError
(
'ExportColumns'
,
'required_fields_missing'
,
'la_error_RequiredColumnsMissing'
);
$ret
=
false
;
}
}
if
(!
$ret
&&
$this
->
Application
->
isDebugMode
())
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Missing required for import/export:'
);
$this
->
Application
->
Debugger
->
dumpVars
(
$missing_columns
);
}
}
// 2. check, that we have only mixed category field or only separated category fields
$category_found
[
'mixed'
]
=
false
;
$category_found
[
'separated'
]
=
false
;
foreach
(
$this
->
exportOptions
[
'ExportColumns'
]
as
$import_field
)
{
if
(
preg_match
(
'/^'
.
$category_prefix
.
'Category(Path|[0-9]+)/'
,
$import_field
,
$rets
))
{
$category_found
[
$rets
[
1
]
==
'Path'
?
'mixed'
:
'separated'
]
=
true
;
}
}
if
(
$category_found
[
'mixed'
]
&&
$category_found
[
'separated'
])
{
$object
->
SetError
(
'ExportColumns'
,
'unique_category'
,
'la_error_unique_category_field'
);
$ret
=
false
;
}
// 3. check, that duplicates check fields are selected & present in imported fields
if
(
$this
->
exportOptions
[
'ReplaceDuplicates'
])
{
if
(
$this
->
exportOptions
[
'CheckDuplicatesMethod'
]
==
1
)
{
$check_fields
=
Array
(
$object
->
IDField
);
}
else
{
$check_fields
=
$this
->
exportOptions
[
'DuplicateCheckFields'
]
?
explode
(
'|'
,
substr
(
$this
->
exportOptions
[
'DuplicateCheckFields'
],
1
,
-
1
))
:
Array
();
$object
=&
$event
->
getObject
();
$language_id
=
$this
->
Application
->
GetDefaultLanguageId
();
foreach
(
$check_fields
as
$index
=>
$check_field
)
{
foreach
(
$object
->
Fields
as
$field_name
=>
$field_options
)
{
if
(
$field_name
==
'l'
.
$language_id
.
'_'
.
$check_field
)
{
$check_fields
[
$index
]
=
'l'
.
$language_id
.
'_'
.
$check_field
;
break
;
}
}
}
}
$this
->
exportOptions
[
'DuplicateCheckFields'
]
=
$check_fields
;
if
(!
$check_fields
)
{
$object
->
setError
(
'CheckDuplicatesMethod'
,
'required'
);
$ret
=
false
;
}
else
{
foreach
(
$check_fields
as
$check_field
)
{
if
(!
in_array
(
$check_field
,
$this
->
exportOptions
[
'ExportColumns'
]))
{
$object
->
setError
(
'ExportColumns'
,
'required'
);
$ret
=
false
;
break
;
}
}
}
}
$this
->
saveOptions
(
$event
);
}
return
$ret
;
}
/**
* Returns filename to read import data from
*
* @return string
*/
function
getImportFilename
()
{
if
(
$this
->
exportOptions
[
'ImportSource'
]
==
1
)
{
$ret
=
$this
->
exportOptions
[
'ImportFilename'
];
// ['name']; commented by Kostja
}
else
{
$ret
=
$this
->
exportOptions
[
'ImportLocalFilename'
];
}
return
EXPORT_PATH
.
'/'
.
$ret
;
}
/**
* Returns filename to write export data to
*
* @return string
*/
function
getExportFilename
()
{
return
EXPORT_PATH
.
'/'
.
$this
->
exportOptions
[
'ExportFilename'
].
'.'
.
$this
->
getFileExtension
();
}
/**
* Opens file required for export/import operations
*
* @param kEvent $event
*/
function
openFile
(&
$event
)
{
if
(
$event
->
Special
==
'export'
)
{
$write_mode
=
(
$this
->
exportOptions
[
'start_from'
]
==
0
)
?
'w'
:
'a'
;
$this
->
filePointer
=
fopen
(
$this
->
getExportFilename
(),
$write_mode
);
}
else
{
$this
->
filePointer
=
fopen
(
$this
->
getImportFilename
(),
'r'
);
}
// skip UTF-8 BOM Modifier
$first_chars
=
fread
(
$this
->
filePointer
,
3
);
if
(
bin2hex
(
$first_chars
)
!=
'efbbbf'
)
{
fseek
(
$this
->
filePointer
,
0
);
}
}
/**
* Closes opened file
*
*/
function
closeFile
()
{
fclose
(
$this
->
filePointer
);
}
function
getExportSQL
(
$count_only
=
false
)
{
if
(
$this
->
exportOptions
[
'export_ids'
]
===
false
)
{
// get links from current category & all it's subcategories
$join_clauses
=
Array
();
$custom_sql
=
''
;
$custom_table
=
$this
->
Application
->
getUnitOption
(
$this
->
curItem
->
Prefix
.
'-cdata'
,
'TableName'
);
if
(
$custom_table
)
{
$ml_formatter
=&
$this
->
Application
->
recallObject
(
'kMultiLanguage'
);
$custom_fields
=
$this
->
Application
->
getUnitOption
(
$this
->
curItem
->
Prefix
,
'CustomFields'
);
foreach
(
$custom_fields
as
$custom_id
=>
$custom_name
)
{
$custom_sql
.=
'custom_data.'
.
$ml_formatter
->
LangFieldName
(
'cust_'
.
$custom_id
).
' AS cust_'
.
$custom_name
.
','
;
}
$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.*, '
.
$custom_sql
.
' ci.CategoryId
FROM '
.
$this
->
curItem
->
TableName
.
' item_table'
;
foreach
(
$join_clauses
as
$table_name
=>
$join_expression
)
{
$sql
.=
' LEFT JOIN '
.
$table_name
.
' ON '
.
$join_expression
;
}
$sql
.=
' WHERE '
;
if
(
$this
->
exportOptions
[
'export_cats_ids'
][
0
]
==
0
)
{
$sql
.=
'1'
;
}
else
{
foreach
(
$this
->
exportOptions
[
'export_cats_ids'
]
as
$category_id
)
{
$sql
.=
'(c.ParentPath LIKE "%|'
.
$category_id
.
'|%") OR '
;
}
$sql
=
preg_replace
(
'/(.*) OR $/'
,
'
\\
1'
,
$sql
);
}
$sql
.=
' ORDER BY ci.PrimaryCat DESC'
;
// NEW
}
else
{
// get only selected links
$sql
=
'SELECT item_table.*, '
.
$this
->
exportOptions
[
'export_cats_ids'
][
0
].
' AS CategoryId
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
;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
performExport
(&
$event
)
{
$this
->
exportOptions
=
$this
->
loadOptions
(
$event
);
$this
->
exportFields
=
$this
->
exportOptions
[
'ExportColumns'
];
$this
->
curItem
=&
$event
->
getObject
(
Array
(
'skip_autoload'
=>
true
)
);
$this
->
openFile
(
$event
);
if
(
$this
->
exportOptions
[
'start_from'
]
==
0
)
// first export step
{
if
(!
getArrayValue
(
$this
->
exportOptions
,
'IsBaseCategory'
))
{
$this
->
exportOptions
[
'IsBaseCategory'
]
=
0
;
}
if
(
$this
->
exportOptions
[
'IsBaseCategory'
]
)
{
$sql
=
'SELECT CachedNavbar
FROM '
.
TABLE_PREFIX
.
'Category
WHERE CategoryId = '
.
$this
->
Application
->
GetVar
(
'm_cat_id'
);
$this
->
exportOptions
[
'BaseLevel'
]
=
substr_count
(
$this
->
Conn
->
GetOne
(
$sql
),
'>'
)
+
1
;
// level to cut from other categories
}
// 1. export field titles if required
if
(
$this
->
exportOptions
[
'IncludeFieldTitles'
])
{
$data_array
=
Array
();
foreach
(
$this
->
exportFields
as
$export_field
)
{
$data_array
=
array_merge
(
$data_array
,
$this
->
getFieldCaption
(
$export_field
));
}
$this
->
writeRecord
(
$data_array
);
}
$this
->
exportOptions
[
'total_records'
]
=
$this
->
Conn
->
GetOne
(
$this
->
getExportSQL
(
true
)
);
}
// 2. export data
$records
=
$this
->
Conn
->
Query
(
$this
->
getExportSQL
()
);
$records_exported
=
0
;
foreach
(
$records
as
$record_info
)
{
$this
->
curItem
->
Clear
();
$this
->
curItem
->
SetDBFieldsFromHash
(
$record_info
);
$this
->
setCurrentID
();
$this
->
curItem
->
raiseEvent
(
'OnAfterItemLoad'
,
$this
->
curItem
->
GetID
()
);
$data_array
=
Array
();
foreach
(
$this
->
exportFields
as
$export_field
)
{
$data_array
=
array_merge
(
$data_array
,
$this
->
getFieldValue
(
$export_field
)
);
}
$this
->
writeRecord
(
$data_array
);
$records_exported
++;
}
$this
->
closeFile
();
$this
->
exportOptions
[
'start_from'
]
+=
$records_exported
;
$this
->
saveOptions
(
$event
);
return
$this
->
exportOptions
;
}
function
getItemFields
()
{
// just in case dummy user selected automtic mode & moved columns too :(
return
array_merge
(
$this
->
curItem
->
Fields
[
'AvailableColumns'
][
'options'
],
$this
->
curItem
->
Fields
[
'ExportColumns'
][
'options'
]);
}
/**
* Checks if field really belongs to importable field list
*
* @param string $field_name
* @param kCatDBItem $object
* @return bool
*/
function
validateField
(
$field_name
,
&
$object
)
{
// 1. convert custom field
$field_name
=
preg_replace
(
'/^Custom_(.*)/'
,
'__CUSTOM__
\\
1'
,
$field_name
);
// 2. convert category field (mixed version & serparated version)
$field_name
=
preg_replace
(
'/^Category(Path|[0-9]+)/'
,
'__CATEGORY__Category
\\
1'
,
$field_name
);
$valid_fields
=
$object
->
getPossibleExportColumns
();
return
isset
(
$valid_fields
[
$field_name
])
||
isset
(
$valid_fields
[
'__VIRTUAL__'
.
$field_name
]);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
performImport
(&
$event
)
{
if
(!
$this
->
exportOptions
)
{
// load import options in case if not previously loaded in verification function
$this
->
exportOptions
=
$this
->
loadOptions
(
$event
);
}
$backup_category_id
=
$this
->
Application
->
GetVar
(
'm_cat_id'
);
$this
->
Application
->
SetVar
(
'm_cat_id'
,
(
int
)
$this
->
Application
->
RecallVar
(
'ImportCategory'
)
);
$this
->
openFile
(
$event
);
$bytes_imported
=
0
;
if
(
$this
->
exportOptions
[
'start_from'
]
==
0
)
// first export step
{
// 1st time run
if
(
$this
->
exportOptions
[
'SkipFirstRow'
])
{
$this
->
readRecord
();
$this
->
exportOptions
[
'start_from'
]
=
ftell
(
$this
->
filePointer
);
$bytes_imported
=
ftell
(
$this
->
filePointer
);
}
$current_category_id
=
$this
->
Application
->
GetVar
(
'm_cat_id'
);
if
(
$current_category_id
>
0
)
{
$sql
=
'SELECT ParentPath FROM '
.
TABLE_PREFIX
.
'Category WHERE CategoryId = '
.
$current_category_id
;
$this
->
exportOptions
[
'ImportCategoryPath'
]
=
$this
->
Conn
->
GetOne
(
$sql
);
}
else
{
$this
->
exportOptions
[
'ImportCategoryPath'
]
=
''
;
}
$this
->
exportOptions
[
'total_records'
]
=
filesize
(
$this
->
getImportFilename
());
}
else
{
$this
->
loadCache
();
}
$this
->
exportFields
=
$this
->
exportOptions
[
'ExportColumns'
];
$this
->
addToCache
(
'category_parent_path'
,
$this
->
Application
->
GetVar
(
'm_cat_id'
),
$this
->
exportOptions
[
'ImportCategoryPath'
]);
// 2. import data
$this
->
dummyCategory
=&
$this
->
Application
->
recallObject
(
'c.-tmpitem'
,
'c'
,
Array
(
'skip_autoload'
=>
true
));
fseek
(
$this
->
filePointer
,
$this
->
exportOptions
[
'start_from'
]);
while
((
$bytes_imported
<
IMPORT_CHUNK
)
&&
!
feof
(
$this
->
filePointer
))
{
$data
=
$this
->
readRecord
();
if
(
$data
)
{
if
(
$this
->
exportOptions
[
'ReplaceDuplicates'
])
{
// set fields used as keys for replace duplicates code
$this
->
resetImportObject
(
$event
,
IMPORT_TEMP
,
$data
);
}
$this
->
processCurrentItem
(
$event
,
$data
);
}
$bytes_imported
=
ftell
(
$this
->
filePointer
)
-
$this
->
exportOptions
[
'start_from'
];
}
$this
->
closeFile
();
$this
->
Application
->
SetVar
(
'm_cat_id'
,
$backup_category_id
);
$this
->
exportOptions
[
'start_from'
]
+=
$bytes_imported
;
$this
->
storeCache
(
'new_ids'
);
$this
->
saveOptions
(
$event
);
if
(
$this
->
exportOptions
[
'start_from'
]
==
$this
->
exportOptions
[
'total_records'
])
{
$this
->
Conn
->
Query
(
'TRUNCATE TABLE '
.
$this
->
cacheTable
);
}
return
$this
->
exportOptions
;
}
function
setCurrentID
()
{
$this
->
curItem
->
setID
(
$this
->
curItem
->
GetDBField
(
$this
->
curItem
->
IDField
)
);
}
function
setFieldValue
(
$field_index
,
$value
)
{
if
(
empty
(
$value
))
{
$value
=
null
;
}
$field_name
=
getArrayValue
(
$this
->
exportFields
,
$field_index
);
if
(
$field_name
==
'ResourceId'
)
{
return
false
;
}
if
(
substr
(
$field_name
,
0
,
7
)
==
'Custom_'
)
{
$field_name
=
'cust_'
.
substr
(
$field_name
,
7
);
$this
->
curItem
->
SetField
(
$field_name
,
$value
);
}
elseif
(
$field_name
==
'CategoryPath'
||
$field_name
==
'__CATEGORY__CategoryPath'
)
{
$this
->
curItem
->
CategoryPath
=
$value
?
explode
(
$this
->
exportOptions
[
'CategorySeparator'
],
$value
)
:
Array
();
}
elseif
(
substr
(
$field_name
,
0
,
8
)
==
'Category'
)
{
$this
->
curItem
->
CategoryPath
[
(
int
)
substr
(
$field_name
,
8
)
-
1
]
=
$value
;
}
elseif
(
substr
(
$field_name
,
0
,
20
)
==
'__CATEGORY__Category'
)
{
$this
->
curItem
->
CategoryPath
[
(
int
)
substr
(
$field_name
,
20
)
]
=
$value
;
}
elseif
(
substr
(
$field_name
,
0
,
11
)
==
'__VIRTUAL__'
)
{
$field_name
=
substr
(
$field_name
,
11
);
$this
->
curItem
->
SetField
(
$field_name
,
$value
);
}
else
{
$this
->
curItem
->
SetField
(
$field_name
,
$value
);
}
$pseudo_error
=
getArrayValue
(
$this
->
curItem
->
FieldErrors
,
$field_name
,
'pseudo'
);
if
(
$pseudo_error
)
{
$this
->
curItem
->
SetDBField
(
$field_name
,
null
);
unset
(
$this
->
curItem
->
FieldErrors
[
$field_name
]);
}
}
function
resetImportObject
(&
$event
,
$object_type
,
$record_data
=
null
)
{
switch
(
$object_type
)
{
case
IMPORT_TEMP
:
$this
->
curItem
=&
$event
->
getObject
(
Array
(
'skip_autoload'
=>
true
)
);
break
;
case
IMPORT_LIVE
:
$this
->
curItem
=&
$this
->
Application
->
recallObject
(
$event
->
Prefix
.
'.-tmpitem'
.
$event
->
Special
,
$event
->
Prefix
,
Array
(
'skip_autoload'
=>
true
));
break
;
}
$this
->
curItem
->
Clear
();
if
(
isset
(
$record_data
))
{
$this
->
setImportData
(
$record_data
);
}
}
function
setImportData
(
$record_data
)
{
foreach
(
$record_data
as
$field_index
=>
$field_value
)
{
$this
->
setFieldValue
(
$field_index
,
$field_value
);
}
$this
->
setCurrentID
();
}
function
getItemCategory
()
{
$backup_category_id
=
$this
->
Application
->
GetVar
(
'm_cat_id'
);
$category_id
=
$this
->
getFromCache
(
'category_names'
,
implode
(
':'
,
$this
->
curItem
->
CategoryPath
));
if
(
$category_id
)
{
$this
->
Application
->
SetVar
(
'm_cat_id'
,
$category_id
);
return
$category_id
;
}
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
)
)
);
$category_id
=
$this
->
getFromCache
(
'category_names'
,
$category_key
);
if
(
$category_id
===
false
)
{
// get parent category path to search only in it
$current_category_id
=
$this
->
Application
->
GetVar
(
'm_cat_id'
);
// $parent_path = $this->getParentPath($current_category_id);
// get category id from database by name
$sql
=
'SELECT CategoryId
FROM '
.
TABLE_PREFIX
.
'Category
WHERE (Name = '
.
$this
->
Conn
->
qstr
(
$category_name
).
') AND (ParentId = '
.
$current_category_id
.
')'
;
$category_id
=
$this
->
Conn
->
GetOne
(
$sql
);
if
(
$category_id
===
false
)
{
// category not in db -> create
$category_fields
=
Array
(
'Name'
=>
$category_name
,
'Description'
=>
$category_name
,
'Status'
=>
STATUS_ACTIVE
,
'ParentId'
=>
$current_category_id
,
'AutomaticFilename'
=>
1
);
$this
->
dummyCategory
->
SetDBFieldsFromHash
(
$category_fields
);
if
(
$this
->
dummyCategory
->
Create
())
{
$category_id
=
$this
->
dummyCategory
->
GetID
();
$this
->
addToCache
(
'category_parent_path'
,
$category_id
,
$this
->
dummyCategory
->
GetDBField
(
'ParentPath'
));
$this
->
addToCache
(
'category_names'
,
$category_key
,
$category_id
);
}
}
else
{
$this
->
addToCache
(
'category_names'
,
$category_key
,
$category_id
);
}
}
if
(
$category_id
)
{
$this
->
Application
->
SetVar
(
'm_cat_id'
,
$category_id
);
}
}
if
(!
$this
->
curItem
->
CategoryPath
)
{
$category_id
=
$backup_category_id
;
}
return
$category_id
;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
processCurrentItem
(&
$event
,
$record_data
)
{
$save_method
=
'Create'
;
$load_keys
=
Array
();
// create/update categories
$backup_category_id
=
$this
->
Application
->
GetVar
(
'm_cat_id'
);
// perform replace duplicates code
if
(
$this
->
exportOptions
[
'ReplaceDuplicates'
])
{
// get replace keys first, then reset current item to empty one
$category_id
=
$this
->
getItemCategory
();
if
(
$this
->
exportOptions
[
'CheckDuplicatesMethod'
]
==
1
)
{
if
(
$this
->
curItem
->
GetID
())
{
$load_keys
=
Array
(
$this
->
curItem
->
IDField
=>
$this
->
curItem
->
GetID
());
}
}
else
{
$key_fields
=
$this
->
exportOptions
[
'DuplicateCheckFields'
];
foreach
(
$key_fields
as
$key_field
)
{
$load_keys
[
$key_field
]
=
$this
->
curItem
->
GetDBField
(
$key_field
);
}
}
$this
->
resetImportObject
(
$event
,
IMPORT_LIVE
);
if
(
count
(
$load_keys
))
{
$where_clause
=
''
;
foreach
(
$load_keys
as
$field_name
=>
$field_value
)
{
$where_clause
.=
'(item_table.`'
.
$field_name
.
'` = '
.
$this
->
Conn
->
qstr
(
$field_value
).
') AND '
;
}
$where_clause
=
preg_replace
(
'/(.*) AND $/'
,
'
\\
1'
,
$where_clause
);
$item_id
=
$this
->
getFromCache
(
'new_ids'
,
crc32
(
$where_clause
));
if
(!
$item_id
)
{
if
(
$this
->
exportOptions
[
'CheckDuplicatesMethod'
]
==
2
)
{
// by other fields
$parent_path
=
$this
->
getParentPath
(
$category_id
);
$where_clause
=
'(c.ParentPath LIKE "'
.
$parent_path
.
'%") AND '
.
$where_clause
;
}
$sql
=
'SELECT '
.
$this
->
curItem
->
IDField
.
'
FROM '
.
$this
->
curItem
->
TableName
.
' item_table
LEFT JOIN '
.
TABLE_PREFIX
.
'CategoryItems ci ON ci.ItemResourceId = item_table.ResourceId
LEFT JOIN '
.
TABLE_PREFIX
.
'Category c ON c.CategoryId = ci.CategoryId
WHERE '
.
$where_clause
;
$item_id
=
$this
->
Conn
->
GetOne
(
$sql
);
}
$save_method
=
$item_id
&&
$this
->
curItem
->
Load
(
$item_id
)
?
'Update'
:
'Create'
;
}
$this
->
setImportData
(
$record_data
);
}
else
{
$this
->
resetImportObject
(
$event
,
IMPORT_LIVE
,
$record_data
);
$category_id
=
$this
->
getItemCategory
();
}
// create main record
if
(
$save_method
==
'Create'
)
{
$this
->
fillRequiredFields
(
$this
->
false
,
$this
->
curItem
,
true
);
}
// $sql_start = getmicrotime();
if
(!
$this
->
curItem
->
$save_method
())
{
return
false
;
}
// $sql_end = getmicrotime();
// $this->saveLog('SQL ['.$save_method.'] Time: '.($sql_end - $sql_start).'s');
if
(
$load_keys
&&
(
$save_method
==
'Create'
)
&&
$this
->
exportOptions
[
'ReplaceDuplicates'
])
{
// map new id to old id
$this
->
addToCache
(
'new_ids'
,
crc32
(
$where_clause
),
$this
->
curItem
->
GetID
()
);
}
// assign item to categories
$this
->
curItem
->
assignToCategory
(
$category_id
,
false
);
$this
->
Application
->
SetVar
(
'm_cat_id'
,
$backup_category_id
);
return
true
;
}
/*function saveLog($msg)
{
$fp = fopen(FULL_PATH.'/sqls.log', 'a');
fwrite($fp, $msg."\n");
fclose($fp);
}*/
/**
* Returns category parent path, if possible, then from cache
*
* @param int $category_id
* @return string
*/
function
getParentPath
(
$category_id
)
{
$parent_path
=
$this
->
getFromCache
(
'category_parent_path'
,
$category_id
);
if
(
$parent_path
===
false
)
{
$sql
=
'SELECT ParentPath
FROM '
.
TABLE_PREFIX
.
'Category
WHERE CategoryId = '
.
$category_id
;
$parent_path
=
$this
->
Conn
->
GetOne
(
$sql
);
$this
->
addToCache
(
'category_parent_path'
,
$category_id
,
$parent_path
);
}
return
$parent_path
;
}
function
getFileExtension
()
{
return
$this
->
exportOptions
[
'ExportFormat'
]
==
1
?
'csv'
:
'xml'
;
}
function
getLineSeparator
(
$option
=
'LineEndings'
)
{
return
$this
->
exportOptions
[
$option
]
==
1
?
"
\r\n
"
:
"
\n
"
;
}
/**
* Returns field caption for any exported field
*
* @param string $field
* @return string
*/
function
getFieldCaption
(
$field
)
{
if
(
substr
(
$field
,
0
,
10
)
==
'__CUSTOM__'
)
{
$ret
=
'Custom_'
.
substr
(
$field
,
10
,
strlen
(
$field
)
);
}
elseif
(
substr
(
$field
,
0
,
12
)
==
'__CATEGORY__'
)
{
return
$this
->
getCategoryTitle
();
}
elseif
(
substr
(
$field
,
0
,
11
)
==
'__VIRTUAL__'
)
{
$ret
=
substr
(
$field
,
11
);
}
else
{
$ret
=
$field
;
}
return
Array
(
$ret
);
}
/**
* Returns requested field value (including custom fields and category fields)
*
* @param string $field
* @return string
*/
function
getFieldValue
(
$field
)
{
if
(
substr
(
$field
,
0
,
10
)
==
'__CUSTOM__'
)
{
$field
=
'cust_'
.
substr
(
$field
,
10
,
strlen
(
$field
));
$ret
=
$this
->
curItem
->
GetField
(
$field
);
}
elseif
(
substr
(
$field
,
0
,
12
)
==
'__CATEGORY__'
)
{
return
$this
->
getCategoryPath
();
}
elseif
(
substr
(
$field
,
0
,
11
)
==
'__VIRTUAL__'
)
{
$field
=
substr
(
$field
,
11
);
return
$this
->
curItem
->
GetField
(
$field
);
}
else
{
$ret
=
$this
->
curItem
->
GetField
(
$field
);
}
$ret
=
str_replace
(
"
\r\n
"
,
$this
->
getLineSeparator
(
'LineEndingsInside'
),
$ret
);
return
Array
(
$ret
);
}
/**
* Returns category field(-s) caption based on export mode
*
* @return string
*/
function
getCategoryTitle
()
{
// category path in separated fields
$category_count
=
$this
->
getMaxCategoryLevel
();
if
(
$this
->
exportOptions
[
'CategoryFormat'
]
==
1
)
{
// category path in one field
return
$category_count
?
Array
(
'CategoryPath'
)
:
Array
();
}
else
{
$i
=
0
;
$ret
=
Array
();
while
(
$i
<
$category_count
)
{
$ret
[]
=
'Category'
.(
$i
+
1
);
$i
++;
}
return
$ret
;
}
}
/**
* Returns category path in required format for current link
*
* @return string
*/
function
getCategoryPath
()
{
$category_id
=
$this
->
curItem
->
GetDBField
(
'CategoryId'
);
$category_path
=
$this
->
getFromCache
(
'category_path'
,
$category_id
);
if
(!
$category_path
)
{
$sql
=
'SELECT CachedNavbar
FROM '
.
TABLE_PREFIX
.
'Category
WHERE CategoryId = '
.
$category_id
;
$category_path
=
$this
->
Conn
->
GetOne
(
$sql
);
$category_path
=
$category_path
?
explode
(
'>'
,
$category_path
)
:
Array
();
if
(
$this
->
exportOptions
[
'IsBaseCategory'
])
{
$i
=
$this
->
exportOptions
[
'BaseLevel'
];
while
(
$i
>
0
)
{
array_shift
(
$category_path
);
$i
--;
}
}
$category_count
=
$this
->
getMaxCategoryLevel
();
if
(
$this
->
exportOptions
[
'CategoryFormat'
]
==
1
)
{
// category path in single field
$category_path
=
$category_count
?
Array
(
implode
(
$this
->
exportOptions
[
'CategorySeparator'
],
$category_path
)
)
:
Array
();
}
else
{
// category path in separated fields
$levels_used
=
count
(
$category_path
);
if
(
$levels_used
<
$category_count
)
{
$i
=
0
;
while
(
$i
<
$category_count
-
$levels_used
)
{
$category_path
[]
=
''
;
$i
++;
}
}
}
$this
->
addToCache
(
'category_path'
,
$category_id
,
$category_path
);
}
return
$category_path
;
}
/**
* Get maximal category deep level from links beeing exported
*
* @return int
*/
function
getMaxCategoryLevel
()
{
static
$max_level
=
-
1
;
if
(
$max_level
!=
-
1
)
{
return
$max_level
;
}
$sql
=
'SELECT IF(c.CategoryId IS NULL, 0, MAX( LENGTH(c.ParentPath) - LENGTH( REPLACE(c.ParentPath, "|", "") ) - 1 ))
FROM '
.
$this
->
curItem
->
TableName
.
' item_table
LEFT JOIN '
.
TABLE_PREFIX
.
'CategoryItems ci ON item_table.ResourceId = ci.ItemResourceId
LEFT JOIN '
.
TABLE_PREFIX
.
'Category c ON c.CategoryId = ci.CategoryId
WHERE (ci.PrimaryCat = 1) AND '
;
$where_clause
=
''
;
if
(
$this
->
exportOptions
[
'export_ids'
]
===
false
)
{
// get links from current category & all it's subcategories
if
(
$this
->
exportOptions
[
'export_cats_ids'
][
0
]
==
0
)
{
$where_clause
=
1
;
}
else
{
foreach
(
$this
->
exportOptions
[
'export_cats_ids'
]
as
$category_id
)
{
$where_clause
.=
'(c.ParentPath LIKE "%|'
.
$category_id
.
'|%") OR '
;
}
$where_clause
=
preg_replace
(
'/(.*) OR $/'
,
'
\\
1'
,
$where_clause
);
}
}
else
{
// get only selected links
$where_clause
=
$this
->
curItem
->
IDField
.
' IN ('
.
implode
(
','
,
$this
->
exportOptions
[
'export_ids'
]).
')'
;
}
$max_level
=
$this
->
Conn
->
GetOne
(
$sql
.
'('
.
$where_clause
.
')'
);
if
(
$this
->
exportOptions
[
'IsBaseCategory'
]
)
{
$max_level
-=
$this
->
exportOptions
[
'BaseLevel'
];
}
return
$max_level
;
}
/**
* Saves one record to export file
*
* @param Array $fields_hash
*/
function
writeRecord
(
$fields_hash
)
{
fputcsv2
(
$this
->
filePointer
,
$fields_hash
,
$this
->
exportOptions
[
'FieldsSeparatedBy'
],
$this
->
exportOptions
[
'FieldsEnclosedBy'
],
$this
->
getLineSeparator
()
);
}
function
readRecord
()
{
return
fgetcsv
(
$this
->
filePointer
,
10000
,
$this
->
exportOptions
[
'FieldsSeparatedBy'
],
$this
->
exportOptions
[
'FieldsEnclosedBy'
]);
}
function
saveOptions
(&
$event
,
$options
=
null
)
{
if
(!
isset
(
$options
))
{
$options
=
$this
->
exportOptions
;
}
$this
->
Application
->
StoreVar
(
$event
->
getPrefixSpecial
().
'_options'
,
serialize
(
$options
)
);
}
function
loadOptions
(&
$event
)
{
return
unserialize
(
$this
->
Application
->
RecallVar
(
$event
->
getPrefixSpecial
().
'_options'
));
}
}
?>
Event Timeline
Log In to Comment