Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Thu, Jul 17, 12:41 AM

in-portal

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: trunk/kernel/admin/include/toolbar/browse.php
===================================================================
--- trunk/kernel/admin/include/toolbar/browse.php (revision 3542)
+++ trunk/kernel/admin/include/toolbar/browse.php (revision 3543)
@@ -1,889 +1,932 @@
<?php
global $objConfig,$objSections,$section, $rootURL,$adminURL, $admin, $imagesURL,$envar,
$m_var_list_update,$objCatList, $homeURL, $upURL, $objSession,$CatScopeClause,$DefaultTab;
global $CategoryFilter,$TotalItemCount;
global $Bit_All,$Bit_Pending,$Bit_Disabled,$Bit_New,$Bit_Pop,$Bit_Hot,$Bit_Ed;
global $hideSelectAll;
/* bit place holders for category view menu */
$Bit_Active=64;
$Bit_Pending=32;
$Bit_Disabled=16;
$Bit_New=8;
$Bit_Pop=4;
$Bit_Hot=2;
$Bit_Ed=1;
if( isset($_GET['SetTab']) )
{
if($_GET["SetTab"] != "categories")
{
$m_tab_CatTab_Hide = 1;
$DefaultTab = $_GET["SetTab"];
}
else
{
$DefaultTab="categories";
$m_tab_CatTab_Hide = 0;
}
}
else
$m_tab_CatTab_Hide = (int)$objConfig->Get("CatTab_Hide");
$CategoryView = $objConfig->Get("Category_View");
if(!is_numeric($CategoryView))
{
$CategoryView = 127;
}
$Category_Sortfield = $objConfig->Get("Category_Sortfield");
if(!strlen($Category_Sortfield))
$Category_Sortfield = "Name";
$Category_Sortorder = $objConfig->Get("Category_Sortorder");
if(!strlen($Category_Sortorder))
$Category_Sortorder = "desc";
$Perpage_Category = (int)$objConfig->Get("Perpage_Category");
if(!$Perpage_Category)
$Perpage_Category="'all'";
if($CategoryView == 127)
{
$Category_ShowAll = 1;
}
else
{
$Category_ShowAll=0;
$Status = array();
$Mod = array();
if($CategoryView & $Bit_Pending)
$Status[] = STATUS_PENDING;
if($CategoryView & $Bit_Active)
$Status[] = STATUS_ACTIVE;
if($CategoryView & $Bit_Disabled)
$Status[] = STATUS_DISABLED;
if(count($Status))
{
$CategoryFilter .= " AND (Status IN (".implode(",",$Status).") ";
}
else
$CategoryFilter .= " AND ((Status=-1) ";
if($CategoryView & $Bit_Ed)
{
$CategoryFilter .= " OR (EditorsPick=1) ";
}
if($CategoryView & $Bit_New)
{
$cutoff = adodb_date("U") - ($objConfig->Get("Category_DaysNew") * 86400);
$CategoryFilter .= " OR (CreatedOn > ".$cutoff.") ";
}
$CategoryFilter .= ")";
}
$list = $objSession->GetVariable("SearchWord");
if(strlen($list))
{
$CatScope = $objSession->GetVariable("SearchScope");
switch($CatScope)
{
case 0 :
$CatScopeClause = "";
break;
case 1:
$cat = $objCatList->CurrentCategoryID();
if($cat>0)
{
$allcats = $objCatList->AllSubCats($cat);
if(count($allcats)>0)
{
$catlist = implode(",",$allcats);
$CatScopeClause = " CategoryId IN ($catlist) ";
}
}
break;
case 2:
$CatScopeClause = "CategoryId=".$objCatList->CurrentCategoryID();
break;
}
}
else
$CatScopeClause="";
$Cat_Paste = "false";
if($objCatList->ItemsOnClipboard()>0)
$Cat_Paste = "true";
$CurrentCat = $objCatList->CurrentCategoryID();
if($CurrentCat>0)
{
$c = $objCatList->GetItem($CurrentCat);
$CurrentRes = (int)$c->Get("ResourceId");
}
else
$CurrentRes =0;
$mnuClearSearch = language("la_SearchMenu_Clear");
$mnuNewSearch = language("la_SearchMenu_New");
$mnuSearchCategory = language("la_SearchMenu_Categories");
$lang_New = language("la_Text_New");
$lang_Hot = language("la_Text_Hot");
$lang_EdPick = language("la_prompt_EditorsPick");
$lang_Pop = language("la_Text_Pop");
$lang_Rating = language("la_prompt_Rating");
$lang_Hits = language("la_prompt_Hits");
$lang_Votes = language("la_prompt_Votes");
$lang_Name = language("la_prompt_Name");
$lang_Categories = language("la_ItemTab_Categories");
$lang_Description = language("la_prompt_Description");
$lang_MetaKeywords = language("la_prompt_MetaKeywords");
$lang_SubSearch = language("la_prompt_SubSearch");
$lang_Within = language("la_Text_Within");
$lang_Current = language("la_Text_Current");
$lang_Active = language("la_Text_Active");
$lang_SubCats = language("la_Text_SubCats");
$lang_SubItems = language("la_Text_Subitems");
// View, Sort, Select, Per Page
$lang_View = language('la_Text_View');
$lang_Sort = language('la_Text_Sort');
$lang_PerPage = language('la_prompt_PerPage');
$lang_Select = language('la_Text_Select');
print <<<END
<script language="JavaScript">
// global usage phrases
var lang_View = '$lang_View';
var lang_Sort = '$lang_Sort';
var lang_PerPage = '$lang_PerPage';
var lang_Select = '$lang_Select';
// local usage phrases
var Category_Sortfield = '$Category_Sortfield';
var Category_Sortorder = '$Category_Sortorder';
var Category_Perpage = $Perpage_Category;
var Category_ShowAll = $Category_ShowAll;
var CategoryView = $CategoryView;
var default_tab = "$DefaultTab";
var Categories_Paste = $Cat_Paste;
var CurrentCat = $CurrentCat;
var CurrentRes = $CurrentRes;
PasteButton = PasteButton || Categories_Paste;
//JS Language variables
var lang_New = "$lang_New";
var lang_Hot = "$lang_Hot";
var lang_EdPick = "$lang_EdPick";
var lang_Pop = "$lang_Pop";
var lang_Rating = "$lang_Rating";
var lang_Hits = "$lang_Hits";
var lang_Votes = "$lang_Votes";
var lang_Name = "$lang_Name";
var lang_Categories = "$lang_Categories";
var lang_Description = "$lang_Description";
var lang_MetaKeywords = "$lang_MetaKeywords";
var lang_SubSearch = "$lang_SubSearch";
var lang_Within="$lang_Within";
var lang_Current = "$lang_Current";
var lang_Active = "$lang_Active";
var lang_SubCats = "$lang_SubCats";
var lang_SubItems = "$lang_SubItems";
var m_tab_CatTab_hide = $m_tab_CatTab_Hide;
var hostname = '$rootURL';
var env = '$envar';
var actionlist = new Array();
var homeURL = "$homeURL";
var upURL = "$upURL";
// K4 code for handling toolbar operations: begin
var \$TabRegistry = Array();
function InpGrid(tab)
{
this.TabId = tab;
}
InpGrid.prototype.ClearSelection = function(force,called_from)
{
unselectAll(this.TabId, 1); //1 means don't upate toolbar
}
function registerTab(\$tab_id)
{
var \$tab = document.getElementById(\$tab_id);
var \$index = \$TabRegistry.length;
\$TabRegistry[\$index] = new Array();
\$TabRegistry[\$index]['tab_id'] = \$tab_id;
\$TabRegistry[\$index]['prefix_special'] = \$tab.getAttribute('PrefixSpecial');
\$TabRegistry[\$index]['edit_template'] = \$tab.getAttribute('EditURL');
}
function queryTabRegistry(\$search_key, \$search_value, \$return_key)
{
var \$i = 0;
while(\$i < \$TabRegistry.length)
{
if(\$TabRegistry[\$i][\$search_key] == \$search_value)
{
return \$TabRegistry[\$i][\$return_key];
break;
}
\$i++;
}
return '<'+\$search_key+'='+\$search_value+'>';
}
function k4_actionHandler(action, prefix_special)
{
var k4_action = '';
switch (action)
{
case 'edit':
k4_action = 'edit_item("'+prefix_special+'")';
break;
case 'delete':
k4_action = 'delete_items("'+prefix_special+'")';
break;
case 'unselect':
k4_action = 'unselect("'+prefix_special+'")';
break;
+
case 'approve':
k4_action = 'approve_items("'+prefix_special+'")';
break;
case 'decline':
k4_action = 'decine_items("'+prefix_special+'")';
break;
case 'm_rebuild_cache':
k4_action = 'rebuild_cache("c")';
break;
+
+ case 'import':
+ k4_action = 'import_items("'+prefix_special+'")';
+ break;
+
+ case 'export':
+ k4_action = 'export_items("'+prefix_special+'")';
+ break;
case 'copy':
k4_action = 'copy_items("'+prefix_special+'")';
break;
case 'cut':
k4_action = 'cut_items("'+prefix_special+'")';
break;
+
case 'move_up':
k4_action = 'move_up("'+prefix_special+'")';
break;
case 'move_down':
k4_action = 'move_down("'+prefix_special+'")';
break;
}
if (k4_action != '')
{
\$form_prefix = queryTabRegistry('prefix_special', prefix_special, 'tab_id');
eval(k4_action);
}
else alert(action+' not implemented');
}
function approve_items(prefix_special)
{
set_hidden_field('remove_specials['+prefix_special+']',1);
submit_event(prefix_special,'OnMassApprove','')
}
function decine_items(prefix_special)
{
set_hidden_field('remove_specials['+prefix_special+']',1);
submit_event(prefix_special,'OnMassDecline','')
}
+ function import_items(prefix_special)
+ {
+ set_hidden_field('remove_specials['+prefix_special+']',1);
+ submit_event(prefix_special,'OnImport','')
+ }
+
+ function export_items(prefix_special)
+ {
+ set_hidden_field('remove_specials['+prefix_special+']',1);
+ submit_event(prefix_special,'OnExport','')
+ }
+
function edit()
{
edit_item( queryTabRegistry('tab_id', activeTab.id, 'prefix_special') );
}
function edit_item(prefix_special)
{
opener_action('d');
set_hidden_field(prefix_special+'_mode', 't');
submit_event(prefix_special, 'OnEdit', queryTabRegistry('prefix_special', prefix_special, 'edit_template'), '../../admin/index4.php');
}
function delete_items(prefix_special)
{
set_hidden_field('remove_specials['+prefix_special+']',1);
submit_event(prefix_special,'OnMassDelete','')
}
function copy_items(prefix_special)
{
submit_event(prefix_special,'OnCopy','')
}
function cut_items(prefix_special)
{
submit_event(prefix_special,'OnCut','')
}
function move_up(prefix_special)
{
submit_event(prefix_special,'OnMassMoveUp','')
}
function move_down(prefix_special)
{
submit_event(prefix_special,'OnMassMoveDown','')
}
function unselect(prefix_special)
{
Grids[prefix_special].ClearSelection(null,'Inp_AdvancedView.Unselect');
}
function rebuild_cache(prefix_special)
{
submit_event(prefix_special,'OnRebuildCache','')
}
// K4 code for handling toolbar operations: end
function InitPage()
{
addCommonActions();
initToolbar('mainToolBar', actionHandler);
initCheckBoxes();
//toggleMenu();
}
- function AddButtonAction(actionname,actionval)
+ function AddButtonAction(action_name,action_value)
{
- var item = new Array(actionname,actionval);
- actionlist[actionlist.length] = item;
+ actionlist[actionlist.length] = new Array(action_name, action_value);
}
function actionHandler(button)
{
- //alert('a button has been pressed!');
+// alert('a button has been pressed!');
for(i=0; i<actionlist.length;i++)
{
a = actionlist[i];
if(button.action==a[0])
{
// alert('Button action '+a[0]+' is '+a[1]);
eval(a[1]);
break;
}
}
}
function addCommonActions()
{
AddButtonAction('upcat',"get_to_server(upURL,'');");// UP
AddButtonAction('homecat',"get_to_server(homeURL,'');"); //home
AddButtonAction('new_cat',"get_to_server('$adminURL/category/addcategory.php',env+'&new=1');"); //new cat
AddButtonAction('editcat',"edit_current(); "); //edit current
AddButtonAction('edit',"check_submit('','edit');"); //edit
AddButtonAction('delete',"check_submit('$admin/browse','delete');"); //delete
AddButtonAction('approve',"check_submit('$admin/browse','approve');"); //approve
AddButtonAction('decline',"check_submit('$admin/browse','decline');"); //decline
AddButtonAction('import',"check_submit('$admin/browse','import');"); // import
AddButtonAction('export',"check_submit('$admin/browse','export');"); // export
AddButtonAction('rebuild_cache',"check_submit('$admin/category/category_maint', 'm_rebuild_cache');"); // rebuild_cache
AddButtonAction('cut',"check_submit('$admin/browse','cut');"); //cut
AddButtonAction('copy',"check_submit('$admin/browse','copy');"); //copy
AddButtonAction('paste',"get_to_server('$adminURL/browse.php',env+'&Action=m_paste');"); //paste
AddButtonAction('move_up',"check_submit('$admin/browse','move_up');"); //up
AddButtonAction('move_down',"check_submit('$admin/browse','move_down');"); //down
AddButtonAction('print',"window.print();"); //print ?
AddButtonAction('view',"toggleMenu(); window.FW_showMenu(window.cat_menu,getRealLeft(button) - ((document.all) ? 6 : -2),getRealTop(button)+32);");
AddButtonAction('search_a',"setSearchMenu(); window.FW_showMenu(window.SearchMenu,getRealLeft(button)-134 - ((document.all) ? 8 : -1),getRealTop(button)+22);");
AddButtonAction('search_b',"search_submit();");
AddButtonAction('search_c',"new_search_submit();");
}
function AdminCatNav(url)
{
f = document.getElementById("admin_search");
if(f)
{
f.action = url;
new_search_submit();
}
}
function search_submit()
{
f = document.getElementById("admin_search");
if(f)
{
//alert('Setting SearchWord to ' + f.value);
f.Action.value = "m_SearchWord";
f.submit();
}
}
function new_search_submit()
{
var newSearchInput = document.getElementById("NewSearch");
if (newSearchInput) newSearchInput.value = 1;
search_submit();
}
function ClearSearch()
{
//alert('Clearing Search');
f = document.getElementById("admin_search");
if(f)
{
f.Action.value = "m_ClearSearch";
f.submit();
}
}
function SetSearchType(value)
{
f = document.getElementById("admin_search");
if(f)
{
f.SearchType.value = value;
}
}
function SetSearchScope(value)
{
f = document.getElementById("admin_search");
if(f)
{
f.SearchScope.value = value;
}
}
function ToggleNewSearch()
{
f = document.getElementById("admin_search");
if(f)
{
value = f.NewSearch.value;
if(value==1)
{
f.NewSearch.value=0;
}
else
f.NewSearch.value=1;
}
}
function isNewSearch()
{
f = document.getElementById("admin_search");
if(f)
{
return f.NewSearch.value;
}
else return 0;
}
function get_to_server(path,attr)
{
if(attr.length>0)
path = path + '?'+attr;
window.location.href=path;
return true;
}
- function check_submit(page,actionValue)
- {
-
- if (actionValue.match(/delete$/)) {
+ function check_submit(page, actionValue)
+ {
+ if (actionValue.match(/delete$/))
+ {
if (!theMainScript.Confirm(lang_DeleteConfirm)) return;
}
- var formname = '';
- var action_prefix ='';
+ var formname = '';
+ var action_prefix ='';
- if ((activeTab) && (!isAnyChecked('categories')))
- {
- form_name = activeTab.id;
- action_prefix = activeTab.getAttribute("ActionPrefix");
- if(page.length==0)
- page = activeTab.getAttribute("EditURL");
+ var isCatImportExport = activeTab && isAnyChecked('categories') && (actionValue == 'import' || actionValue == 'export');
+
+ if (activeTab && (!isAnyChecked('categories') || isCatImportExport))
+ {
+ form_name = activeTab.id;
+ action_prefix = activeTab.getAttribute("ActionPrefix");
+ if (page.length == 0) page = activeTab.getAttribute("EditURL");
- if ( action_prefix.match("k4:(.*)") )
- {
- act = RegExp.$1;
- act = act.replace('$\$event$$', actionValue);
- act = act.replace('$\$prefix$$', activeTab.getAttribute("PrefixSpecial") );
- eval(act);
- return;
- }
- }
- else
- {
- form_name = 'categories';
- action_prefix = 'm_cat_';
- if(page.length==0)
- page="$admin" + '/category/addcategory';
- }
- var f = document.getElementsByName(form_name+'_form')[0];
-
- if(f)
- {
- if (actionValue.substring(0,2) == 'm_')
- {
- f.Action.value = actionValue;
+ if ( action_prefix.match("k4:(.*)") )
+ {
+ act = RegExp.$1;
+ act = act.replace('$\$event$$', actionValue);
+ act = act.replace('$\$prefix$$', activeTab.getAttribute("PrefixSpecial") );
+ eval(act);
+ return;
+ }
+ else if(actionValue == 'import' || actionValue == 'export')
+ {
+ save_selected_categories('export_categories');
+ return k4_actionHandler(actionValue, activeTab.getAttribute("PrefixSpecial"));
+ }
+ }
+ else
+ {
+ form_name = 'categories';
+ action_prefix = 'm_cat_';
+ if (page.length == 0) page = "$admin" + '/category/addcategory';
+ }
+
+ var f = document.getElementsByName(form_name+'_form')[0];
+ if(f)
+ {
+ if (actionValue.substring(0,2) == 'm_')
+ {
+ f.Action.value = actionValue;
+ }
+ else
+ {
+ f.Action.value = action_prefix + actionValue;
+ }
+
+ f.action = '$rootURL' + page + '.php?'+ env;
+// alert(f.name+ ' is submitting to '+ f.action + ' action=' + f.Action.value);
+ f.submit();
}
- else
- {
- f.Action.value = action_prefix + actionValue;
- }
-
- f.action = '$rootURL' + page + '.php?'+ env;
-// alert(f.name+ ' is submitting to '+ f.action + ' action=' + f.Action.value);
- f.submit();
- }
- } // check submit
+ } // check submit
+ function save_selected_categories(field_name)
+ {
+ var result = '';
+ var checkboxes = document.getElementsByName('catlist[]');
+
+ for (var i = 0; i < checkboxes.length; i++)
+ {
+ if (checkboxes[i].checked == true)
+ {
+ result += checkboxes[i].value + ',';
+ }
+ }
+ result = result.replace(/(.*),\$/, '\$1');
+ if (activeTab) \$form_prefix = activeTab.id;
+ set_hidden_field(field_name, result);
+ }
+
function edit_current()
{
if(CurrentCat==0)
{
get_to_server('$adminURL/category/addcategory_permissions.php',env+'&item=0');
}
else
get_to_server('$adminURL/category/addcategory.php',env+'&item=$CurrentRes');
}
function flip_current(field_suffix)
{
if(activeTab)
{
field = activeTab.getAttribute("tabTitle")+field_suffix;
return flip(eval(field));
}
}
function config_current(field_suffix,value)
{
if(activeTab)
{
field = activeTab.getAttribute("tabTitle")+field_suffix;
config_val(field,value);
}
}
function getSType(type,value)
{
f = document.getElementById("admin_search");
if(f)
{
if (f.SearchType.value == type) return 2; else return 0;
} else return 0;
}
function getSScope(scope)
{
f = document.getElementById("admin_search");
if(f)
{
if (f.SearchScope.value == scope) return 2; else return 0;
} else return 0;
}
function setSearchMenu()
{
window.SearchMenu = new Menu("search");
SearchMenu.addMenuItem(lang_All,"SetSearchType('all');",getSType('all'));
SearchMenu.addMenuSeparator()
SearchMenu.addMenuItem(lang_Categories, "SetSearchType('categories');",getSType('categories'));
param = "";
for (var i = 0; i < tabIDs.length; i++)
{
d = document.getElementById(tabIDs[i]);
if(d)
{
tabname = d.getAttribute("tabTitle");
param = "SetSearchType('"+tabname+"');";
SearchMenu.addMenuItem(tabname,param,getSType(tabname));
}
}
SearchMenu.addMenuSeparator();
SearchMenu.addMenuItem(lang_All+' '+lang_Categories,"SetSearchScope('0');",getSScope(0));
SearchMenu.addMenuItem(lang_SubSearch,"ToggleNewSearch();",isNewSearch());
SearchMenu.addMenuItem(lang_Current+' '+lang_Categories,"SetSearchScope('2');",getSScope(2));
SearchMenu.addMenuItem(lang_Within+' '+lang_Categories,"SetSearchScope('1');",getSScope(1));
SearchMenu.addMenuSeparator();
window.SearchMenu.addMenuItem('$mnuClearSearch',"ClearSearch();","");
window.triedToWriteMenus = false;
window.SearchMenu.writeMenus();
}
\$fw_menus['c_view_menu'] = function()
{
// filtering menu
\$Menus['c_filtring_menu'] = new Menu(lang_View);
\$Menus['c_filtring_menu'].addMenuItem(lang_All,"config_val('Category_View', 127);",CategoryView==127);
\$Menus['c_filtring_menu'].addMenuSeparator();
\$Menus['c_filtring_menu'].addMenuItem(lang_Active,"FlipBit('Category_View',CategoryView,6);",BitStatus(CategoryView,6));
\$Menus['c_filtring_menu'].addMenuItem(lang_Pending,"FlipBit('Category_View',CategoryView,5);", BitStatus(CategoryView,5));
\$Menus['c_filtring_menu'].addMenuItem(lang_Disabled,"FlipBit('Category_View',CategoryView,4);",BitStatus(CategoryView,4));
\$Menus['c_filtring_menu'].addMenuSeparator();
\$Menus['c_filtring_menu'].addMenuItem(lang_New,"FlipBit('Category_View',CategoryView,3);",BitStatus(CategoryView,3));
\$Menus['c_filtring_menu'].addMenuItem(lang_EdPick,"FlipBit('Category_View',CategoryView,0);",BitStatus(CategoryView,0));
// sorting menu
\$Menus['c_sorting_menu'] = new Menu(lang_Sort);
\$Menus['c_sorting_menu'].addMenuItem(lang_Asc,"config_val('Category_Sortorder','asc');",RadioIsSelected(Category_Sortorder,'asc'));
\$Menus['c_sorting_menu'].addMenuItem(lang_Desc,"config_val('Category_Sortorder','desc');",RadioIsSelected(Category_Sortorder,'desc'));
\$Menus['c_sorting_menu'].addMenuSeparator();
\$Menus['c_sorting_menu'].addMenuItem(lang_Default,"config_val('Category_Sortfield','Name');","");
\$Menus['c_sorting_menu'].addMenuItem(lang_Name,"config_val('Category_Sortfield','Name');",RadioIsSelected(Category_Sortfield,'Name'));
\$Menus['c_sorting_menu'].addMenuItem(lang_Description,"config_val('Category_Sortfield','Description');",RadioIsSelected(Category_Sortfield,'Description'));
\$Menus['c_sorting_menu'].addMenuItem(lang_CreatedOn,"config_val('Category_Sortfield','CreatedOn');",RadioIsSelected(Category_Sortfield,'CreatedOn'));
\$Menus['c_sorting_menu'].addMenuItem(lang_SubCats,"config_val('Category_Sortfield','CachedDescendantCatsQty');",RadioIsSelected(Category_Sortfield,'CachedDescendantCatsQty'));
// perpage menu
// select menu
\$Menus['c_select_menu'] = new Menu(lang_Select);
\$Menus['c_select_menu'].addMenuItem(lang_All,"javascript:selectAllC('categories');","");
\$Menus['c_select_menu'].addMenuItem(lang_Unselect,"javascript:unselectAll('categories');","");
\$Menus['c_select_menu'].addMenuItem(lang_Invert,"javascript:invert('categories');","");
// view menu
\$Menus['c_view_menu'] = new Menu(lang_Categories);
\$Menus['c_view_menu'].addMenuItem( \$Menus['c_filtring_menu'] );
\$Menus['c_view_menu'].addMenuItem( \$Menus['c_sorting_menu'] );
\$Menus['c_view_menu'].addMenuItem( \$Menus['c_select_menu'] );
}
function toggleMenu()
{
var \$ViewMenus = new Array();
// prepare categories menu
if (document.getElementById('categories').active)
{
\$fw_menus['c_view_menu']();
\$ViewMenus.push('c');
}
if (activeTab)
{
var prefix_special = activeTab.getAttribute('PrefixSpecial');
\$fw_menus[prefix_special+'_view_menu']();
\$ViewMenus.push(prefix_special);
}
if(\$ViewMenus.length == 1)
{
prefix_special = \$ViewMenus[\$ViewMenus.length-1];
window.cat_menu = \$Menus[prefix_special+'_view_menu'];
}
else
{
window.cat_menu = new Menu('ViewMenu_mixed');
// merge menus into new one
for(var i in \$ViewMenus)
{
prefix_special = \$ViewMenus[i];
window.cat_menu.addMenuItem( \$Menus[prefix_special+'_view_menu'] );
}
}
window.triedToWriteMenus = false;
window.cat_menu.writeMenus();
}
function toggleCategoriesA(tabHeader, instant)
{
var categories = document.getElementById('categories');
if (!categories) return;
toggleCategories(instant);
tabHeader.setAttribute("background", '$imagesURL'+'/itemtabs/' + ((categories.active) ? "tab_active" : "tab_inactive") + ".gif")
var images = tabHeader.getElementsByTagName("IMG");
if (images.length < 1) return;
images[0].src = '$imagesURL'+'/itemtabs/' + ((categories.active) ? "divider_up" : "divider_dn") + ".gif";
}
function toggleCategoriesB(tabHeader, instant)
{
var categories = document.getElementById('categories');
if (!categories) return;
toggleCategories(instant);
var active_str = '$imagesURL'+'/itemtabs/' + (categories.active ? 'tab_active' : 'tab_inactive');
SetBackground('l_cat', active_str + '_l.gif');
SetBackground('m_cat', active_str + '.gif');
SetBackground('m1_cat', active_str + '.gif');
SetBackground('r_cat', active_str + '_r.gif');
var images = tabHeader.getElementsByTagName("IMG");
if (images.length < 1) return;
images[0].src = '$imagesURL'+'/itemtabs/' + ((categories.active) ? "divider_up" : "divider_dn") + ".gif";
}
function toggleTabA(tabId, atm)
{
var hl = document.getElementById("hidden_line");
var activeTabId;
if (activeTab) activeTabId = activeTab.id;
if (activeTabId == tabId)
{
var devider = document.getElementById("tabsDevider");
devider.style.display = "";
unselectAll(tabId);
var tab = document.getElementById(tabId);
tab.active = false;
activeTab = null;
collapseTab = tab;
toolbar.setTab(null);
showTab();
}
else
{
if (activeTab) toggleTab(tabId, true)
else toggleTab(tabId, atm)
if (hl) hl.style.display = "none";
}
tab_hdr = document.getElementById('tab_headers');
if (!tab_hdr) return;
for (var i = 0; i < tabIDs.length; i++)
{
var tabHeader;
TDs = tab_hdr.getElementsByTagName("TD");
for (var j = 0; j < TDs.length; j++)
if (TDs[j].getAttribute("tabHeaderOf") == tabIDs[i])
{
tabHeader = TDs[j];
break;
}
if (!tabHeader) continue;
var tab = document.getElementById(tabIDs[i]);
if (!tab) continue;
tabHeader.setAttribute("background", "$imagesURL/itemtabs/" + ((tab.active) ? "tab_active" : "tab_inactive") + ".gif")
var images = tabHeader.getElementsByTagName("IMG");
if (images.length < 1) continue;
images[0].src = "$imagesURL/itemtabs/" + ((tab.active) ? "divider_up" : "divider_dn") + ".gif";
}
}
function toggleTabB(tabId, atm)
{
var hl = document.getElementById("hidden_line");
var activeTabId;
if (activeTab) activeTabId = activeTab.id;
if (activeTabId == tabId)
{
var devider = document.getElementById("tabsDevider");
devider.style.display = "";
unselectAll(tabId);
var tab = document.getElementById(tabId);
tab.active = false;
activeTab = null;
collapseTab = tab;
toolbar.setTab(null);
showTab();
}
else
{
if (activeTab)
toggleTab(tabId, true)
else
toggleTab(tabId, atm)
if (hl) hl.style.display = "none";
}
tab_hdr = document.getElementById('tab_headers');
if (!tab_hdr) return;
// process all module tabs
var active_str = '';
for(var i = 0; i < tabIDs.length; i++)
{
var tabHeader;
TDs = tab_hdr.getElementsByTagName("TD");
for (var j = 0; j < TDs.length; j++)
if (TDs[j].getAttribute("tabHeaderOf") == tabIDs[i])
{
tabHeader = TDs[j];
break;
}
if (!tabHeader) continue;
var tab = document.getElementById(tabIDs[i]);
if (!tab) continue;
active_str = (tab.active) ? "tab_active" : "tab_inactive";
if (TDs[j].getAttribute("tabHeaderOf") == tabId) {
// module tab is selected
SetBackground('l_' + tabId, "$imagesURL/itemtabs/" + active_str + "_l.gif");
SetBackground('m_' + tabId, "$imagesURL/itemtabs/" + active_str + ".gif");
SetBackground('m1_' + tabId, "$imagesURL/itemtabs/" + active_str + ".gif");
SetBackground('r_' + tabId, "$imagesURL/itemtabs/" + active_str + "_r.gif");
}
else
{
// module tab is not selected
SetBackground('l_' +tabIDs[i], "$imagesURL/itemtabs/" + active_str + "_l.gif");
SetBackground('m_' + tabIDs[i], "$imagesURL/itemtabs/" + active_str + ".gif");
SetBackground('m1_' + tabIDs[i], "$imagesURL/itemtabs/" + active_str + ".gif");
SetBackground('r_' + tabIDs[i], "$imagesURL/itemtabs/" + active_str + "_r.gif");
}
var images = tabHeader.getElementsByTagName("IMG");
if (images.length < 1) continue;
images[0].src = "$imagesURL/itemtabs/" + ((tab.active) ? "divider_up" : "divider_dn") + ".gif";
}
}
function SetBackground(element_id, img_url)
{
// set background image of element specified by id
var el = document.getElementById(element_id);
el.style.backgroundImage = 'url('+img_url+')';
}
</script>
END;
?>
Property changes on: trunk/kernel/admin/include/toolbar/browse.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.11
\ No newline at end of property
+1.12
\ No newline at end of property
Index: trunk/kernel/module_help/visits_list.txt
===================================================================
--- trunk/kernel/module_help/visits_list.txt (revision 3542)
+++ trunk/kernel/module_help/visits_list.txt (revision 3543)
@@ -1,24 +1,24 @@
-<span style="font-weight: bold;">Visits (In-portal Platform)<br/>
-<br/>
-</span>This section displays the log of all visits to your website. The visit is recorded when a user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
-The grid on this page displays the following columns:<br/>
-<ul>
- <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
- <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
- <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
- <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
-</ul>
-<br/>
-<span style="font-weight: bold;">Visits (with In-commerce installed)<br/>
-<br/>
-</span>This section displays the log of all visits to your website. The visit is recorded when user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
-The grid on this page displays the following columns:<br/>
-<ul>
- <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
- <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
- <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
- <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
- <li>Affiliate User &ndash; the username of affiliate who has referred the visitor</li>
- <li>Order Total &ndash; the total amount of the orders made during this visit</li>
- <li>Affiliate Commission &ndash; amount of affiliate commission received for the orders made during the visit</li>
+<span style="font-weight: bold;">Visits (In-portal Platform)<br/>
+<br/>
+</span>This section displays the log of all visits to your website. The visit is recorded when a user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
+The grid on this page displays the following columns:<br/>
+<ul>
+ <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
+ <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
+ <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
+ <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
+</ul>
+<br/>
+<span style="font-weight: bold;">Visits (with In-commerce installed)<br/>
+<br/>
+</span>This section displays the log of all visits to your website. The visit is recorded when user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
+The grid on this page displays the following columns:<br/>
+<ul>
+ <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
+ <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
+ <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
+ <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
+ <li>Affiliate User &ndash; the username of affiliate who has referred the visitor</li>
+ <li>Order Total &ndash; the total amount of the orders made during this visit</li>
+ <li>Affiliate Commission &ndash; amount of affiliate commission received for the orders made during the visit</li>
</ul>
\ No newline at end of file
Property changes on: trunk/kernel/module_help/visits_list.txt
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property
Index: trunk/kernel/units/general/cat_dbitem.php
===================================================================
--- trunk/kernel/units/general/cat_dbitem.php (revision 3542)
+++ trunk/kernel/units/general/cat_dbitem.php (revision 3543)
@@ -1,275 +1,354 @@
<?php
class kCatDBItem extends kDBItem {
var $CustomFields = Array();
+ /**
+ * Category path, needed for import
+ *
+ * @var Array
+ */
+ var $CategoryPath = Array();
+
function Init($prefix, $special, $event_params = null)
{
parent::Init($prefix, $special, $event_params);
$item_type = $this->Application->getUnitOption($this->Prefix, 'ItemType');
- $sql = 'SELECT CustomFieldId, FieldName FROM '.TABLE_PREFIX.'CustomField WHERE Type = %s';
- $this->CustomFields = $this->Conn->GetCol( sprintf($sql, $item_type), 'FieldName' );
+ $sql = 'SELECT CustomFieldId, FieldName FROM '.TABLE_PREFIX.'CustomField WHERE Type = '.$item_type;
+ $this->CustomFields = $this->Conn->GetCol($sql, 'FieldName');
}
- function Create()
+ function Create($force_id=false, $system_create=false)
{
if (!$this->Validate()) return false;
$this->checkFilename();
$this->SetDBField('ResourceId', $this->Application->NextResourceId());
$this->SetDBField('Modified', adodb_mktime() );
$this->SetDBField('CreatedById', $this->Application->GetVar('u_id'));
$this->generateFilename();
- $ret = parent::Create();
+ $ret = parent::Create($force_id, $system_create);
if($ret)
{
if ( kTempTablesHandler::IsTempTable($this->TableName) ) {
$table = kTempTablesHandler::GetTempName(TABLE_PREFIX.'CategoryItems');
}
else {
$table = TABLE_PREFIX.'CategoryItems';
}
$cat_id = $this->Application->GetVar('m_cat_id');
$query = 'INSERT INTO '.$table.' (CategoryId,ItemResourceId,PrimaryCat)
VALUES ('.$cat_id.','.$this->GetField('ResourceId').',1)';
$this->Conn->Query($query);
}
return $ret;
}
- function Update($id=null)
+ function Update($id=null, $system_update=false)
{
$this->checkFilename();
$this->VirtualFields['ResourceId'] = true;
$this->SetDBField('Modified', adodb_mktime() );
$this->SetDBField('ModifiedById', $this->Application->GetVar('u_id'));
$this->generateFilename();
- return parent::Update($id);
+ return parent::Update($id, $system_update);
}
function checkFilename()
{
if( !$this->GetDBField('AutomaticFilename') )
{
$filename = $this->GetDBField('Filename');
$this->SetDBField('Filename', $this->stripDisallowed($filename) );
}
}
function Copy($cat_id=null)
{
if (!isset($cat_id)) $cat_id = $this->Application->GetVar('m_cat_id');
$this->NameCopy($cat_id);
return $this->Create($cat_id);
}
function NameCopy($master=null, $foreign_key=null)
{
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
if (!$title_field) return;
$new_name = $this->GetDBField($title_field);
$cat_id = $this->Application->GetVar('m_cat_id');
$original_checked = false;
do {
if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) {
$new_name = 'Copy '.( (int)$regs[1] + 1 ).' of '.$regs[2];
}
elseif ($original_checked) {
$new_name = 'Copy of '.$new_name;
}
$query = 'SELECT '.$title_field.' FROM '.$this->TableName.'
LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON
('.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$this->TableName.'.ResourceId)
WHERE ('.TABLE_PREFIX.'CategoryItems.CategoryId = '.$cat_id.') AND '.
$title_field.' = '.$this->Conn->qstr($new_name);
$res = $this->Conn->GetOne($query);
$original_checked = true;
} while ($res !== false);
$this->SetDBField($title_field, $new_name);
}
function MoveToCat($cat_id=null)
{
// $this->NameCopy();
$cat_id = $this->Application->GetVar('m_cat_id');
// check if the product already exists in destination cat
$query = 'SELECT PrimaryCat FROM '.TABLE_PREFIX.'CategoryItems
WHERE CategoryId = '.$cat_id.' AND ItemResourceId = '.$this->GetDBField('ResourceId');
// if it's not found is_primary will be FALSE, if it's found but not primary it will be int 0
$is_primary = $this->Conn->GetOne($query);
$exists = $is_primary !== false;
if ($exists) { // if the Product already exists in destination category
if ($is_primary) return; // do nothing when we paste to primary
// if it's not primary - delete it from destination category,
// as we will move it from current primary below
$query = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems
WHERE ItemResourceId = '.$this->GetDBField('ResourceId').' AND CategoryId = '.$cat_id;
$this->Conn->Query($query);
}
$query = 'UPDATE '.TABLE_PREFIX.'CategoryItems SET CategoryId = '.$cat_id.
' WHERE ItemResourceId = '.$this->GetDBField('ResourceId').' AND PrimaryCat = 1';
$this->Conn->Query($query);
$this->Update();
}
// We need to delete CategoryItems record when deleting product
function Delete($id=null)
{
if( isset($id) ) {
$this->setID($id);
}
$this->Load($this->GetID());
$ret = parent::Delete();
if ($ret) {
$query = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE ItemResourceId = '.$this->GetDBField('ResourceId');
$this->Conn->Query($query);
}
return $ret;
}
/**
* Deletes item from categories
*
* @param Array $delete_category_ids
* @author Alex
*/
function DeleteFromCategories($delete_category_ids)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); // because item was loaded before by ResourceId
$ci_table = $this->Application->getUnitOption('ci', 'TableName');
$resource_id = $this->GetDBField('ResourceId');
$item_cats_sql = 'SELECT CategoryId FROM %s WHERE ItemResourceId = %s';
$delete_category_items_sql = 'DELETE FROM %s WHERE ItemResourceId = %s AND CategoryId IN (%s)';
$category_ids = $this->Conn->GetCol( sprintf($item_cats_sql, $ci_table, $resource_id) );
$cats_left = array_diff($category_ids, $delete_category_ids);
if(!$cats_left)
{
$sql = 'SELECT %s FROM %s WHERE ResourceId = %s';
$ids = $this->Conn->GetCol( sprintf($sql, $id_field, $this->TableName, $resource_id) );
$temp =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->DeleteItems($this->Prefix, $this->Special, $ids);
}
else
{
$this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids) ) );
$sql = 'SELECT CategoryId FROM %s WHERE PrimaryCat = 1 AND ItemResourceId = %s';
$primary_cat_id = $this->Conn->GetCol( sprintf($sql, $ci_table, $resource_id) );
if( count($primary_cat_id) == 0 )
{
$sql = 'UPDATE %s SET PrimaryCat = 1 WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
$this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id ) );
}
}
}
function SetCustomField($field, $value)
{
$cf_id = getArrayValue($this->CustomFields, $field);
if(!$cf_id) return false;
$data_table = TABLE_PREFIX.'CustomMetaData';
$sql = 'SELECT CustomDataId FROM '.$data_table.' WHERE CustomFieldId = %s AND ResourceId = %s';
$data_id = (int)$this->Conn->GetOne( sprintf($sql, $cf_id, $this->GetDBField('ResourceId') ) );
$lang_id = $this->Application->GetVar('lang.current_id');
$sql = 'REPLACE INTO '.$data_table.'(CustomDataId,ResourceId,CustomFieldId,Value,l'.$lang_id.'_Value) VALUES (%1$s,%2$s,%3$s,%4$s,%4$s)';
$this->Conn->Query( sprintf($sql, $data_id, $this->GetDBField('ResourceId'), $cf_id, $this->Conn->qstr($value) ) );
}
/**
* replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
*
* @param string $string
* @return string
*/
function stripDisallowed($string)
{
$not_allowed = Array( ' ', '\\', '/', ':', '*', '?', '"', '<', '>', '|', '`',
'~', '!', '@', '#', '$', '%', '^', '&', '(', ')', '~',
'+', '=', '-', '{', '}', ']', '[', "'", ';', '.', ',');
$string = str_replace($not_allowed, '_', $string);
$string = preg_replace('/(_+)/', '_', $string);
$string = $this->checkAutoFilename($string);
return $string;
}
function checkAutoFilename($filename)
{
if(!$filename) return $filename;
$item_id = !$this->GetID() ? 0 : $this->GetID();
// check temp table
$sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE Filename = '.$this->Conn->qstr($filename);
$found_temp_ids = $this->Conn->GetCol($sql_temp);
// check live table
$sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename);
$found_live_ids = $this->Conn->GetCol($sql_live);
$found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) );
$has_page = preg_match('/(.*)_([\d]+)([a-z]*)$/', $filename, $rets);
$duplicates_found = (count($found_item_ids) > 1) || ($found_item_ids && $found_item_ids[0] != $item_id);
if ($duplicates_found || $has_page) // other category has same filename as ours OR we have filename, that ends with _number
{
$append = $duplicates_found ? '_a' : '';
if($has_page)
{
$filename = $rets[1].'_'.$rets[2];
$append = $rets[3] ? $rets[3] : '_a';
}
// check live & temp table
$sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')';
$sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')';
while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 ||
$this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 )
{
if (substr($append, -1) == 'z') $append .= 'a';
$append = substr($append, 0, strlen($append) - 1) . chr( ord( substr($append, -1) ) + 1 );
}
return $filename.$append;
}
return $filename;
}
/**
* Generate item's filename based on it's title field value
*
* @return string
*/
function generateFilename()
{
if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false;
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
$name = $this->stripDisallowed( $this->GetDBField($title_field) );
if ( $name != $this->GetDBField('Filename') ) $this->SetDBField('Filename', $name);
}
+
+ /**
+ * Check if value is set for required field
+ *
+ * @param string $field field name
+ * @param Array $params field options from config
+ * @return bool
+ * @access private
+ */
+ function ValidateRequired($field, $params)
+ {
+ $res = true;
+ $error_field = isset($params['error_field']) ? $params['error_field'] : $field;
+ if ( getArrayValue($params,'required') )
+ {
+ if (getArrayValue($params, 'formatter') == 'kUploadFormatter')
+ {
+ $value = $this->GetDBField($field);
+ $res = is_array($value) && $value['size'] ? true : false;
+ }
+ else {
+ $res = ( (string) $this->FieldValues[$field] != '');
+ }
+ }
+ if (!$res) $this->FieldErrors[$error_field]['pseudo'] = 'required';
+ return $res;
+ }
+
+ /**
+ * Adds item to other category
+ *
+ * @param int $category_id
+ * @param bool $is_primary
+ */
+ function assignToCategory($category_id, $is_primary = false)
+ {
+ $check_sql = ' SELECT CategoryId
+ FROM '.TABLE_PREFIX.'CategoryItems
+ WHERE (ItemResourceId = '.$this->GetDBField('ResourceId').') AND (PrimaryCat = 1)';
+ $primary_category_id = $this->Conn->GetOne($check_sql);
+ if (!$primary_category_id) $is_primary = true;
+
+ if ($primary_category_id == $category_id) return ;
+
+ $sql = 'INSERT INTO '.TABLE_PREFIX.'CategoryItems (CategoryId,ItemResourceId,PrimaryCat) VALUES (%s,%s,%s)';
+ $this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId'), $is_primary ? 1 : 0) );
+ }
+
+ /**
+ * Removes item from category specified
+ *
+ * @param int $category_id
+ */
+ function removeFromCategory($category_id)
+ {
+ $sql = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
+ $this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId')) );
+ }
+
+ /**
+ * Returns list of columns, that could exist in imported file
+ *
+ * @return Array
+ */
+ function getPossibleExportColumns()
+ {
+ static $columns = null;
+ if (!is_array($columns)) {
+ $columns = array_merge($this->Fields['AvailableColumns']['options'], $this->Fields['ExportColumns']['options']);
+ }
+ return $columns;
+ }
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/cat_dbitem.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.18
\ No newline at end of property
+1.19
\ No newline at end of property
Index: trunk/kernel/units/general/cat_dbitem_export.php
===================================================================
--- trunk/kernel/units/general/cat_dbitem_export.php (nonexistent)
+++ trunk/kernel/units/general/cat_dbitem_export.php (revision 3543)
@@ -0,0 +1,848 @@
+<?php
+
+ define('EXPORT_STEP', 200); // export by 200 items (e.g. links)
+ define('IMPORT_CHUNK', 50120); // 5 KB
+
+ class kCatDBItemExportHelper extends kHelper {
+
+
+ var $cache = Array();
+
+ var $exportFields = Array();
+
+ /**
+ * Export options
+ *
+ * @var Array
+ */
+ var $exportOptions = Array();
+
+ /**
+ * If we have custom fields in export
+ *
+ * @var unknown_type
+ */
+ var $hasCustomFields = false;
+
+ /**
+ * Custom field values for last item beeing exported
+ *
+ * @var Array
+ */
+ var $customValues = 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;
+
+ /**
+ * 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)
+ {
+// if (!isset($this->cache[$type])) $this->cache[$type] = Array();
+ $this->cache[$type][$key] = $value;
+ }
+
+ /**
+ * Fill required fields with dummy values
+ *
+ * @param kEvent $event
+ */
+ function fillRequiredFields(&$event)
+ {
+ $object =& $event->getObject();
+
+ $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;
+
+ $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);
+ }
+ $object->SetDBField($field_name, isset($sample_value) && $sample_value ? $sample_value : 'dummy');
+ }
+ }
+
+ /**
+ * 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);
+
+ $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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+
+ $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;
+ }
+
+ // 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();
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns filename to read import data from
+ *
+ * @return string
+ */
+ function getImportFilename()
+ {
+ if ($this->exportOptions['ImportSource'] == 1)
+ {
+ $ret = $this->exportOptions['ImportFilename']['name'];
+ }
+ 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');
+ }
+ }
+
+ /**
+ * 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
+ $sql = 'SELECT item_table.*, ci.CategoryId
+ 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 ';
+
+ 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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ $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 ($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) );
+ $this->exportOptions['has_custom_fields'] = $this->scanCustomFields();
+ }
+
+ $this->hasCustomFields = $this->exportOptions['has_custom_fields'];
+
+ // 2. export data
+ $records = $this->Conn->Query( $this->getExportSQL() );
+ $records_exported = 0;
+ foreach ($records as $record_info) {
+ $this->curItem->SetDBFieldsFromHash($record_info);
+ if ($this->hasCustomFields)
+ {
+ $this->loadItemCustomFields();
+ }
+
+ $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->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($this->exportOptions) );
+
+ 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]);
+ }
+
+ /**
+ * 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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ }
+
+ $this->curItem =& $event->getObject( Array('skip_autoload' => true) );
+
+ $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->cache['new_ids'] = $this->exportOptions['new_ids_hash'];
+ }
+ $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)) {
+ $this->customValues = Array();
+ $data = $this->readRecord();
+ if ($data) {
+ foreach ($data as $field_index => $field_value) {
+ $this->setFieldValue($field_index, $field_value);
+ }
+ $this->curItem->setID( $this->curItem->GetDBField($this->curItem->IDField) );
+ $this->processCurrentItem($event);
+ }
+ $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->exportOptions['new_ids_hash'] = getArrayValue($this->cache, 'new_ids');
+ $this->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($this->exportOptions) );
+
+ return $this->exportOptions;
+ }
+
+ function setFieldValue($field_index, $value)
+ {
+ $field_name = $this->exportFields[$field_index];
+
+ if (substr($field_name, 0, 7) == 'Custom_') {
+ $field_name = substr($field_name, 7);
+ $this->customValues[$field_name] = $value;
+ }
+ elseif ($field_name == 'CategoryPath') {
+ $this->curItem->CategoryPath = explode($this->exportOptions['CategorySeparator'], $value);
+ }
+ elseif (substr($field_name, 0, 8) == 'Category') {
+ $this->curItem->CategoryPath[ (int)substr($field_name, 8) ] = $value;
+ }
+ else {
+ $this->curItem->SetField($field_name, $value);
+ }
+ }
+
+ /**
+ * Returns temporary items for import procedures
+ *
+ * @param kEvent $event
+ * @return kCatDBItem
+ */
+ function &getTempItem(&$event)
+ {
+ return $this->Application->recallObject($event->Prefix.'.-tmpitem', $event->Prefix, Array('skip_autoload' => true));
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function processCurrentItem(&$event)
+ {
+ $tmp_item =& $this->getTempItem($event);
+
+ // create/update categories
+ $backup_category_id = $this->Application->GetVar('m_cat_id');
+
+ foreach ($this->curItem->CategoryPath as $category_name) {
+ if (!$category_name) continue;
+ $category_id = $this->getFromCache('category_names', $category_name);
+ 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 (ParentPath LIKE "'.$parent_path.'%")';
+ $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,
+ );
+ $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_name, $category_id);
+ }
+ }
+ else {
+ $this->addToCache('category_names', $category_name, $category_id);
+ }
+ }
+
+ if ($category_id) {
+ $this->Application->SetVar('m_cat_id', $category_id);
+ }
+ }
+
+ // create main record
+ $save_method = 'Create';
+ if ($this->exportOptions['ReplaceDuplicates']) {
+ if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
+ $load_keys = Array($this->curItem->IDField => $this->curItem->GetID());
+ }
+ else {
+ $key_fields = explode('|', substr($this->exportOptions['DuplicateCheckFields']) );
+ foreach ($key_fields as $key_field) {
+ $load_keys[$key_field] = $this->curItem->GetDBField($key_field);
+ }
+ }
+
+ $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', $where_clause);
+ if (!$item_id) {
+ $parent_path = $this->getParentPath($category_id);
+ $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 (c.ParentPath LIKE "'.$parent_path.'%") AND '.$where_clause;
+ $item_id = $this->Conn->GetOne($sql);
+ }
+ $save_method = $tmp_item->Load($item_id) ? 'Update' : 'Create';
+ }
+
+ $resource_id = $tmp_item->isLoaded() ? $tmp_item->GetDBField('ResourceId') : 0;
+ $tmp_item->SetDBFieldsFromHash($this->curItem->FieldValues);
+ if( ($save_method == 'Update') && $resource_id ) {
+ $tmp_item->SetDBField('ResourceId', $resource_id);
+ }
+
+ if (!$tmp_item->$save_method()) return false;
+
+ if ( ($save_method == 'Create') && $this->exportOptions['ReplaceDuplicates'] ) {
+ // map new id to old id
+ $this->addToCache('new_ids', $where_clause, $tmp_item->GetID() );
+ }
+
+ // set custom fields
+ foreach ($this->customValues as $custom_field => $custom_value) {
+ if (($save_method == 'Create') && !$custom_value) continue;
+ $tmp_item->SetCustomField($custom_field, $custom_value);
+ }
+
+ // assign item to categories
+ $tmp_item->assignToCategory($category_id, false);
+
+ $this->Application->SetVar('m_cat_id', $backup_category_id);
+ return true;
+ }
+
+ /**
+ * 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 loadItemCustomFields()
+ {
+ $sql = 'SELECT meta_data.Value, cf.FieldName
+ FROM '.TABLE_PREFIX.'CustomMetaData meta_data
+ LEFT JOIN '.TABLE_PREFIX.'CustomField cf ON cf.CustomFieldId = meta_data.CustomFieldId
+ WHERE meta_data.ResourceId = '.$this->curItem->GetDBField('ResourceId');
+ $this->customValues = $this->Conn->GetCol($sql, 'FieldName');
+ }
+
+ function getFileExtension()
+ {
+ return $this->exportOptions['ExportFormat'] == 1 ? 'csv' : 'xml';
+ }
+
+ function getLineSeparator($option = 'LineEndings')
+ {
+ return $this->exportOptions[$option] == 1 ? "\r\n" : "\n";
+ }
+
+ function scanCustomFields()
+ {
+ $ret = false;
+ $export_fields = $this->exportOptions['ExportColumns'];
+ foreach ($export_fields as $field)
+ {
+ if (substr($field, 0, 10) == '__CUSTOM__')
+ {
+ $ret = true;
+ break;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * 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();
+ }
+ 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 = substr($field, 10, strlen($field) );
+ $ret = isset($this->customValues[$field]) ? $this->customValues[$field] : '';
+ }
+ elseif (substr($field, 0, 12) == '__CATEGORY__')
+ {
+ return $this->getCategoryPath();
+ }
+ 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()
+ {
+ if ($this->exportOptions['CategoryFormat'] == 1)
+ {
+ // category path in one field
+ return Array('CategoryPath');
+ }
+ else
+ {
+ // category path in separated fields
+ $category_count = $this->getMaxCategoryLevel();
+
+ $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 = explode('>', $category_path);
+
+ if ($this->exportOptions['IsBaseCategory'] ) {
+ $i = $this->exportOptions['BaseLevel'];
+ while ($i > 0) {
+ array_shift($category_path);
+ $i--;
+ }
+ }
+
+ if ($this->exportOptions['CategoryFormat'] == 1) {
+ // category path in single field
+ $category_path = Array( implode($this->exportOptions['CategorySeparator'], $category_path) );
+ }
+ else {
+ // category path in separated fields
+ $category_count = $this->getMaxCategoryLevel();
+ $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']);
+ }
+ }
+
+?>
Property changes on: trunk/kernel/units/general/cat_dbitem_export.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/kernel/units/general/cat_tag_processor.php
===================================================================
--- trunk/kernel/units/general/cat_tag_processor.php (revision 3542)
+++ trunk/kernel/units/general/cat_tag_processor.php (revision 3543)
@@ -1,28 +1,80 @@
<?php
class kCatDBTagProcessor extends kDBTagProcessor {
function ItemIcon($params)
{
$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$icons =& $grids[ $params['grid'] ]['Icons'];
$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
if(!$status_fields) return $icons['default'];
$value = $object->GetDBField($status_fields[0]); // sets base status icon
if($value == STATUS_ACTIVE)
{
if( $object->GetDBField('IsPop') ) $value = 'POP';
if( $object->GetDBField('IsHot') ) $value = 'HOT';
if( $object->GetDBField('IsNew') ) $value = 'NEW';
if( $object->GetDBField('EditorsPick') ) $value = 'PICK';
}
return isset($icons[$value]) ? $icons[$value] : $icons['default'];
}
+
+ /**
+ * Returns path where exported category items should be saved
+ *
+ * @param Array $params
+ */
+ function ExportPath($params)
+ {
+ $ret = EXPORT_PATH.'/';
+
+ if( getArrayValue($params, 'as_url') )
+ {
+ $ret = str_replace( FULL_PATH.'/', $this->Application->BaseURL(), $ret);
+ }
+
+ $export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial().'_options'));
+ $ret .= $export_options['ExportFilename'].'.'.($export_options['ExportFormat'] == 1 ? 'csv' : 'xml');
+
+ return $ret;
+ }
+
+ function CategoryPath($params)
+ {
+ if (!isset($params['cat_id']))
+ {
+ $params['cat_id'] = $this->Application->RecallVar($params['session_var'], 0);
+ }
+
+ $block_params['separator'] = $params['separator'];
+
+ if($params['cat_id'] == 0)
+ {
+ $block_params['name'] = $params['rootcatblock'];
+ return $this->Application->ParseBlock($block_params);
+ }
+ else
+ {
+ $cat_object =& $this->Application->recallObject('c', 'c_List');
+ $sql = 'SELECT CategoryId, ParentId, Name FROM '.$cat_object->TableName.' WHERE CategoryId = '.$params['cat_id'];
+ $res = $this->Conn->GetRow($sql);
+
+ $block_params['name'] = $params['block'];
+ $block_params['cat_name'] = $res['Name'];
+ $block_params['cat_id'] = $res['CategoryId'];
+
+ $next_params['separator'] = $params['separator'];
+ $next_params['rootcatblock'] = $params['rootcatblock'];
+ $next_params['block'] = $params['block'];
+ $next_params['cat_id'] = $res['ParentId'];
+ return $this->CategoryPath($next_params).$this->Application->ParseBlock($block_params);
+ }
+ }
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/cat_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property
Index: trunk/kernel/units/general/cat_event_handler.php
===================================================================
--- trunk/kernel/units/general/cat_event_handler.php (revision 3542)
+++ trunk/kernel/units/general/cat_event_handler.php (revision 3543)
@@ -1,1011 +1,1385 @@
<?php
$application =& kApplication::Instance();
$application->Factory->includeClassFile('kDBEventHandler');
class kCatDBEventHandler extends InpDBEventHandler {
function OnCopy(&$event)
{
$object = $event->getObject();
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard', implode(',', $ids));
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard_mode', 'copy');
$this->Application->StoreVar('ClipBoard', 'COPY-0.'.$object->TableName.'.ResourceId=0');
$event->redirect_params = Array('opener' => 's', 'pass_events'=>true); //do not go up - STAY
}
function OnCut(&$event)
{
$object = $event->getObject();
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard', implode(',', $ids));
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard_mode', 'cut');
$this->Application->StoreVar('ClipBoard', 'CUT-0.'.$object->TableName.'.ResourceId=0');
$event->redirect_params = Array('opener' => 's', 'pass_events'=>true); //do not go up - STAY
}
function OnPaste(&$event)
{
$ids = $this->Application->RecallVar($event->getPrefixSpecial().'_clipboard');
if ($ids == '') {
$event->redirect = false;
return;
}
//recalling by different name, because we may get kDBList, if we recall just by prefix
$object =& $this->Application->recallObject($event->getPrefixSpecial().'.item', $event->Prefix);
$this->prepareObject($object, $event);
if ($this->Application->RecallVar($event->getPrefixSpecial().'_clipboard_mode') == 'copy') {
$ids_arr = explode(',', $ids);
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if($ids_arr)
{
$temp->CloneItems($event->Prefix, $event->Special, $ids_arr);
}
}
else { // mode == cut
$ids_arr = explode(',', $ids);
foreach ($ids_arr as $id) {
$object->Load($id);
$object->MoveToCat();
}
}
$event->status = erSUCCESS;
}
/**
* Occurs when pasting category
*
* @param kEvent $event
*/
function OnCatPaste(&$event)
{
$inp_clipboard = $this->Application->RecallVar('ClipBoard');
$inp_clipboard = explode('-', $inp_clipboard, 2);
if($inp_clipboard[0] == 'COPY')
{
$saved_cat_id = $this->Application->GetVar('m_cat_id');
$cat_ids = $event->getEventParam('cat_ids');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$ids_sql = 'SELECT '.$id_field.' FROM '.$table.' WHERE ResourceId IN (%s)';
$resource_ids_sql = 'SELECT ItemResourceId FROM '.TABLE_PREFIX.'CategoryItems WHERE CategoryId = %s AND PrimaryCat = 1';
$this->Application->setUnitOption($event->Prefix,'AutoLoad', false);
$object =& $this->Application->recallObject($event->Prefix.'.item', $event->Prefix);
foreach($cat_ids as $source_cat => $dest_cat)
{
$item_resource_ids = $this->Conn->GetCol( sprintf($resource_ids_sql, $source_cat) );
if(!$item_resource_ids) continue;
$this->Application->SetVar('m_cat_id', $dest_cat);
$item_ids = $this->Conn->GetCol( sprintf($ids_sql, implode(',', $item_resource_ids) ) );
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if($item_ids) $temp->CloneItems($event->Prefix, $event->Special, $item_ids);
}
$this->Application->setUnitOption($event->Prefix,'AutoLoad', true);
$this->Application->SetVar('m_cat_id', $saved_cat_id);
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnPreSaveAndOpenTranslator(&$event)
{
$this->Application->SetVar('allow_translation', true);
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
// $url = $this->Application->HREF($t, '', Array('pass'=>'all', $event->getPrefixSpecial(true).'_id' => $object->GetId()));
// $field = $this->Application->GetVar('translator_field');
$cf_id = $this->Application->GetVar('translator_cf_id');
if($cf_id)
{
$cv =& $this->Application->recallObject('cv.-item', null, Array('skip_autoload' => true) );
$load_params = Array('CustomFieldId' => $cf_id, 'ResourceId'=> $object->GetDBField('ResourceId') );
if( !$cv->Load($load_params) )
{
$cv->SetFieldsFromHash($load_params);
$cv->Create();
}
$this->Application->SetVar('cv_id', $cv->getID() );
}
$event->redirect = $this->Application->GetVar('translator_t');
$event->redirect_params = Array('pass'=>'all,trans,'.$this->Application->GetVar('translator_prefixes'),
$event->getPrefixSpecial(true).'_id' => $object->GetId(),
'trans_event'=>'OnLoad',
'trans_prefix'=> $this->Application->GetVar('translator_prefixes'),
'trans_field'=>$this->Application->GetVar('translator_field'),
'trans_multi_line'=>$this->Application->GetVar('translator_multi_line'),
);
// 1. SAVE LAST TEMPLATE TO SESSION
$last_template = $this->Application->RecallVar('last_template');
preg_match('/index4\.php\|'.$this->Application->GetSID().'-(.*):/U', $last_template, $rets);
// $this->Application->StoreVar('return_template', $rets[1]);
$this->Application->StoreVar('return_template', $this->Application->GetVar('t'));
//$after_script = "openTranslator('".$event->getPrefixSpecial()."', '".$field."', '".$url."', '".$wnd_name."')";
}
// $this->Application->SetVar('after_script', $after_script);
// $event->redirect = false;
}
/**
* Apply scope clause
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
if ($event->Special != 'showall') {
if ( $event->getEventParam('parent_cat_id') ) {
$parent_cat_id = $event->getEventParam('parent_cat_id');
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
if ((string) $parent_cat_id != 'any') {
if ($event->getEventParam('recursive')) {
$current_path = $this->Conn->GetOne('SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId='.$parent_cat_id);
$subcats = $this->Conn->GetCol('SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ParentPath LIKE "'.$current_path.'%" ');
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId IN ('.implode(', ', $subcats).')');
}
else {
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId = '.$parent_cat_id );
}
}
}
else {
$object->addFilter('primary_filter', 'PrimaryCat = 1');
}
$view_perm = 1;
$object->addFilter('perm_filter', 'perm.PermId = '.$view_perm);
if ( !$this->Application->IsAdmin() )
{
$groups = explode( ',', $this->Application->RecallVar('UserGroups') );
foreach($groups as $group)
{
$view_filters[] = 'FIND_IN_SET('.$group.', perm.acl) || ((NOT FIND_IN_SET('.$group.',perm.dacl)) AND perm.acl=\'\')';
}
$view_filter = implode(' OR ', $view_filters);
$object->addFilter('perm_filter2', $view_filter);
$object->addFilter('status_filter', $object->TableName.'.Status = 1');
}
/*$list_type = $event->getEventParam('ListType');
switch($list_type)
{
case 'favorites':
$fav_table = $this->Application->getUnitOption('fav','TableName');
$user_id =& $this->Application->GetVar('u_id');
$sql = 'SELECT DISTINCT f.ResourceId
FROM '.$fav_table.' f
LEFT JOIN '.$object->TableName.' p ON p.ResourceId = f.ResourceId
WHERE f.PortalUserId = '.$user_id;
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.PrimaryCat = 1');
$object->addFilter('favorites_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
case 'search':
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = ' SELECT DISTINCT ResourceId
FROM '.$search_results_table.'
WHERE ItemType=11';
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('search_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
} */
}
/**
* Adds calculates fields for item statuses
*
* @param kCatDBItem $object
* @param kEvent $event
*/
- function PrepareObject(&$object, &$event)
+ function prepareObject(&$object, &$event)
{
+ $this->prepareItemStatuses($event);
+
+ if ($event->Special == 'export' || $event->Special == 'import')
+ {
+ $this->prepareExportColumns($event);
+ }
+ }
+ /**
+ * Creates calculated fields for all item statuses based on config settings
+ *
+ * @param kEvent $event
+ */
+ function prepareItemStatuses(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if($new_days_var)
{
$object->addCalculatedField('IsNew', ' IF(%1$s.NewItem = 2,
IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0),
%1$s.NewItem
)');
}
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_limit_var)
{
$sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = "'.$hot_limit_var.'"';
$hot_limit = $this->Conn->GetOne($sql);
if($hot_limit === false) $hot_limit = $this->CalculateHotLimit($event);
$object->addCalculatedField('IsHot', ' IF(%1$s.HotItem = 2,
IF(%1$s.Hits >= '.$hot_limit.', 1, 0),
%1$s.HotItem
)');
}
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if($votes2pop_var && $rating2pop_var)
{
$object->addCalculatedField('IsPop', ' IF(%1$s.PopItem = 2,
IF(%1$s.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND %1$s.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0),
%1$s.PopItem)');
}
}
-
+
function CalculateHotLimit(&$event)
{
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
$hot_count_var = getArrayValue($property_mappings, 'HotCount');
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_count_var && $hot_limit_var)
{
$last_hot = $this->Application->ConfigValue($hot_count_var) - 1;
$sql = 'SELECT Hits FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
ORDER BY Hits DESC
LIMIT '.$last_hot.', 1';
$res = $this->Conn->GetCol($sql);
$hot_limit = (double)array_shift($res);
$this->Conn->Query('REPLACE INTO '.TABLE_PREFIX.'Cache VALUES ("'.$hot_limit_var.'", "'.$hot_limit.'", '.adodb_mktime().')');
return $hot_limit;
}
return 0;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$object =& $event->getObject();
if( $this->Application->IsAdmin() && ($this->Application->GetVar('Hits_original') !== false) &&
floor($this->Application->GetVar('Hits_original')) != $object->GetDBField('Hits') )
{
$sql = 'SELECT MAX(Hits) FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE FLOOR(Hits) = '.$object->GetDBField('Hits');
$hits = ( $res = $this->Conn->GetOne($sql) ) ? $res + 0.000001 : $object->GetDBField('Hits');
$object->SetDBField('Hits', $hits);
}
}
function OnAfterItemUpdate(&$event)
{
$this->CalculateHotLimit($event);
}
/**
* Makes simple search for products
* based on keywords string
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnSimpleSearch(&$event)
{
if($this->Application->GetVar('INPORTAL_ON') && !($this->Application->GetVar('Action') == 'm_simple_search'))
{
return;
}
$event->redirect = false;
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$keywords = trim($this->Application->GetVar('keywords'));
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$keywords = unhtmlentities($keywords);
}
$query_object =& $this->Application->recallObject('HTTPQuery');
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if(!isset($query_object->Get['keywords']) &&
!isset($query_object->Post['keywords']) &&
$this->Conn->Query($sql))
{
return; // used when navigating by pages or changing sorting in search results
}
if(!$keywords || strlen($keywords) < $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$this->Application->SetVar('keywords_too_short', 1);
return; // if no or too short keyword entered, doing nothing
}
$this->Application->StoreVar('keywords', $keywords);
$keywords = strtr($keywords, Array('%' => '\\%', '_' => '\\_'));
$event->setPseudoClass('_List');
$object =& $event->getObject();
$this->Application->SetVar($event->getPrefixSpecial().'_Page', 1);
$lang = $this->Application->GetVar('m_lang');
$product_table = $this->Application->getUnitOption('p', 'TableName');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="In-Commerce"
AND SimpleSearch=1';
$search_config = $this->Conn->Query($sql, 'FieldName');
$field_list = array_keys($search_config);
$join_clauses = Array();
// field processing
$weight_sum = 0;
foreach($field_list as $key => $field)
{
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$search_config[$field]['TableName'];
$weight_sum += $search_config[$field]['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if($options['formatter'] == 'kMultiLanguage')
{
$field_list[$key] = 'l'.$lang.'_'.$field;
}
// processing fields from other tables
if($foreign_field = $search_config[$field]['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
unset($field_list[$key]);
continue; // ignoring having type clauses in simple search
/*$user_object =& $this->Application->recallObject('u');
$user_groups = $user_object->GetDBField('PortalUserId') ?
implode(',', $this->Conn->GetCol(' SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE PortalUserId='.$user_object->GetDBField('PortalUserId'))) : 0;
$having_list[$key] = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$join_clauses[] = $join_clause;*/
}
else
{
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
$field_list[$key] = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{LocalTable}', $product_table, $join_clause);
if($search_config[$field]['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$search_config[$field]['CustomFieldId'];
}
$join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
$field_list[$key] = $local_table.'.'.$field_list[$key];
}
}
// keyword string processing
$normal_keywords = Array();
$plus_keywords = Array();
$minus_keywords = Array();
for($i = 0; $i < strlen($keywords); $i++)
{
if(substr($keywords, $i, 1) == ' ') continue;
$extra_skip = 0;
switch(substr($keywords, $i, 1))
{
case '+':
if(substr($keywords, $i + 1, 1) == '"')
{
$keyword_start = $i + 2;
$keyword_end = strpos($keywords, '"', $i + 2);
$extra_skip = 2;
}
else
{
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, ' ', $i + 1);
$extra_skip = 0;
}
$target_array =& $plus_keywords;
break;
case '-':
if(substr($keywords, $i + 1, 1) == '"')
{
$keyword_start = $i + 2;
$keyword_end = strpos($keywords, '"', $i + 2);
$extra_skip = 2;
}
else
{
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, ' ', $i + 1);
$extra_skip = 0;
}
$target_array =& $minus_keywords;
break;
case '"':
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, '"', $i + 1);
$extra_skip = 1;
$target_array =& $normal_keywords;
break;
default:
$keyword_start = $i;
$keyword_end = strpos($keywords, ' ', $i + 1);
$target_array =& $normal_keywords;
}
if($keyword_end === false)
{
$keyword_end = strlen($keywords);
}
$keyword_length = $keyword_end - $keyword_start;
$keyword = substr($keywords, $keyword_start, $keyword_length);
if(strlen($keyword) >= $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$target_array[] = addcslashes($keyword, '"');
}
$i += $keyword_length + $extra_skip;
}
// preparing conditions
$normal_conditions = Array();
$plus_conditions = Array();
$minus_conditions = Array();
foreach($normal_keywords as $keyword)
{
$normal_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $field_list).' LIKE "%'.$keyword.'%"';
}
foreach($plus_keywords as $keyword)
{
$plus_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $field_list).' LIKE "%'.$keyword.'%"';
}
foreach($minus_keywords as $keyword)
{
foreach($field_list as $field)
{
$condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL';
}
$minus_conditions[] = '('.implode(') AND (', $condition).')';
}
// building where clause
if($normal_conditions)
{
$where_clause = '('.implode(') OR (', $normal_conditions).')';
}
else
{
$where_clause = '1';
}
if($plus_conditions)
{
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $plus_conditions).')';
}
if($minus_conditions)
{
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $minus_conditions).')';
}
$where_clause = $where_clause.' AND '.$product_table.'.Status=1';
if($this->Application->GetVar('Action') == 'm_simple_subsearch') // subsearch, In-portal
{
if( $event->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$product_table.'.ResourceId IN ('.implode(',', $event->specificParams['ResultIds']).')';
}
}
if( $event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild' ) // subsearch, k4
{
if( $event->MasterEvent->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$product_table.'.ResourceId IN ('.implode(',', $event->MasterEvent->getEventParam('ResultIds')).')';
}
}
// building having clause
// making relevance clause
$positive_words = array_merge($normal_keywords, $plus_keywords);
$this->Application->StoreVar('highlight_keywords', serialize($positive_words));
$revelance_parts = Array();
reset($search_config);
foreach($field_list as $field)
{
$config_elem = each($search_config);
$weight = $search_config[$field]['Priority'];
$revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)';
foreach($positive_words as $keyword)
{
$revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$config_elem['value']['Priority'].', 0)';
}
}
$rel_keywords = $this->Application->ConfigValue('SearchRel_DefaultKeyword_products') / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_DefaultPop_products') / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_DefaultRating_products') / 100;
$relevance_clause = '('.implode(' + ', $revelance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
// building final search query
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table); // erase old search table if clean k4 event
}
if($this->Conn->Query('SHOW TABLES LIKE "'.$search_table.'"'))
{
$select_intro = 'INSERT INTO '.$search_table.' (Relevance, ItemId, ResourceId, ItemType, EdPick) ';
}
else
{
$select_intro = 'CREATE TABLE '.$search_table.' AS ';
}
$sql = $select_intro.' SELECT '.$relevance_clause.' AS Relevance,
'.$product_table.'.ProductId AS ItemId,
'.$product_table.'.ResourceId,
11 AS ItemType,
'.$product_table.'.EditorsPick AS EdPick
FROM '.$object->TableName.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$product_table.'.ProductId';
$res = $this->Conn->Query($sql);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSubSearch(&$event)
{
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if($this->Conn->Query($sql))
{
$sql = 'SELECT DISTINCT ResourceId FROM '.$search_table;
$ids = $this->Conn->GetCol($sql);
}
$event->setEventParam('ResultIds', $ids);
$event->CallSubEvent('OnSimpleSearch');
}
/**
* Enter description here...
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnAdvancedSearch(&$event)
{
$query_object =& $this->Application->recallObject('HTTPQuery');
if(!isset($query_object->Post['andor']))
{
return; // used when navigating by pages or changing sorting in search results
}
$this->Application->RemoveVar('keywords');
$this->Application->RemoveVar('Search_Keywords');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="In-Commerce"
AND AdvancedSearch=1';
$search_config = $this->Conn->Query($sql);
$lang = $this->Application->GetVar('m_lang');
$object =& $event->getObject();
$object->SetPage(1);
$user_object =& $this->Application->recallObject('u');
$product_table = $this->Application->getUnitOption('p', 'TableName');
$keywords = $this->Application->GetVar('value');
$verbs = $this->Application->GetVar('verb');
$glues = $this->Application->GetVar('andor');
$and_conditions = Array();
$or_conditions = Array();
$and_having_conditions = Array();
$or_having_conditions = Array();
$join_clauses = Array();
$highlight_keywords = Array();
$relevance_parts = Array();
$condition_patterns = Array( 'any' => '%s LIKE %s',
'contains' => '%s LIKE %s',
'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
'is' => '%s = %s',
'isnot' => '(%1$s != %2$s OR %1$s IS NULL)');
$alias_counter = 0;
$weight_sum = 0;
// processing fields and preparing conditions
foreach($search_config as $record)
{
$field = $record['FieldName'];
$join_clause = '';
$condition_mode = 'WHERE';
// field processing
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$record['TableName'];
$weight_sum += $record['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if($options['formatter'] == 'kMultiLanguage')
{
$field_name = 'l'.$lang.'_'.$field;
}
else
{
$field_name = $field;
}
// processing fields from other tables
if($foreign_field = $record['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
$user_groups = $user_object->GetDBField('PortalUserId') ?
implode(',', $this->Conn->GetCol(' SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE PortalUserId='.$user_object->GetDBField('PortalUserId'))) : 0;
$field_name = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $record['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$condition_mode = 'HAVING';
}
else
{
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
$field_name = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $record['JoinClause']);
$join_clause = str_replace('{LocalTable}', $product_table, $join_clause);
if($record['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$record['CustomFieldId'];
}
$join_clause = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
$field_name = $local_table.'.'.$field_name;
}
$condition = '';
switch($record['FieldType'])
{
case 'text':
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$keywords[$field] = unhtmlentities( $keywords[$field] );
}
if(strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$highlight_keywords[] = $keywords[$field];
if( in_array($verbs[$field], Array('any', 'contains', 'notcontains')) )
{
$keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
}
$condition = sprintf( $condition_patterns[$verbs[$field]],
$field_name,
$this->Conn->qstr( $keywords[$field] ));
}
break;
case 'boolean':
if($keywords[$field] != -1)
{
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
switch($field)
{
case 'HotItem':
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_limit_var)
{
$sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName="'.$hot_limit_var.'"';
$hot_limit = (int)$this->Conn->GetOne($sql);
$condition = 'IF('.$product_table.'.HotItem = 2,
IF('.$product_table.'.Hits >= '.
$hot_limit.
', 1, 0), '.$product_table.'.HotItem) = '.$keywords[$field];
}
break;
case 'PopItem':
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if($votes2pop_var && $rating2pop_var)
{
$condition = 'IF('.$product_table.'.PopItem = 2, IF('.$product_table.'.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND '.$product_table.'.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0), '.$product_table.'.PopItem) = '.$keywords[$field];
}
break;
case 'NewItem':
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if($new_days_var)
{
$condition = 'IF('.$product_table.'.NewItem = 2,
IF('.$product_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0), '.$product_table.'.NewItem) = '.$keywords[$field];
}
break;
case 'EditorsPick':
$condition = $product_table.'.EditorsPick = '.$keywords[$field];
break;
}
}
break;
case 'range':
$range_conditions = Array();
if($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from']))
{
$range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
}
if($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to']))
{
$range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
}
if($range_conditions)
{
$condition = implode(' AND ', $range_conditions);
}
break;
case 'date':
if($keywords[$field])
{
if( in_array($keywords[$field], Array('today', 'yesterday')) )
{
$current_time = getdate();
$day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
$time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
$min_time = $time_mapping[$keywords[$field]];
}
else
{
$time_mapping = Array( 'last_week' => 604800, 'last_month' => 2628000,
'last_3_months' => 7884000, 'last_6_months' => 15768000,
'last_year' => 31536000
);
$min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
}
$condition = $field_name.' > '.$min_time;
}
break;
}
if($condition)
{
if($join_clause)
{
$join_clauses[] = $join_clause;
}
$relevance_parts[] = 'IF('.$condition.', '.$record['Priority'].', 0)';
if($glues[$field] == 1) // and
{
if($condition_mode == 'WHERE')
{
$and_conditions[] = $condition;
}
else
{
$and_having_conditions[] = $condition;
}
}
else // or
{
if($condition_mode == 'WHERE')
{
$or_conditions[] = $condition;
}
else
{
$or_having_conditions[] = $condition;
}
}
}
}
$this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords));
// making relevance clause
if($relevance_parts)
{
$rel_keywords = $this->Application->ConfigValue('SearchRel_DefaultKeyword_products') / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_DefaultPop_products') / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_DefaultRating_products') / 100;
$relevance_clause = '('.implode(' + ', $relevance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
else
{
$relevance_clause = '0';
}
// building having clause
if($or_having_conditions)
{
$and_having_conditions[] = '('.implode(' OR ', $or_having_conditions).')';
}
$having_clause = implode(' AND ', $and_having_conditions);
$having_clause = $having_clause ? ' HAVING '.$having_clause : '';
// building where clause
if($or_conditions)
{
$and_conditions[] = '('.implode(' OR ', $or_conditions).')';
}
// $and_conditions[] = $product_table.'.Status = 1';
$where_clause = implode(' AND ', $and_conditions);
if(!$where_clause)
{
if($having_clause)
{
$where_clause = '1';
}
else
{
$where_clause = '0';
$this->Application->SetVar('adv_search_error', 1);
}
}
$where_clause .= ' AND '.$product_table.'.Status = 1';
// building final search query
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$sql = ' CREATE TABLE '.$search_table.'
SELECT '.$relevance_clause.' AS Relevance,
'.$product_table.'.ProductId AS ItemId,
'.$product_table.'.ResourceId AS ResourceId,
11 AS ItemType,
'.$product_table.'.EditorsPick AS EdPick
FROM '.$product_table.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$product_table.'.ProductId'.
$having_clause;
$res = $this->Conn->Query($sql);
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page)
{
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page)
{
if( $this->Application->RewriteURLs() )
{
$page = $this->Application->GetVar($event->Prefix.'_Page');
if (!$page)
{
$page = $this->Application->RecallVar($event->Prefix.'_Page');
}
if($page) $this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
else
{
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
// $page = $this->Application->GetLinkedVar($event->getPrefixSpecial(true).'_Page', $event->getPrefixSpecial().'_Page');
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
$object->SetPage($page);
}
+
+/* === RELATED TO IMPORT/EXPORT: BEGIN === */
+
+ /**
+ * Returns module folder
+ *
+ * @param kEvent $event
+ * @return string
+ */
+ function getModuleFolder(&$event)
+ {
+ return $this->Application->getUnitOption($event->Prefix, 'ModuleFolder');
+ }
+
+ /**
+ * Shows export dialog
+ *
+ * @param kEvent $event
+ */
+ function OnExport(&$event)
+ {
+ $selected_ids = $this->Application->GetVar('linklist');
+ $selected_cats_ids = $this->Application->GetVar('export_categories');
+
+ $this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
+ $this->Application->StoreVar($event->Prefix.'_export_cats_ids', $selected_cats_ids);
+
+ $event->redirect = $this->getModuleFolder($event).'/export';
+
+ $redirect_params = Array( 'm_opener' => 'd',
+ 'index_file' => 'index4.php',
+ $this->Prefix.'.export_event' => 'OnNew',
+ 'pass' => 'all,'.$this->Prefix.'.export');
+
+ $event->setRedirectParams($redirect_params);
+ }
+
+ /**
+ * 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') );
+ }
+
+ list($item_id, $field_values) = each($items_info);
+
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ $object->SetFieldsFromHash($field_values);
+ $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->StoreVar($event->getPrefixSpecial().'_options', serialize($field_values) );
+
+ if( $export_object->verifyOptions($event) )
+ {
+ $this->doExport($event);
+ }
+ else
+ {
+ $event->status = erFAIL;
+ $event->redirect = false;
+ }
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function doExport(&$event)
+ {
+ if ($event->Name == 'OnExportBegin')
+ {
+ $done_percent = 0;
+ }
+ else {
+ $export_options = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ $done_percent = round($export_options['start_from'] * 100 / $export_options['total_records'], 0);
+ }
+
+ $block_params = Array( 'name' => $this->getModuleFolder($event).'/'.$event->Special.'_progress',
+ 'percent_done' => $done_percent,
+ 'percent_left' => 100 - $done_percent);
+
+ $this->Application->InitParser();
+ $this->Application->setUnitOption($event->Prefix, 'AutoLoad', false);
+ echo $this->Application->ParseBlock($block_params);
+ flush();
+
+ $export_object =& $this->Application->recallObject('CatItemExportHelper');
+
+ $action_method = 'perform'.ucfirst($event->Special);
+ $field_values = $export_object->$action_method($event);
+
+ if ($field_values['start_from'] == $field_values['total_records'])
+ {
+ if ($event->Special == 'import') {
+ $this->Application->StoreVar('PermCache_UpdateRequired', 1);
+ $event->SetRedirectParam('index_file', 'category/category_maint.php');
+ }
+ else {
+ $event->redirect = $this->getModuleFolder($event).'/'.$event->Special.'_finish';
+ }
+ }
+ else {
+ $event->redirect = $this->getModuleFolder($event).'/'.$event->Special.'_progress';
+ $redirect_params = Array($event->getPrefixSpecial().'_event' => 'OnExportProgress', 'pass' => 'm,'.$event->getPrefixSpecial());
+ $event->setRedirectParams($redirect_params);
+ }
+ }
+
+ /**
+ * Next export steps
+ *
+ * @param kEvent $event
+ */
+ function OnExportProgress(&$event)
+ {
+ $this->doExport($event);
+ }
+
+ /**
+ * Sets correct available & export fields
+ *
+ * @param kEvent $event
+ */
+ function prepareExportColumns(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+
+ $available_columns = Array();
+
+ // 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
+ $fields = array_keys($object->Fields);
+ foreach ($fields as $field_name)
+ {
+ if (!$object->SkipField($field_name))
+ {
+ $available_columns[$field_name] = $field_name;
+ }
+ }
+
+ // custom fields
+ $fields = array_keys($object->CustomFields);
+ foreach ($fields as $field_name)
+ {
+ $available_columns['__CUSTOM__'.$field_name] = $field_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);
+
+ if ($event->Special == 'import')
+ {
+ $import_filenames = Array();
+
+ if ($folder_handle = opendir(EXPORT_PATH)) {
+ while (false !== ($file = readdir($folder_handle))) {
+ if ( 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);
+ }
+ }
+
+
+// ImportLocalFilename
+
+ 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;
+ }
+
+ /**
+ * Shows export dialog
+ *
+ * @param kEvent $event
+ */
+ function OnImport(&$event)
+ {
+
+ $event->redirect = $this->getModuleFolder($event).'/import';
+
+ $redirect_params = Array( 'm_opener' => 'd',
+ 'index_file' => 'index4.php',
+ $this->Prefix.'.import_event' => 'OnNew',
+ 'pass' => 'all,'.$this->Prefix.'.import');
+
+ $event->setRedirectParams($redirect_params);
+ }
+
+ /**
+ * Prepares item for import/export operations
+ *
+ * @param kEvent $event
+ */
+ function OnNew(&$event)
+ {
+ parent::OnNew($event);
+
+ if ($event->Special != 'import' && $event->Special != 'export') return ;
+ $this->setRequiredFields($event);
+ }
+
+ /**
+ * set required fields based on import or export params
+ *
+ * @param kEvent $event
+ */
+ function setRequiredFields(&$event)
+ {
+ $required_fields['common'] = Array('FieldsSeparatedBy', 'FieldsEnclosedBy', 'LineEndings', 'CategoryFormat');
+
+ $required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns');
+ $required_fields['import'] = Array('FieldTitles', 'ImportSource', 'CheckDuplicatesMethod'); // ImportFilename, ImportLocalFilename
+
+ $object =& $event->getObject();
+ 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);
+ }
+ }
+
+ /**
+ * Saves selected category as new import category
+ *
+ * @param kEvent $event
+ */
+ function OnSelectItems(&$event)
+ {
+ $items_info = $this->Application->GetVar('c');
+
+ if ($items_info)
+ {
+ $selected_categories = array_keys($items_info);
+ $cat_id = array_shift($selected_categories);
+
+ $sql = 'SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ResourceId = '.$cat_id;
+ $cat_id = $this->Conn->GetOne($sql);
+ }
+ else {
+ $cat_id = 0;
+ }
+
+ $this->Application->StoreVar('ImportCategory', $cat_id);
+ $this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 1); // not to loose import/export values on form refresh
+
+ $this->Application->SetVar($event->getPrefixSpecial().'_id', 0);
+ $this->Application->SetVar($event->getPrefixSpecial().'_event', 'OnExportBegin');
+
+ $passed = $this->Application->GetVar('passed');
+ $this->Application->SetVar('passed', $passed.','.$event->getPrefixSpecial());
+ $event->setEventParam('pass_events', true);
+
+ $this->finalizePopup($event, null, $this->getModuleFolder($event).'/'.$event->Special);
+
+ }
+
+ /**
+ * Saves Import/Export settings to session
+ *
+ * @param kEvent $event
+ */
+ function OnSaveSettings(&$event)
+ {
+ $event->redirect = false;
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if ($items_info) {
+ $this->Application->StoreVar($event->getPrefixSpecial().'_ItemsInfo', serialize($items_info));
+ }
+ }
+
+/* === RELATED TO IMPORT/EXPORT: END === */
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/cat_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.16
\ No newline at end of property
+1.17
\ No newline at end of property
Index: trunk/kernel/units/general/my_application.php
===================================================================
--- trunk/kernel/units/general/my_application.php (revision 3542)
+++ trunk/kernel/units/general/my_application.php (revision 3543)
@@ -1,52 +1,53 @@
<?php
class MyApplication extends kApplication {
function RegisterDefaultClasses()
{
parent::RegisterDefaultClasses();
$this->registerClass('Inp1Parser',MODULES_PATH.'/kernel/units/general/inp1_parser.php','Inp1Parser');
$this->registerClass('InpSession',MODULES_PATH.'/kernel/units/general/inp_ses_storage.php','Session');
$this->registerClass('InpSessionStorage',MODULES_PATH.'/kernel/units/general/inp_ses_storage.php','SessionStorage');
$this->registerClass('kCatDBItem',MODULES_PATH.'/kernel/units/general/cat_dbitem.php');
+ $this->registerClass('kCatDBItemExportHelper',MODULES_PATH.'/kernel/units/general/cat_dbitem_export.php', 'CatItemExportHelper');
$this->registerClass('kCatDBList',MODULES_PATH.'/kernel/units/general/cat_dblist.php');
$this->registerClass('kCatDBEventHandler',MODULES_PATH.'/kernel/units/general/cat_event_handler.php');
$this->registerClass('kCatDBTagProcessor',MODULES_PATH.'/kernel/units/general/cat_tag_processor.php');
$this->registerClass('InpDBEventHandler', MODULES_PATH.'/kernel/units/general/inp_db_event_handler.php', 'kDBEventHandler');
$this->registerClass('InpTempTablesHandler',MODULES_PATH.'/kernel/units/general/inp_temp_handler.php','kTempTablesHandler');
$this->registerClass('InpCustomFieldsHelper',MODULES_PATH.'/kernel/units/general/custom_fields.php','InpCustomFieldsHelper');
$this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper');
$this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper');
}
function getUserGroups($user_id)
{
switch($user_id)
{
case -1:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
break;
case -2:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
$user_groups .= ','.$this->ConfigValue('User_GuestGroup');
break;
default:
$sql = 'SELECT GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = '.$user_id;
$res = $this->DB->GetCol($sql);
$user_groups = Array( $this->ConfigValue('User_LoggedInGroup') );
if(is_array($res))
{
$user_groups = array_merge($user_groups, $res);
}
$user_groups = implode(',', $user_groups);
}
return $user_groups;
}
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/my_application.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.20
\ No newline at end of property
+1.21
\ No newline at end of property
Index: trunk/kernel/admin_templates/incs/script.js
===================================================================
--- trunk/kernel/admin_templates/incs/script.js (revision 3542)
+++ trunk/kernel/admin_templates/incs/script.js (revision 3543)
@@ -1,474 +1,724 @@
if( !( isset($init_made) && $init_made ) )
{
var Grids = new Array();
var Toolbars = new Array();
var $Menus = new Array();
var $ViewMenus = new Array();
var $form_prefix = 'kernel'; // results usage of kernel_form
if(!$fw_menus) var $fw_menus = new Array();
var $env = '';
var submitted = false;
var $init_made = true; // in case of double inclusion of script.js :)
}
function resort_grid(prefix_special,field,form_action)
{
set_hidden_field(prefix_special+'_Sort1', field);
submit_event(prefix_special,'OnSetSorting',null,form_action);
}
function direct_sort_grid($prefix_special,$field,$direction,$field_pos)
{
if(!isset($field_pos)) $field_pos = 1;
set_hidden_field($prefix_special+'_Sort'+$field_pos,$field);
set_hidden_field($prefix_special+'_Sort'+$field_pos+'_Dir',$direction);
set_hidden_field($prefix_special+'_SortPos',$field_pos);
submit_event($prefix_special,'OnSetSortingDirect');
}
function reset_sorting($prefix_special)
{
submit_event($prefix_special,'OnResetSorting');
}
function set_per_page($prefix_special,$per_page)
{
set_hidden_field($prefix_special+'_PerPage',$per_page);
submit_event($prefix_special,'OnSetPerPage');
}
function submit_event(prefix_special,event,t,form_action)
{
if (isset(event)) {
set_hidden_field('events['+prefix_special+']', event);
}
if(isset(t)) set_hidden_field('t', t);
if( isset(form_action) )
{
var old_env = '';
if ( !form_action.match(/\?/) ) {
document.getElementById($form_prefix+'_form').action.match(/.*(\?.*)/);
old_env = RegExp.$1;
}
document.getElementById($form_prefix+'_form').action = form_action+old_env;
}
submit_kernel_form();
}
function show_form_data()
{
var $kf = document.getElementById($form_prefix+'_form');
$ret = '';
for(var i in $kf.elements)
{
$elem = $kf.elements[i];
$ret += $elem.id + ' = ' + $elem.value + "\n";
}
alert($ret);
}
function submit_kernel_form()
{
if (submitted) {
return;
}
submitted = true;
var $form = document.getElementById($form_prefix+'_form');
if (typeof $form.onsubmit == "function") {
$form.onsubmit();
}
$form.submit();
$form.target = '';
$form.t.value = t;
window.setTimeout(function() {submitted = false}, 500);
}
function set_event(prefix_special, event)
{
var event_field=document.getElementById('events[' + prefix_special + ']');
if(isset(event_field))
{
event_field.value = event;
}
}
function isset(variable)
{
if(variable==null) return false;
return (typeof(variable)=='undefined')?false:true;
}
function print_pre(variable)
{
var s = "";
for (prop in variable) {
s += prop+" => "+variable[prop] + "";
}
alert(s);
}
function go_to_page(prefix_special, page)
{
set_hidden_field(prefix_special+'_Page', page);
submit_event(prefix_special);
}
function go_to_list(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnUpdateAndGoToTab',null);
}
function go_to_tab(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnPreSaveAndGoToTab',null);
}
function go_to_id(prefix_special, id)
{
set_hidden_field(prefix_special+'_GoId', id);
submit_event(prefix_special,'OnPreSaveAndGo')
}
// in-portal compatibility functions: begin
function getScriptURL($script_name)
{
var $asid = get_hidden_field('sid');
return base_url+$script_name+'?env='+( isset($env)&&$env?$env:$asid )+'&en=0';
}
function OpenEditor(extra_env,TargetForm,TargetField)
{
var $url = getScriptURL('admin/editor/editor_new.php');
$url = $url+'&TargetForm='+TargetForm+'&TargetField='+TargetField+'&destform=popup';
if(extra_env.length>0) $url += extra_env;
openwin($url,'html_edit',800,575);
}
function OpenUserSelector(extra_env,TargetForm,TargetField)
{
var $url = getScriptURL('admin/users/user_select.php');
$url += '&destform='+TargetForm+'&Selector=radio&destfield='+TargetField+'&IdField=Login';
if(extra_env.length>0) $url += extra_env;
openwin($url,'user_select',800,575);
return false;
}
function OpenCatSelector(extra_env)
{
var $url = getScriptURL('admin/cat_select.php');
if(extra_env.length>0) $url += extra_env;
openwin($url,'catselect',750,400);
}
function OpenItemSelector(extra_env,$TargetForm)
{
var $url = getScriptURL('admin/relation_select.php') + '&destform='+$TargetForm;
if(extra_env.length>0) $url += extra_env;
openwin($url,'groupselect',750,400);
}
function OpenUserEdit($user_id, $extra_env)
{
var $url = getScriptURL('admin/users/adduser.php') + '&direct_id=' + $user_id;
if( isset($extra_env) ) $url += $extra_env;
window.location.href = $url;
}
function OpenLinkEdit($link_id, $extra_env)
{
var $url = getScriptURL('in-link/admin/addlink.php') + '&item=' + $link_id;
if( isset($extra_env) ) $url += $extra_env;
window.location.href = $url;
}
function OpenHelp($help_link)
{
// $help_link.match('http://(.*).lv/in-commerce/admin(.*)');
// alert(RegExp.$2);
openwin($help_link,'HelpPopup',750,400);
}
// in-portal compatibility functions: end
function PreSaveAndOpenTranslator(prefix,field,t,multi_line,$width,$height)
{
if(!isset($window_name)) var $window_name = 'select_'+t.replace(/(\/|-)/g, '_');
if(!isset($width)) $width=750;
if(!isset($height)) $height=400;
if(!isset(multi_line)) multi_line=0;
openwin('',$window_name,$width,$height);
set_hidden_field('translator_wnd_name', $window_name);
set_hidden_field('translator_field', field);
set_hidden_field('translator_t', t);
set_hidden_field('translator_prefixes', prefix);
set_hidden_field('translator_multi_line', multi_line);
document.kernel_form.target=$window_name;
var split_prefix = prefix.split(',');
submit_event(split_prefix[0],'OnPreSaveAndOpenTranslator');
}
function PreSaveAndOpenTranslatorCV(prefix,field,t,cf_id,multi_line)
{
if(!isset($window_name)) var $window_name = 'select_'+t.replace(/(\/|-)/g, '_');
if(!isset(multi_line)) multi_line=0;
openwin('',$window_name,750,400);
set_hidden_field('translator_wnd_name', $window_name);
set_hidden_field('translator_field', field);
set_hidden_field('translator_t', t);
set_hidden_field('translator_prefixes', prefix);
set_hidden_field('translator_cf_id', cf_id);
set_hidden_field('translator_multi_line', multi_line);
document.kernel_form.target=$window_name;
var split_prefix = prefix.split(',');
submit_event(split_prefix[0],'OnPreSaveAndOpenTranslator');
}
function openTranslator(prefix,field,url,wnd)
{
set_hidden_field('trans_prefix', prefix);
set_hidden_field('trans_field', field);
set_hidden_field('events[trans]', 'OnLoad');
var $regex = new RegExp('(.*)\?env=' + document.getElementById('sid').value + '-(.*?):(.*)');
var $t = $regex.exec(url)[2];
document.kernel_form.target = wnd;
submit_event(prefix,'',$t,url);
}
function openSelector($prefix,$url,$window_name,$width,$height,$event)
{
var $regex = new RegExp('(.*)\?env=' + document.getElementById('sid').value + '-(.*?):(.*)');
var $t = $regex.exec($url)[2];
if(!isset($window_name)) var $window_name = 'select_'+$t.replace(/(\/|-)/g, '_');
if(!isset($width)) $width=750;
if(!isset($height)) $height=400;
if(!isset($event)) $event='';
set_hidden_field('m_opener','s');
openwin('',$window_name,$width,$height);
set_hidden_field('main_prefix', $prefix);
document.kernel_form.target=$window_name;
var old_action = document.kernel_form.action;
document.kernel_form.action = $url;
submit_event($prefix,$event,$t);
document.kernel_form.action = old_action;
}
function openwin($url,$name,$width,$height)
{
var $window_params = 'width='+$width+',height='+$height+',status=yes,resizable=yes,menubar=no,scrollbars=yes,toolbar=no';
return window.open($url,$name,$window_params);
}
function opener_action(new_action)
{
set_hidden_field('m_opener', new_action);
}
function std_precreate_item(prefix_special, edit_template)
{
opener_action('d');
set_hidden_field(prefix_special+'_mode', 't');
submit_event(prefix_special,'OnPreCreate', edit_template)
}
function std_new_item(prefix_special, edit_template)
{
opener_action('d');
submit_event(prefix_special,'OnNew', edit_template)
}
function std_edit_item(prefix_special, edit_template)
{
opener_action('d');
set_hidden_field(prefix_special+'_mode', 't');
submit_event(prefix_special,'OnEdit',edit_template)
}
function std_edit_temp_item(prefix_special, edit_template)
{
opener_action('d');
submit_event(prefix_special,'',edit_template)
}
function std_delete_items(prefix_special)
{
if (inpConfirm('Are you sure you want to delete selected items?'))
submit_event(prefix_special,'OnMassDelete')
}
// sets hidden field value
// if the field does not exist - creates it
function set_hidden_field($field_id, $value)
{
// alert('form: '+$form_prefix+'_form');
var $kf = document.getElementById($form_prefix+'_form');
var $field = $kf.elements[$field_id];
if($field)
{
$field.value = $value;
return true;
}
$field = document.createElement('INPUT');
$field.type = 'hidden';
$field.name = $field_id;
$field.id = $field_id;
$field.value = $value;
$kf.appendChild($field);
return false;
}
function get_hidden_field($field)
{
var $kf = document.getElementById($form_prefix+'_form');
return $kf.elements[$field] ? $kf.elements[$field].value : false;
}
function search($prefix_special, $grid_name)
{
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special,'OnSearch');
}
function search_reset($prefix_special, $grid_name)
{
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special,'OnSearchReset');
}
function search_keydown($event)
{
if(!$event && window.event) $event = window.event;
if($event.keyCode == 13)
{
var $prefix_special = this.getAttribute('PrefixSpecial');
var $grid = this.getAttribute('Grid');
search($prefix_special,$grid);
}
}
function getRealLeft(el)
{
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null)
{
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
function getRealTop(el)
{
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null)
{
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
function show_viewmenu($toolbar, $button_id)
{
var $img = $toolbar.GetButtonImage($button_id);
var $pos_x = getRealLeft($img) - ((document.all) ? 6 : -2);
var $pos_y = getRealTop($img) + 32;
var $prefix_special = '';
window.triedToWriteMenus = false;
if($ViewMenus.length == 1)
{
$prefix_special = $ViewMenus[$ViewMenus.length-1];
$fw_menus[$prefix_special+'_view_menu']();
$Menus[$prefix_special+'_view_menu'].writeMenus('MenuContainers['+$prefix_special+']');
window.FW_showMenu($Menus[$prefix_special+'_view_menu'], $pos_x, $pos_y);
}
else
{
// prepare menus
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$fw_menus[$prefix_special+'_view_menu']();
}
$Menus['mixed'] = new Menu('ViewMenu_mixed');
// merge menus into new one
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$Menus['mixed'].addMenuItem( $Menus[$prefix_special+'_view_menu'] );
}
$Menus['mixed'].writeMenus('MenuContainers[mixed]');
window.FW_showMenu($Menus['mixed'], $pos_x, $pos_y);
}
}
function set_window_title($title)
{
var $window = window;
if($window.parent) $window = $window.parent;
$window.document.title = (main_title.length ? main_title + ' - ' : '') + $title;
}
function set_filter($prefix_special, $filter_id, $filter_value)
{
set_hidden_field('filter_id',$filter_id);
set_hidden_field('filter_value',$filter_value);
submit_event($prefix_special,'OnSetFilter');
}
function filters_remove_all($prefix_special)
{
submit_event($prefix_special,'OnRemoveFilters');
}
function filters_apply_all($prefix_special)
{
submit_event($prefix_special,'OnApplyFilters');
}
function RemoveTranslationLink($string)
{
return $string.match(/<a href="(.*)">(.*)<\/a>/) ? RegExp.$2 : $string;
}
function redirect($url)
{
window.location.href = $url;
}
function update_checkbox_options($cb_mask, $hidden_id)
{
var $kf = document.getElementById($form_prefix+'_form');
var $tmp = '';
for (var i = 0; i < $kf.elements.length; i++)
{
if ( $kf.elements[i].id.match($cb_mask) )
{
-// alert('found:' + $kf.elements[i].id);
if ($kf.elements[i].checked) $tmp += '|'+$kf.elements[i].value;
}
}
if($tmp.length > 0) $tmp += '|';
document.getElementById($hidden_id).value = $tmp.replace(/,$/, '');
-// alert('field: '+$hidden_id+' = '+document.getElementById($hidden_id).value );
-}
\ No newline at end of file
+}
+
+// related to lists operations (moving)
+
+
+
+ function move_selected($from_list, $to_list)
+ {
+ if (typeof($from_list) != 'object') $from_list = document.getElementById($from_list);
+ if (typeof($to_list) != 'object') $to_list = document.getElementById($to_list);
+
+ if (has_selected_options($from_list))
+ {
+ var $from_array = select_to_array($from_list);
+ var $to_array = select_to_array($to_list);
+ var $new_from = Array();
+ var $cur = null;
+
+ for (var $i = 0; $i < $from_array.length; $i++)
+ {
+ $cur = $from_array[$i];
+ if ($cur[2]) // If selected - add to To array
+ {
+ $to_array[$to_array.length] = $cur;
+ }
+ else //Else - keep in new From
+ {
+ $new_from[$new_from.length] = $cur;
+ }
+ }
+
+ $from_list = array_to_select($new_from, $from_list);
+ $to_list = array_to_select($to_array, $to_list);
+ }
+ else
+ {
+ alert('Please select items to perform moving!');
+ }
+ }
+
+ function select_to_array($aSelect)
+ {
+ var $an_array = new Array();
+ var $cur = null;
+
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ $cur = $aSelect.options[$i];
+ $an_array[$an_array.length] = new Array($cur.text, $cur.value, $cur.selected);
+ }
+ return $an_array;
+ }
+
+ function array_to_select($anArray, $aSelect)
+ {
+ var $initial_length = $aSelect.length;
+ for (var $i = $initial_length - 1; $i >= 0; $i--)
+ {
+ $aSelect.options[$i] = null;
+ }
+
+ for (var $i = 0; $i < $anArray.length; $i++)
+ {
+ $cur = $anArray[$i];
+ $aSelect.options[$aSelect.length] = new Option($cur[0], $cur[1]);
+ }
+ }
+
+ function select_compare($a, $b)
+ {
+ if ($a[0] < $b[0])
+ return -1;
+ if ($a[0] > $b[0])
+ return 1;
+ return 0;
+ }
+
+ function select_to_string($aSelect)
+ {
+ var $result = '';
+ var $cur = null;
+
+ if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
+
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ $result += $aSelect.options[$i].value + '|';
+ }
+
+ return $result.length ? '|' + $result : '';
+ }
+
+ function selected_to_string($aSelect)
+ {
+ var $result = '';
+ var $cur = null;
+
+ if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
+
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ $cur = $aSelect.options[$i];
+ if ($cur.selected && $cur.value != '')
+ {
+ $result += $cur.value + '|';
+ }
+ }
+
+ return $result.length ? '|' + $result : '';
+ }
+
+ function string_to_selected($str, $aSelect)
+ {
+ var $cur = null;
+ for (var $i = 0; i < $aSelect.length; $i++)
+ {
+ $cur = $aSelect.options[$i];
+ $aSelect.options[$i].selected = $str.match(',' + $cur.value + ',') ? true : false;
+ }
+ }
+
+ function set_selected($selected_options, $aSelect)
+ {
+ if (!$selected_options.length) return false;
+
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ for (var $k = 0; $k < $selected_options.length; $k++)
+ {
+ if ($aSelect.options[$i].value == $selected_options[$k])
+ {
+ $aSelect.options[$i].selected = true;
+ }
+ }
+ }
+ }
+
+ function get_selected_count($theList)
+ {
+ var $count = 0;
+ var $cur = null;
+ for (var $i = 0; $i < $theList.length; $i++)
+ {
+ $cur = $theList.options[$i];
+ if ($cur.selected) $count++;
+ }
+ return $count;
+ }
+
+ function get_selected_index($aSelect, $typeIndex)
+ {
+ var $index = 0;
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ if ($aSelect.options[$i].selected)
+ {
+ $index = $i;
+ if ($typeIndex == 'firstSelected') break;
+ }
+ }
+ return $index;
+ }
+
+ function has_selected_options($theList)
+ {
+ var $ret = false;
+ var $cur = null;
+
+ for (var $i = 0; $i < $theList.length; $i++)
+ {
+ $cur = $theList.options[$i];
+ if ($cur.selected) $ret = true;
+ }
+ return $ret;
+ }
+
+ function select_sort($aSelect)
+ {
+ if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
+
+ var $to_array = select_to_array($aSelect);
+ $to_array.sort(select_compare);
+ array_to_select($to_array, $aSelect);
+ }
+
+ function move_options_up($aSelect, $interval)
+ {
+ if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
+
+ if (has_selected_options($aSelect))
+ {
+ var $selected_options = Array();
+ var $first_selected = get_selected_index($aSelect, 'firstSelected');
+
+ for (var $i = 0; $i < $aSelect.length; $i++)
+ {
+ if ($aSelect.options[$i].selected && ($first_selected > 0) )
+ {
+ swap_options($aSelect, $i, $i - $interval);
+ $selected_options[$selected_options.length] = $aSelect.options[$i - $interval].value;
+ }
+ else if ($first_selected == 0)
+ {
+ alert('Begin of list');
+ break;
+ }
+ }
+ set_selected($selected_options, $aSelect);
+ }
+ else
+ {
+ alert('Check items from moving');
+ }
+ }
+
+ function move_options_down($aSelect, $interval)
+ {
+ if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
+
+ if (has_selected_options($aSelect))
+ {
+ var $last_selected = get_selected_index($aSelect, 'lastSelected');
+ var $selected_options = Array();
+
+ for (var $i = $aSelect.length - 1; $i >= 0; $i--)
+ {
+ if ($aSelect.options[$i].selected && ($aSelect.length - ($last_selected + 1) > 0))
+ {
+ swap_options($aSelect, $i, $i + $interval);
+ $selected_options[$selected_options.length] = $aSelect.options[$i + $interval].value;
+ }
+ else if ($last_selected + 1 == $aSelect.length)
+ {
+ alert('End of list');
+ break;
+ }
+ }
+ set_selected($selected_options, $aSelect);
+ }
+ else
+ {
+ alert('Check items from moving');
+ }
+ }
+
+ function swap_options($aSelect, $src_num, $dst_num)
+ {
+ var $src_option = new Option($aSelect.options[$src_num].innerHTML, $aSelect.options[$src_num].value);
+ var $dst_option = new Option($aSelect.options[$dst_num].innerHTML, $aSelect.options[$dst_num].value);
+
+ $aSelect.options[$src_num] = $dst_option;
+ $aSelect.options[$dst_num] = $src_option;
+ }
\ No newline at end of file
Property changes on: trunk/kernel/admin_templates/incs/script.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8
\ No newline at end of property
+1.9
\ No newline at end of property
Index: trunk/kernel/admin_templates/incs/form_blocks.tpl
===================================================================
--- trunk/kernel/admin_templates/incs/form_blocks.tpl (revision 3542)
+++ trunk/kernel/admin_templates/incs/form_blocks.tpl (revision 3543)
@@ -1,277 +1,286 @@
<inp2:m_block name="section_header"/>
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr class="section_header_bg">
<td valign="top" class="admintitle" align="left" style="padding-top: 2px; padding-bottom: 2px;">
<img width="46" height="46" src="img/icons/<inp2:m_param name="icon"/>.gif" align="absmiddle" title="<inp2:m_phrase label="$title"/>">&nbsp;<inp2:m_phrase label="$title"/>
</td>
</tr>
</table>
<inp2:m_blockend/>
<inp2:m_block name="blue_bar"/>
<table border="0" cellpadding="2" cellspacing="0" class="tableborder_full" width="100%" height="30">
<tr>
<td class="header_left_bg" nowrap width="80%" valign="middle">
<span class="tablenav_link" id="blue_bar"><inp2:$prefix_SectionTitle title_preset="$title_preset" title="Invalid OR Missing title preset" cut_first="100"/></span>
</td>
<td align="right" class="tablenav" width="20%" valign="middle">
<script>
var $help_url='<inp2:m_t t="help" h_prefix="$prefix" h_icon="$icon" h_module="$module" h_title_preset="$title_preset" pass="all,m,h" escape="escape" front="1" />';
set_window_title( document.getElementById('blue_bar').innerHTML );
</script>
<a href="javascript: OpenHelp($help_url);">
<img src="img/blue_bar_help.gif" border="0">
</a>
</td>
</tr>
</table>
<inp2:m_blockend/>
<inp2:m_block name="subsection"/>
<tr class="subsectiontitle">
<td colspan="5"><inp2:m_phrase label="$title"/></td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_field_caption" subfield="" NamePrefix=""/>
<inp2:m_inc param="tab_index" by="1"/>
<td class="text">
<label for="<inp2:m_param name="NamePrefix"/><inp2:$prefix_InputName field="$field" subfield="$subfield"/>">
<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
<inp2:m_phrase label="$title"/></span><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:
</label>
</td>
<inp2:m_blockend/>
<inp2:m_block name="inp_label" is_last="" as_label="" currency="" is_last=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td valign="top"><span class="text"><inp2:$prefix_Field field="$field" as_label="$as_label" currency="$currency"/></span></td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_id_label"/>
<inp2:m_if prefix="$prefix" function="FieldEquals" field="$field" value="" inverse="inverse"/>
<inp2:m_ParseBlock name="inp_label" pass_params="true"/>
<inp2:m_endif/>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_box" subfield="" class="" is_last="" maxlength="" onblur="" size=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" subfield="$subfield" title="$title" is_last="$is_last"/>
<td>
<input type="text" name="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" id="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" value="<inp2:$prefix_Field field="$field" subfield="$subfield"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_upload" class="" is_last=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<input type="file" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" class="<inp2:m_param name="class"/>">
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_box_ml" class="" size="" maxlength=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<td class="text" valign="top">
<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
<inp2:m_phrase label="$title"/><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:</span><br>
<a href="javascript:PreSaveAndOpenTranslator('<inp2:m_param name="prefix"/>', '<inp2:m_param name="field"/>', 'popups/translator');" title="<inp2:m_Phrase label="la_Translate"/>"><img src="img/icons/icon24_translate.gif" style="cursor:hand" border="0"></a>
</td>
<td>
<input type="text" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" format="no_default"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_hidden" db=""/>
<input type="hidden" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="$db"/>">
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_date" class="" is_last=""/>
<inp2:m_if check="m_GetEquals" name="calendar_included" value="1" inverse="inverse">
<script type="text/javascript" src="incs/calendar.js"></script>
<inp2:m_set calendar_included="1"/>
</inp2:m_if>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<input type="text" name="<inp2:$prefix_InputName field="{$field}_date"/>" id="<inp2:$prefix_InputName field="{$field}_date"/>" value="<inp2:$prefix_Field field="{$field}_date"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_date" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>" datepickerIcon="<inp2:m_ProjectBase/>admin/images/ddarrow.gif">&nbsp;<span class="small">(<inp2:$prefix_Format field="{$field}_date" human="true"/>)</span>
<script type="text/javascript">
initCalendar("<inp2:$prefix_InputName field="{$field}_date"/>", "<inp2:$prefix_Format field="{$field}_date"/>");
</script>
<input type="hidden" name="<inp2:$prefix_InputName field="{$field}_time"/>" id="<inp2:$prefix_InputName field="{$field}_time"/>" value="">
</td>
<td class="error"><inp2:$prefix_Error field="{$field}_date"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_date_time" class="" is_last=""/>
<inp2:m_if check="m_GetEquals" name="calendar_included" value="1" inverse="inverse">
<script type="text/javascript" src="incs/calendar.js"></script>
<inp2:m_set calendar_included="1"/>
</inp2:m_if>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<!-- <input type="hidden" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="db"/>"> -->
<input type="text" name="<inp2:$prefix_InputName field="{$field}_date"/>" id="<inp2:$prefix_InputName field="{$field}_date"/>" value="<inp2:$prefix_Field field="{$field}_date"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_date" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>" datepickerIcon="<inp2:m_ProjectBase/>admin/images/ddarrow.gif">
<span class="small">(<inp2:$prefix_Format field="{$field}_date" human="true"/>)</span>
<script type="text/javascript">
initCalendar("<inp2:$prefix_InputName field="{$field}_date"/>", "<inp2:$prefix_Format field="{$field}_date"/>");
</script>
&nbsp;<input type="text" name="<inp2:$prefix_InputName field="{$field}_time"/>" id="<inp2:$prefix_InputName field="{$field}_time"/>" value="<inp2:$prefix_Field field="{$field}_time"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_time" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>"><span class="small"> (<inp2:$prefix_Format field="{$field}_time" human="true"/>)</span>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_textarea" class="" allow_html="allow_html"/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<td class="text" valign="top">
<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
<inp2:m_phrase label="$title"/><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:</span><br>
<inp2:m_if check="m_ParamEquals" name="allow_html" value="allow_html">
<a href="javascript:OpenEditor('&section=in-link:editlink_general','kernel_form','<inp2:$prefix_InputName field="$field"/>');"><img src="img/icons/icon24_link_editor.gif" style="cursor:hand" border="0"></a>
</inp2:m_if>
</td>
<td>
<textarea tabindex="<inp2:m_get param="tab_index"/>" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" cols="<inp2:m_param name="cols"/>" rows="<inp2:m_param name="rows"/>" class="<inp2:m_param name="class"/>"><inp2:$prefix_Field field="$field"/></textarea>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_textarea_ml" class=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<td class="text" valign="top">
<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
<inp2:m_phrase label="$title"/><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:</span><br>
<a href="javascript:OpenEditor('&section=in-link:editlink_general','kernel_form','<inp2:$prefix_InputName field="$field"/>');"><img src="img/icons/icon24_link_editor.gif" style="cursor:hand" border="0"></a>
<a href="javascript:PreSaveAndOpenTranslator('<inp2:m_param name="prefix"/>', '<inp2:m_param name="field"/>', 'popups/translator', 1);" title="<inp2:m_Phrase label="la_Translate"/>"><img src="img/icons/icon24_translate.gif" style="cursor:hand" border="0"></a>
</td>
<td>
<textarea tabindex="<inp2:m_get param="tab_index"/>" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" cols="<inp2:m_param name="cols"/>" rows="<inp2:m_param name="rows"/>" class="<inp2:m_param name="class"/>"><inp2:$prefix_Field field="$field"/></textarea>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_user" class="" is_last=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<input type="text" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" class="<inp2:m_param name="class"/>">
<a href="#" onclick="return OpenUserSelector('','kernel_form','<inp2:$prefix_InputName field="$field"/>');">
<img src="img/icons/icon24_link_user.gif" style="cursor:hand;" border="0">
</a>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_option_item"/>
<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_param name="option"/></option>
<inp2:m_blockend/>
<inp2:m_block name="inp_option_phrase"/>
<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_phrase label="$option"/></option>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_options" is_last="" has_empty="0" empty_value=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<select tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" onchange="<inp2:m_Param name="onchange"/>">
<inp2:m_if prefix="m" function="ParamEquals" name="use_phrases" value="1"/>
<inp2:$prefix_PredefinedOptions field="$field" block="inp_option_phrase" selected="selected" has_empty="$has_empty" empty_value="$empty_value"/>
<inp2:m_else/>
<inp2:$prefix_PredefinedOptions field="$field" block="inp_option_item" selected="selected" has_empty="$has_empty" empty_value="$empty_value"/>
<inp2:m_endif/>
</select>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_radio_item"/>
- <input type="radio" <inp2:m_param name="checked"/> name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>" onclick="<inp2:m_param name="onclick"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;
+ <input type="radio" <inp2:m_param name="checked"/> name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>" onclick="<inp2:m_param name="onclick"/>" onchange="<inp2:m_param name="onchange"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_param name="option"/></label>&nbsp;
<inp2:m_blockend/>
-<inp2:m_block name="inp_edit_radio" is_last="" pass_tabindex="" onclick=""/>
+<inp2:m_block name="inp_radio_phrase"/>
+ <input type="radio" <inp2:m_param name="checked"/> name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>" onclick="<inp2:m_param name="onclick"/>" onchange="<inp2:m_param name="onchange"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;
+<inp2:m_blockend/>
+
+<inp2:m_block name="inp_edit_radio" is_last="" pass_tabindex="" onclick="" onchange="" use_phrases="1"/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
- <inp2:$prefix_PredefinedOptions field="$field" tabindex="$pass_tabindex" block="inp_radio_item" selected="checked" onclick="$onclick" />
+ <inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
+ <inp2:$prefix_PredefinedOptions field="$field" tabindex="$pass_tabindex" block="inp_radio_phrase" selected="checked" onclick="$onclick" onchange="$onchange" />
+ <inp2:m_else />
+ <inp2:$prefix_PredefinedOptions field="$field" tabindex="$pass_tabindex" block="inp_radio_item" selected="checked" onclick="$onclick" onchange="$onchange" />
+ </inp2:m_if>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_checkbox" is_last="" field_class="" onchange=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last" NamePrefix="_cb_"/>
<td>
<input type="hidden" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="db"/>">
- <input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_<inp2:$prefix_InputName field="$field"/>" name="_cb_<inp2:$prefix_InputName field="$field"/>" <inp2:$prefix_Field field="$field" checked="checked" db="db"/> class="<inp2:m_param name="field_class"/>" onclick="update_checkbox(this, document.getElementById('<inp2:$prefix_InputName field="$field"/>'))" onchange="<inp2:m_param name="onchange" />">
+ <!--<input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_<inp2:$prefix_InputName field="$field"/>" name="_cb_<inp2:$prefix_InputName field="$field"/>" <inp2:$prefix_Field field="$field" checked="checked" db="db"/> class="<inp2:m_param name="field_class"/>" onclick="update_checkbox(this, document.getElementById('<inp2:$prefix_InputName field="$field"/>'));" onchange="<inp2:m_param name="onchange"/>">-->
+ <input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_<inp2:$prefix_InputName field="$field"/>" name="_cb_<inp2:$prefix_InputName field="$field"/>" <inp2:$prefix_Field field="$field" checked="checked" db="db"/> class="<inp2:m_param name="field_class"/>" onchange="update_checkbox(this, document.getElementById('<inp2:$prefix_InputName field="$field"/>'));<inp2:m_param name="onchange"/>">
<inp2:m_if check="{$prefix}_HasParam" name="hint_label"><inp2:m_phrase label="$hint_label"/></inp2:m_if>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_checkbox_item"/>
<input type="checkbox" <inp2:m_param name="checked"/> id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>" onclick="update_checkbox_options(/^<inp2:$prefix_InputName field="$field" as_preg="1"/>_([0-9A-Za-z-]+)/, '<inp2:$prefix_InputName field="$field"/>');"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_param name="option"/></label>&nbsp;
<inp2:m_blockend/>
<inp2:m_block name="inp_checkbox_phrase"/>
<input type="checkbox" <inp2:m_param name="checked"/> id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>" onclick="update_checkbox_options(/^<inp2:$prefix_InputName field="$field" as_preg="1"/>_([0-9A-Za-z-]+)/, '<inp2:$prefix_InputName field="$field"/>');"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_checkboxes" is_last=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title" is_last="$is_last"/>
<td>
<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" hint_label="$hint_label" block="inp_checkbox_phrase" selected="checked"/>
<inp2:m_else/>
<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" hint_label="$hint_label" block="inp_checkbox_item" selected="checked"/>
</inp2:m_if>
<inp2:m_ParseBlock prefix="$prefix" name="inp_edit_hidden" field="$field"/>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend/>
<inp2:m_block name="inp_edit_weight" subfield="" class="" is_last=""/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" subfield="$subfield" title="$title" is_last="$is_last"/>
<td>
<inp2:m_if check="lang.current_FieldEquals" field="UnitSystem" value="1">
<input type="text" name="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" id="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" value="<inp2:$prefix_Field field="$field" subfield="$subfield"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
<inp2:m_phrase label="la_kg" />
</inp2:m_if>
<inp2:m_if check="lang.current_FieldEquals" field="UnitSystem" value="2">
<input type="text" name="<inp2:$prefix_InputName field="{$field}_a" subfield="$subfield"/>" id="<inp2:$prefix_InputName field="{$field}_a" subfield="$subfield"/>" value="<inp2:$prefix_Field field="{$field}_a" subfield="$subfield"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
<inp2:m_phrase label="la_lbs" />
<input type="text" name="<inp2:$prefix_InputName field="{$field}_b" subfield="$subfield"/>" id="<inp2:$prefix_InputName field="{$field}_b" subfield="$subfield"/>" value="<inp2:$prefix_Field field="{$field}_b" subfield="$subfield"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
<inp2:m_phrase label="la_oz" />
</inp2:m_if>
</td>
<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
</tr>
<inp2:m_blockend />
\ No newline at end of file
Property changes on: trunk/kernel/admin_templates/incs/form_blocks.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.21
\ No newline at end of property
+1.22
\ No newline at end of property
Index: trunk/admin/browse.php
===================================================================
--- trunk/admin/browse.php (revision 3542)
+++ trunk/admin/browse.php (revision 3543)
@@ -1,446 +1,446 @@
<?php
##############################################################
##In-portal ##
##############################################################
## In-portal ##
## Intechnic Corporation ##
## All Rights Reserved, 1998-2002 ##
## ##
## No portion of this code may be copied, reproduced or ##
## otherwise redistributed without proper written ##
## consent of Intechnic Corporation. Violation will ##
## result in revocation of the license and support ##
## privileges along maximum prosecution allowed by law. ##
##############################################################
//KERNEL4 STARTUP - FOR ACTIONS HANDLING
function k4getmicrotime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$start = k4getmicrotime();
define('ADMIN', 1);
define('FULL_PATH', realpath(dirname(__FILE__).'/..'));
define('APPLICATION_CLASS', 'MyApplication');
include_once(FULL_PATH."/kernel/kernel4/startup.php");
$application =& kApplication::Instance();
$application->Init();
$application->ProcessRequest();
if($application->GetVar('Action') == 'm_paste') define('REDIRECT_REQUIRED',1); // this script can issue redirect header
//KERNEL4 END
define('REQUIRE_LAYER_HEADER', 1);
$b_topmargin = "0";
//$b_header_addon = "<DIV style='position:relative; z-Index: 1; background-color: #ffffff; padding-top:1px;'><div style='position:absolute; width:100%;top:0px;' align='right'><img src='images/logo_bg.gif'></div><img src='images/spacer.gif' width=1 height=15><br><div style='z-Index:1; position:relative'>";
require_once FULL_PATH.'/kernel/startup.php';
require_login();
$indexURL = $rootURL."index.php";
$homeURL = "javascript:AdminCatNav('".$_SERVER["PHP_SELF"]."?env=".BuildEnv()."');";
$m_var_list_update["cat"] = 0;
unset($m_var_list_update["cat"]);
$envar = "env=" . BuildEnv();
if($objCatList->CurrentCategoryID()>0)
{
$c = $objCatList->CurrentCat();
$upURL = "javascript:AdminCatNav('".$c->Admin_Parent_Link()."');";
}
else
$upURL = $_SERVER["PHP_SELF"]."?".$envar;
//admin only util
$pathtolocal = $pathtoroot."kernel/";
require_once ($pathtoroot.$admin."/include/elements.php");
//require_once ($pathtoroot."kernel/admin/include/navmenu.php");
require_once ($pathtolocal."admin/include/navmenu.php");
require_once($pathtoroot.$admin."/browse/toolbar.php");
$m = GetModuleArray();
foreach($m as $key=>$value)
{
$path = $pathtoroot.$value."admin/include/parser.php";
if(file_exists($path))
{
//echo "<!-- $path -->";
@include_once($path);
}
}
$application->InitParser();
$cat_templates = $objModules->ExecuteFunction('GetModuleInfo', 'catalog_template');
foreach ($cat_templates as $a_mod => $a_template) {
if (!$a_template) continue;
$a_var = $a_mod.'_TAB_HTML';
$$a_var = $application->ParseBlock(Array('name'=>$a_template), 0, true);
}
//$application->SetVar('t', 'in-commerce/products/products_catalog');
if( !defined('IS_INSTALL') ) define('IS_INSTALL', 0);
if( !IS_INSTALL ) require_login();
//Set Section
$section = 'in-portal:browse';
//Set Environment Variable
//echo $objCatList->ItemsOnClipboard()." Categories on the clipboard<br>\n";
//echo $objTopicList->ItemsOnClipboard()." Topics on the clipboard<br>\n";
//echo $objLinkList->ItemsOnClipboard()." Links on the clipboard<br>\n";
//echo $objArticleList->ItemsOnClipboard()." Articles on the clipboard<br>\n";
// save last category visited
$objSession->SetVariable('prev_category', $objSession->GetVariable('last_category') );
$objSession->SetVariable('last_category', $objCatList->CurrentCategoryID() );
/* // for testing
$last_cat = $objSession->GetVariable('last_category');
$prev_cat = $objSession->GetVariable('prev_category');
echo "Last CAT: [$last_cat]<br>";
echo "Prev CAT: [$prev_cat]<br>";
*/
$SearchType = $objSession->GetVariable("SearchType");
if(!strlen($SearchType))
$SearchType = "all";
$SearchLabel = "la_SearchLabel";
if( GetVar('SearchWord') !== false ) $objSession->SetVariable('admin_seach_words', GetVar('SearchWord') );
$SearchWord = $objSession->GetVariable('admin_seach_words');
// where should all edit popups submit changes
$objSession->SetVariable("ReturnScript", basename($_SERVER['PHP_SELF']) );
$charset = GetRegionalOption('Charset');
$m_tag_processor =& $application->recallObject('m_TagProcessor');
$base_href = $m_tag_processor->Base_Ref();
/* page header */
print <<<END
<html>
<head>
<title>In-portal</title>
$base_href
<meta http-equiv="content-type" content="text/html;charset=$charset">
<meta http-equiv="Pragma" content="no-cache">
<script language="JavaScript">
imagesPath='$imagesURL'+'/';
</script>
END;
require_once($pathtoroot.$admin."/include/mainscript.php");
print <<<END
<script type="text/javascript">
if (window.opener != null) {
theMainScript.CloseAndRefreshParent();
}
</script>
END;
print <<<END
<script src="$browseURL/toolbar.js"></script>
<script src="$browseURL/checkboxes_new.js"></script>
<script language="JavaScript1.2" src="$browseURL/fw_menu.js"></script>
<link rel="stylesheet" type="text/css" href="$browseURL/checkboxes.css">
<link rel="stylesheet" type="text/css" href="$cssURL/style.css">
<link rel="stylesheet" type="text/css" href="$browseURL/toolbar.css">
END;
load_module_styles();
if( !isset($list) ) $list = '';
if(($SearchType=="categories" || $SearchType="all") && strlen($list))
{
int_SectionHeader(NULL,NULL,NULL,admin_language("la_Title_SearchResults"));
}
else
int_SectionHeader();
$filter = false; // always initialize variables before use
if($objSession->GetVariable("SearchWord") != '') {
$filter = true;
}
else {
$bit_combo = $objModules->ExecuteFunction('GetModuleInfo', 'all_bitmask');
$bit_combo = $objModules->MergeReturn($bit_combo);
foreach($bit_combo['VarName'] as $mod_name => $VarName)
{
//echo "VarName: [$VarName] = [".$objConfig->Get($VarName)."], ALL = [".$bit_combo['Bits'][$mod_name]."]<br>";
if( $objConfig->Get($VarName) )
if( $objConfig->Get($VarName) != $bit_combo['Bits'][$mod_name] )
{
$filter = true;
break;
}
}
}
?>
</div>
<!-- alex mark -->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
- <tbody>
- <tr>
- <td>
- <div name="toolBar" id="mainToolBar">
- <tb:button action="upcat" title="<?php echo admin_language("la_ToolTip_Up"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="homecat" title="<?php echo admin_language("la_ToolTip_Home"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="new_cat" title="<?php echo admin_language("la_ToolTip_New_Category"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="editcat" title="<?php echo admin_language("la_ToolTip_Edit_Current_Category"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
-
-<?php
- foreach($NewButtons as $btn)
- {
- print "<tb:button action=\"".$btn["Action"]."\" title=\"".$btn["Alt"]."\" ImagePath=\"".$btn["ImagePath"]."\" ";
- if(strlen($btn["Tab"])>0)
- print "tab=\"".$btn["Tab"]."\"";
- print ">\n";
- }
-?>
- <tb:button action="edit" title="<?php echo admin_language("la_ToolTip_Edit"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="delete" title="<?php echo admin_language("la_ToolTip_Delete"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="approve" title="<?php echo admin_language("la_ToolTip_Approve"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="decline" title="<?php echo admin_language("la_ToolTip_Decline"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
-<?php
- /*<tb:button action="import" title="<?php echo admin_language("la_ToolTip_Import"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="export" title="<?php echo admin_language("la_ToolTip_Export"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">*/
-?>
+ <tbody>
+ <tr>
+ <td>
+ <div name="toolBar" id="mainToolBar">
+ <tb:button action="upcat" title="<?php echo admin_language("la_ToolTip_Up"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="homecat" title="<?php echo admin_language("la_ToolTip_Home"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="new_cat" title="<?php echo admin_language("la_ToolTip_New_Category"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="editcat" title="<?php echo admin_language("la_ToolTip_Edit_Current_Category"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+
+ <?php
+ foreach($NewButtons as $btn)
+ {
+ print '<tb:button action="'.$btn['Action'].'" title="'.$btn['Alt'].'" ImagePath="'.$btn['ImagePath'].'" ';
+ if (getArrayValue($btn, 'Tab')) print 'tab="'.$btn['Tab'].'"';
+ print ">\n";
+ }
+ ?>
+
+ <tb:button action="edit" title="<?php echo admin_language("la_ToolTip_Edit"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="delete" title="<?php echo admin_language("la_ToolTip_Delete"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="approve" title="<?php echo admin_language("la_ToolTip_Approve"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="decline" title="<?php echo admin_language("la_ToolTip_Decline"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+
+ <tb:button action="import" title="<?php echo admin_language("la_ToolTip_Import"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="export" title="<?php echo admin_language("la_ToolTip_Export"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="rebuild_cache" title="<?php echo admin_language("la_ToolTip_RebuildCategoryCache"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="rebuild_cache" title="<?php echo admin_language("la_ToolTip_RebuildCategoryCache"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="cut" title="<?php echo admin_language("la_ToolTip_Cut"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="copy" title="<?php echo admin_language("la_ToolTip_Copy"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="paste" title="<?php echo admin_language("la_ToolTip_Paste"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="move_up" title="<?php echo admin_language("la_ToolTip_Move_Up"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="move_down" title="<?php echo admin_language("la_ToolTip_Move_Down"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="print" title="<?php echo admin_language("la_ToolTip_Print"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- <tb:button action="view" title="<?php echo admin_language("la_ToolTip_View"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
- </div>
- </td>
- </tr>
- </tbody>
+ <tb:button action="cut" title="<?php echo admin_language("la_ToolTip_Cut"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="copy" title="<?php echo admin_language("la_ToolTip_Copy"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="paste" title="<?php echo admin_language("la_ToolTip_Paste"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="move_up" title="<?php echo admin_language("la_ToolTip_Move_Up"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="move_down" title="<?php echo admin_language("la_ToolTip_Move_Down"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:separator ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="print" title="<?php echo admin_language("la_ToolTip_Print"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ <tb:button action="view" title="<?php echo admin_language("la_ToolTip_View"); ?>" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
+ </div>
+ </td>
+ </tr>
+ </tbody>
</table>
+
<table cellspacing="0" cellpadding="0" width="100%" bgcolor="#e0e0da" border="0" class="tableborder_full_a">
<tbody>
<tr>
<td><img height="15" src="<?php echo $imagesURL; ?>/arrow.gif" width="15" align="middle" border="0">
<span class="navbar"><?php $attribs["admin"]=1; print m_navbar($attribs); ?></span>
</td>
<td align="right">
<FORM METHOD="POST" ACTION="<?php echo $_SERVER["PHP_SELF"]."?".$envar; ?>" NAME="admin_search" ID="admin_search"><INPUT ID="SearchScope" NAME="SearchScope" type="hidden" VALUE="<?php echo $objSession->GetVariable("SearchScope"); ?>"><INPUT ID="SearchType" NAME="SearchType" TYPE="hidden" VALUE="<?php echo $objSession->GetVariable("SearchType"); ?>"><INPUT ID="NewSearch" NAME="NewSearch" TYPE="hidden" VALUE="0"><INPUT TYPE="HIDDEN" NAME="Action" value="m_Exec_Search">
<table cellspacing="0" cellpadding="0"><tr>
<td><?php echo admin_language($SearchLabel); ?>&nbsp;</td>
<td><input ID="SearchWord" type="text" value="<?php echo inp_htmlize($SearchWord,1); ?>" name="SearchWord" size="10" style="border-width: 1; border-style: solid; border-color: 999999"></td>
<td><img id="imgSearch" action="search_b" src="<?php echo $imagesURL."/toolbar/";?>/icon16_search.gif" title="<?php echo admin_language("la_ToolTip_Search"); ?>" align="absMiddle" onclick="this.action = this.getAttribute('action'); actionHandler(this);" src="<?php echo $imagesURL."/toolbar/";?>/arrow16.gif" onmouseover="this.src='<?php echo $imagesURL."/toolbar/";?>/icon16_search_f2.gif'" onmouseout="this.src='<?php echo $imagesURL."/toolbar/";?>/icon16_search.gif'" style="cursor:hand" width="22" width="22"><!--<img action="search_a" title="<?php echo admin_language("la_ToolTip_Search"); ?>" align="absMiddle" onclick="this.action = this.getAttribute('action'); actionHandler(this);" src="<?php echo $imagesURL."/toolbar/";?>/arrow16.gif" onmouseover="this.src='<?php echo $imagesURL."/toolbar/";?>/arrow16_f2.gif'" onmouseout="this.src='<?php echo $imagesURL."/toolbar/";?>/arrow16.gif'" style="cursor:hand">-->
<img action="search_c" src="<?php echo $imagesURL."/toolbar/";?>/icon16_search_reset.gif" title="<?php echo admin_language("la_ToolTip_Search"); ?>" align="absMiddle" onclick="document.all.SearchWord.value = ''; this.action = this.getAttribute('action'); actionHandler(this);" onmouseover="this.src='<?php echo $imagesURL."/toolbar/";?>/icon16_search_reset_f2.gif'" onmouseout="this.src='<?php echo $imagesURL."/toolbar/";?>/icon16_search_reset.gif'" style="cursor:hand" width="22" width="22">&nbsp;
</td>
</tr></table>
</FORM>
<!--tb:button action="search_b" title="<?php echo admin_language("la_ToolTip_Search"); ?>" align="right" ImagePath="<?php echo $imagesURL."/toolbar/";?>">
<tb:button action="search_a" title="<?php echo admin_language("la_ToolTip_Search"); ?>" align="right" ImagePath="<?php echo $imagesURL."/toolbar/";?>"-->
</td>
</tr>
</tbody>
</table>
<?php if ($filter) { ?>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="toolbar">
<tr>
<td valign="top">
<?php int_hint_red(admin_language("la_Warning_Filter")); ?>
</td>
</tr>
</table>
<?php } ?>
<br>
<!-- CATEGORY DIVIDER -->
<?php
$OrderBy = $objCatList->QueryOrderByClause(TRUE,TRUE,TRUE);
$objCatList->Clear();
$IsSearch = FALSE;
if($SearchType == 'categories' || $SearchType == 'all')
{
$list = $objSession->GetVariable("SearchWord");
$SearchQuery = $objCatList->AdminSearchWhereClause($list);
if(strlen($SearchQuery))
{
$SearchQuery = " (".$SearchQuery.") ";
if( strlen($CatScopeClause) ) {
$SearchQuery .= " AND ParentId = ".$objCatList->CurrentCategoryID();//" AND ".$CatScopeClause;
}
$objCatList->LoadCategories($SearchQuery.$CategoryFilter,$OrderBy);
$IsSearch = TRUE;
}
else
$objCatList->LoadCategories("ParentId=".$objCatList->CurrentCategoryID()." ".$CategoryFilter,$OrderBy);
}
else
$objCatList->LoadCategories("ParentId=".$objCatList->CurrentCategoryID()." ".$CategoryFilter, $OrderBy);
$TotalItemCount += $objCatList->QueryItemCount;
?>
<?php
$e = $Errors->GetAdminUserErrors();
if(count($e)>0)
{
echo "<table cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" border=\"0\">";
for($ex = 0; $ex<count($e);$ex++)
{
echo "<tr><td width=\100%\" class=\"error\">".prompt_language($e[$ex])."</td></tr>";
}
echo "</TABLE><br>";
}
?>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td width="138" height="20" nowrap="nowrap" class="active_tab" onclick="toggleCategoriesB(this)" id="cats_tab">
<table cellspacing="0" cellpadding="0" width="100%" border="0">
<tr>
<td id="l_cat" background="<?php echo $imagesURL; ?>/itemtabs/tab_active_l.gif" class="left_tab">
<img src="<?php echo $imagesURL; ?>/itemtabs/divider_up.gif" width="20" height="20" border="0" align="absmiddle">
</td>
<td id="m_cat" nowrap background="<?php echo $imagesURL; ?>/itemtabs/tab_active.gif" class="tab_class">
<?php echo admin_language("la_ItemTab_Categories"); ?>:&nbsp;
</td>
<td id="m1_cat" align="right" valign="top" background="<?php echo $imagesURL; ?>/itemtabs/tab_active.gif" class="tab_class">
<span class="cats_stats">(<?php echo $objCatList->QueryItemCount; ?>)</span>&nbsp;
</td>
<td id="r_cat" background="<?php echo $imagesURL; ?>/itemtabs/tab_active_r.gif" class="right_tab">
<img src="<?php echo $imagesURL; ?>/spacer.gif" width="21" height="20">
</td>
</tr>
</table>
</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<div class="divider" style="" id="categoriesDevider"><img width="1" height="1" src="<?php echo $imagesURL; ?>/spacer.gif"></div>
</DIV>
</div>
<DIV style="background-color: #ffffff; position: relative; padding-top: 1px; top: -1px; z-Index:0" id="firstContainer">
<DIV style="background-color: #ffffff; position: relative; padding-top: 1px; top: -1px; z-Index:2" id="secondContainer">
<!-- CATEGORY OUTPUT START -->
<div id="categories" tabtitle="Categories">
<form id="categories_form" name="categories_form" action="" method="post">
<input type="hidden" name="Action">
<?php
if($IsSearch)
{
$template = "cat_search_element.tpl";
}
else {
$template = "cat_element.tpl";
}
print adListSubCats($objCatList->CurrentCategoryID(),$template);
?>
</form>
</div>
<BR>
<!-- CATEGORY OUTPUT END -->
<?php
print $ItemTabs->TabRow();
if(count($ItemTabs->Tabs))
{
?>
<div class="divider" id="tabsDevider"><img width=1 height=1 src="images/spacer.gif"></div>
<?php
}
?>
</DIV>
<?php
unset($m);
//echo $application->ParseBlock(Array('name'=>'kernel_form_start'), 0, true);
$m = GetModuleArray("admin");
foreach($m as $key=>$value)
{
$path = $pathtoroot.$value."admin/browse.php";
if(file_exists($path))
{
//echo "\n<!-- $path -->\n";
include_once($path);
}
}
//echo $application->ParseBlock(Array('name'=>'kernel_form_end'), 0, true);
$admin = $objConfig->Get("AdminDirectory");
if(!strlen($admin)) $admin = "admin";
?>
<form method="post" action="<?php echo $rootURL.$admin; ?>/browse.php?env=<?php echo BuildEnv(); ?>" name="viewmenu">
<input type="hidden" name="fieldname" value="">
<input type="hidden" name="varvalue" value="">
<input type="hidden" name="varvalue2" value="">
<input type="hidden" name="Action" value="">
</form>
</DIV>
<!-- END CODE-->
<script language="JavaScript">
InitPage();
cats_on = theMainScript.GetCookie('cats_tab_on');
if (cats_on == 0) {
toggleCategoriesB(document.getElementById('cats_tab'), true);
}
tabs_on = theMainScript.GetCookie('tabs_on');
if (tabs_on == '1' || tabs_on == null) {
if(default_tab.length == 0 || default_tab == 'categories' )
{
cookie_start = theMainScript.GetCookie('active_tab');
if (cookie_start != null) start_tab = cookie_start;
if(start_tab!=null) {
//alert('ok');
toggleTabB(start_tab, true);
}
}
else
{
//alert('ok');
toggleTabB(default_tab,true);
}
}
d = document.getElementById('SearchWord');
if(d)
{
d.onkeyup = function(event) {
if(window.event.keyCode==13)
{
var el = document.getElementById('imgSearch');
el.onclick();
}
}
}
</script>
<?php
$objSession->SetVariable("HasChanges", 0);
int_footer();
?>
\ No newline at end of file
Property changes on: trunk/admin/browse.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.28
\ No newline at end of property
+1.29
\ No newline at end of property
Index: trunk/admin/include/mainscript.js
===================================================================
--- trunk/admin/include/mainscript.js (revision 3542)
+++ trunk/admin/include/mainscript.js (revision 3543)
@@ -1,160 +1,185 @@
<?php
global $imagesURL;
$SiteName = addslashes( strip_tags( $GLOBALS['objConfig']->Get('Site_Name') ) );
$env2 = BuildEnv();
print <<<END
<script language="Javascript">
var main_title = '$SiteName';
var CurrentTab= new String();
function getRealLeft(el) {
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null) {
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
function getRealTop(el) {
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null) {
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
function swap(imgid, src, img_prefix){
var ob = document.getElementById(imgid);
if(img_prefix == null) img_prefix = 'admin/images';
ob.src = '$rootURL' + img_prefix + '/' + src;
}
function flip(val){
if (val == 0)
return 1;
else
return 0;
}
function config_val(field, val2){
//alert('Setting ' + field + ' to ' + val2);
document.viewmenu.Action.value = "m_SetVariable";
document.viewmenu.fieldname.value = field;
document.viewmenu.varvalue.value = val2;
document.viewmenu.submit();
}
function HideAllTabs()
{
p = document.getElementById('DIVMARKER');
p.innerHTML="";
}
function tabSetLeftImage(tabname,isSelected)
{
img = document.getElementById('tabimgLeft_'+tabname);
if(img)
{
if(isSelected==1)
{
img.src='$imagesURL/divider_left_sel.gif';
}
else
{
img.src='$imagesURL/divider_dn.gif';
}
}
}
function tabSetRightImage(tabname,isSelected)
{
img = document.getElementById('tabimgRight_'+tabname);
if(img)
{
if(isSelected==1)
{
img.src='$imagesURL/divider_sel_right.gif';
}
else
{
img.src='$imagesURL/divider_right.gif';
}
}
}
function tabSetCenter(tabname,isSelected)
{
tab = document.getElementById('tabCenter_'+tabname);
if(isSelected==1)
{
tab.style.backgroundColor='#E9D4CE';
}
else
{
tab.style.backgroundColor='#E0E0DA';
}
}
function toggleTab(el)
{
if(CurrentTab.length)
{
tabSetLeftImage(CurrentTab,0);
tabSetRightImage(CurrentTab,0);
tabSetCenter(CurrentTab,0);
}
tabSetLeftImage(el,1); //line 99
tabSetRightImage(el,1);
tabSetCenter(el,1);
divname = 'divtab'+el;
d = document.getElementById(divname);
p = document.getElementById('DIVMARKER');
if(d)
{
p.innerHTML=d.innerHTML;
}
document.cookie='itemtab='+el;
CurrentTab=el;
}
function setCurrentTab()
{
var allcookies = document.cookie;
var pos= allcookies.indexOf('itemtab=');
if(pos !=-1)
{
var start= pos+8;
var end=allcookies.indexOf(';',start);
if(end==-1)
end=allcookies.length;
var value=allcookies.substring(start,end);
toggleTab(value);
}
}
function set_window_title(\$title)
{
var \$window = window;
if(\$window.parent) \$window = \$window.parent;
\$window.document.title = (main_title.length ? main_title + ' - ' : '') + \$title;
}
+
+// sets hidden field value
+// if the field does not exist - creates it
+function set_hidden_field(\$field_id, \$value)
+{
+// alert('form: '+\$form_prefix+'_form');
+
+ var \$kf = document.getElementById(\$form_prefix+'_form');
+ var \$field = \$kf.elements[\$field_id];
+ if(\$field)
+ {
+ \$field.value = \$value;
+ return true;
+ }
+
+ \$field = document.createElement('INPUT');
+ \$field.type = 'hidden';
+ \$field.name = \$field_id;
+ \$field.id = \$field_id;
+ \$field.value = \$value;
+
+ \$kf.appendChild(\$field);
+ return false;
+}
+
var env = "$env2";
</script>
END;
?>
\ No newline at end of file
Property changes on: trunk/admin/include/mainscript.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4
\ No newline at end of property
+1.5
\ No newline at end of property
Index: trunk/core/kernel/event_manager.php
===================================================================
--- trunk/core/kernel/event_manager.php (revision 3542)
+++ trunk/core/kernel/event_manager.php (revision 3543)
@@ -1,366 +1,366 @@
<?php
define('hBEFORE', 1);
define('hAFTER', 2);
define('reBEFORE', 1);
define('reAFTER', 2);
class kEventManager extends kBase {
/**
* Connection to database
*
* @var kDBConnection
* @access public
*/
var $Conn;
/**
* Cache of QueryString parameters
* from config, that are represented
* in enviroment variable
*
* @var Array
*/
- var $queryMaps=Array();
+ var $queryMaps = Array();
/**
* Build events registred for
* pseudo classes. key - pseudo class
* value - event name
*
* @var Array
* @access private
*/
var $buildEvents=Array();
/**
* Events, that should be run before parser initialization
*
* @var Array
*/
var $beforeRegularEvents = Array();
/**
* Events, that should be run after parser initialization
*
* @var Array
*/
var $afterRegularEvents = Array();
/**
* Holds before hooks
* key - prefix.event (to link to)
* value - hooked event info
*
* @var Array
* @access private
*/
var $beforeHooks=Array();
/**
* Holds after hooks
* key - prefix.event (to link to)
* value - hooked event info
*
* @var Array
* @access private
*/
var $afterHooks = Array();
function kEventManager()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Set's new enviroment parameter mappings
* between their names as application vars
*
* @param Array $new_query_maps
* @access public
*/
function setQueryMaps($new_query_maps)
{
- $this->queryMaps=$new_query_maps;
+ $this->queryMaps = $new_query_maps;
}
-
+
/**
* Registers new regular event
*
* @param string $short_name name to be used to store last maintenace run info
* @param string $event_name
* @param int $run_interval run interval in seconds
* @param int $type before or after regular event
*/
function registerRegularEvent($short_name, $event_name, $run_interval, $type = reBEFORE)
{
if($type == reBEFORE)
{
$this->beforeRegularEvents[$short_name] = Array('EventName' => $event_name, 'RunInterval' => $run_interval);
}
else
{
$this->afterRegularEvents[$short_name] = Array('EventName' => $event_name, 'RunInterval' => $run_interval);
}
}
function registerBuildEvent($pseudo_class,$build_event_name)
{
$this->buildEvents[$pseudo_class]=$build_event_name;
}
/**
* Returns build event by pseudo class
* name if any defined in config
*
* @param string $pseudo_class
* @return kEvent
* @access public
*/
function &getBuildEvent($pseudo_class)
{
$false = false;
if( !isset($this->buildEvents[$pseudo_class]) ) return $false;
$event = new kEvent();
$event->Name=$this->buildEvents[$pseudo_class];
$event->MasterEvent=null;
return $event;
}
/**
* Allows to process any type of event
*
* @param kEvent $event
* @access public
*/
function HandleEvent(&$event)
{
if( !$this->Application->prefixRegistred($event->Prefix) )
{
trigger_error('Prefix <b>'.$event->Prefix.'</b> not registred (requested event <b>'.$event->Name.'</b>)', E_USER_NOTICE);
return false;
}
if (!$event->SkipBeforeHooks) {
$this->processHooks($event, hBEFORE);
if ($event->status == erFATAL) return true;
}
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
$event_handler->processEvent($event);
if ($event->status == erFATAL) return true;
if (!$event->SkipAfterHooks) {
$this->processHooks($event, hAFTER);
}
return true;
}
function ProcessRequest()
{
$this->processOpener();
// 1. get events from $_POST
$events=$this->Application->GetVar('events');
if($events===false) $events=Array();
// 2. if nothing there, then try to find them in $_GET
if($this->queryMaps && !$events)
{
// if we got $_GET type submit (links, not javascript)
foreach($this->queryMaps as $prefix_special => $query_map)
{
$query_map=array_flip($query_map);
if(isset($query_map['event']))
{
$events[$prefix_special]=$this->Application->GetVar($prefix_special.'_event');
}
}
$actions = $this->Application->GetVar('do');
if ($actions) {
list($prefix, $event_name) = explode('_', $actions);
$events[$prefix] = $event_name;
}
}
$passed = explode(',', $this->Application->GetVar('passed'));
foreach($events as $prefix_special => $event_name)
{
if(!$event_name) continue;
if( is_array($event_name) )
{
$event_name = key($event_name);
$events[$prefix_special] = $event_name;
$this->Application->SetVar($prefix_special.'_event', $event_name);
}
$event = new kEvent();
$event->Name=$event_name;
$event->Prefix_Special=$prefix_special;
$prefix_special=explode('.',$prefix_special);
$event->Prefix=$prefix_special[0];
array_push($passed, $prefix_special[0]);
$event->Special=isset($prefix_special[1])?$prefix_special[1]:'';
$event->redirect_params = Array('opener'=>'s', 'pass'=>'all');
$event->redirect = true;
$this->HandleEvent($event);
if($event->status==erSUCCESS && ($event->redirect === true || strlen($event->redirect) > 0) )
{
$this->Application->Redirect($event->redirect, $event->redirect_params, null, $event->redirect_script);
}
}
$this->Application->SetVar('events', $events);
$this->Application->SetVar('passed', implode(',', $passed));
}
function processOpener()
{
$opener_action=$this->Application->GetVar('m_opener');
$opener_stack=$this->Application->RecallVar('opener_stack');
$opener_stack=$opener_stack?unserialize($opener_stack):Array();
switch($opener_action)
{
case 'r': // "reset" opener stack
$opener_stack=Array();
break;
case 'd': // "down/push" new template to opener stack, deeplevel++
if ($this->Application->GetVar('front')) {
array_push($opener_stack, '../'.$this->Application->RecallVar('last_template') );
}
else {
array_push($opener_stack, $this->Application->RecallVar('last_template') );
}
break;
case 'u': // "up/pop" last template from opener stack, deeplevel--
array_pop($opener_stack);
break;
default: // "s/0," stay on same deep level
break;
}
$this->Application->SetVar('m_opener','s');
$this->Application->StoreVar('opener_stack',serialize($opener_stack));
}
function registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional)
{
if( !$this->Application->getUnitOptions($hookto_prefix) )
{
if($this->Application->isDebugMode())
{
trigger_error('Prefix <b>'.$hookto_prefix.'</b> doesn\'t exist when trying to hook from <b>'.$do_prefix.':'.$do_event.'</b>', E_USER_WARNING);
}
return;
}
$hookto_prefix_special = rtrim($hookto_prefix.'.'.$hookto_special, '.');
if ($mode == hBEFORE) {
$this->beforeHooks[strtolower($hookto_prefix_special.'.'.$hookto_event)][] = Array(
'DoPrefix' => $do_prefix,
'DoSpecial' => $do_special,
'DoEvent' => $do_event,
'Conditional' => $conditional,
);
}
elseif ($mode == hAFTER) {
$this->afterHooks[strtolower($hookto_prefix_special.'.'.$hookto_event)][] = Array(
'DoPrefix' => $do_prefix,
'DoSpecial' => $do_special,
'DoEvent' => $do_event,
'Conditional' => $conditional,
);
}
}
/**
* Enter description here...
*
* @param kEvent $event
* @param int $mode hBEFORE or hAFTER
*/
function processHooks(&$event, $mode)
{
if ($mode == hBEFORE) {
$mode_hooks =& $this->beforeHooks;
}
else {
$mode_hooks =& $this->afterHooks;
}
if ( $hooks = getArrayValue($mode_hooks, strtolower($event->Prefix_Special.'.'.$event->Name)) ) {
foreach($hooks as $hook)
{
$prefix_special = rtrim($hook['DoPrefix'].'_'.$hook['DoSpecial'],'_');
if( $hook['Conditional'] && !$this->Application->GetVar($prefix_special) ) continue;
$hook_event = new kEvent( Array('name'=>$hook['DoEvent'],'prefix'=>$hook['DoPrefix'],'special'=>$hook['DoSpecial']) );
$hook_event->MasterEvent =& $event;
$this->HandleEvent($hook_event);
}
}
}
/**
* Set's new event for $prefix_special
* passed
*
* @param string $prefix_special
* @param string $event_name
* @access public
*/
function setEvent($prefix_special,$event_name)
{
$actions =& $this->Application->recallObject('kActions');
$actions->Set('events['.$prefix_special.']',$event_name);
}
/**
* Run registred regular events with specified event type
*
* @param int $event_type
*/
function RunRegularEvents($event_type = reBEFORE)
{
$events_source = ($event_type == reBEFORE) ? $this->beforeRegularEvents : $this->afterRegularEvents;
/*if(rand(0, 100) < 90)
{
return;
}*/
$sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = %s';
$event_last_runs = $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr('RegularEventRuns') ) );
$event_last_runs = $event_last_runs ? unserialize($event_last_runs) : Array();
foreach($events_source as $short_name => $event_data)
{
$event_last_run = getArrayValue($event_last_runs, $short_name);
if($event_last_run && $event_last_run > adodb_mktime() - $event_data['RunInterval'])
{
continue;
}
else
{
$event = new kEvent($event_data['EventName']);
$event->redirect = false;
$this->Application->HandleEvent($event);
$event_last_runs[$short_name] = adodb_mktime();
}
}
$sql = 'REPLACE INTO '.TABLE_PREFIX.'Cache (VarName,Data,Cached) VALUES (%s,%s,%s)';
$this->Conn->Query( sprintf($sql, $this->Conn->qstr('RegularEventRuns'), $this->Conn->qstr(serialize($event_last_runs)), adodb_mktime() ) );
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/event_manager.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.14
\ No newline at end of property
+1.15
\ No newline at end of property
Index: trunk/core/kernel/db/db_event_handler.php
===================================================================
--- trunk/core/kernel/db/db_event_handler.php (revision 3542)
+++ trunk/core/kernel/db/db_event_handler.php (revision 3543)
@@ -1,1538 +1,1539 @@
<?php
define('EH_CUSTOM_PROCESSING_BEFORE',1);
define('EH_CUSTOM_PROCESSING_AFTER',2);
/**
* Note:
* 1. When adressing variables from submit containing
* Prefix_Special as part of their name use
* $event->getPrefixSpecial(true) instead of
* $event->Prefix_Special as usual. This is due PHP
* is converting "." symbols in variable names during
* submit info "_". $event->getPrefixSpecial optional
* 1st parameter returns correct corrent Prefix_Special
* for variables beeing submitted such way (e.g. variable
* name that will be converted by PHP: "users.read_only_id"
* will be submitted as "users_read_only_id".
*
* 2. When using $this->Application-LinkVar on variables submitted
* from form which contain $Prefix_Special then note 1st item. Example:
* LinkVar($event->getPrefixSpecial(true).'_varname',$event->Prefix_Special.'_varname')
*
*/
/**
* EventHandler that is used to process
* any database related events
*
*/
class kDBEventHandler extends kEventHandler {
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
/**
* Adds ability to address db connection
*
* @return kDBEventHandler
* @access public
*/
function kDBEventHandler()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
function mapEvents()
{
$events_map = Array('OnRemoveFilters' => 'FilterAction',
'OnApplyFilters' => 'FilterAction');
$this->eventMethods = array_merge($this->eventMethods, $events_map);
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
*/
function getPassedID(&$event)
{
//$ret = $this->Application->GetLinkedVar($event->getPrefixSpecial(true).'_id', $event->getPrefixSpecial().'_id');
// ?? We don't need to store selected id in session, as long as we have pass=all by default, which
// means that main item id will be passed to all sub-item screens by default
// another prove of that is that sub-items relay on main item '_mode' = 't' for switching to temp tables
// Also having id in session raised problems with the id of deleted item stuck in session
// 1. get id from post (used in admin)
$ret = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if($ret) return $ret;
// 2. get id from env (used in front)
$ret = $this->Application->GetVar($event->getPrefixSpecial().'_id');
if($ret) return $ret;
// recall selected ids array and use the first one
$ids=$this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
if ($ids != '') {
$ids=explode(',',$ids);
if($ids) $ret=array_shift($ids);
}
else { // if selected ids are not yet stored
$this->StoreSelectedIDs($event);
return $this->Application->GetVar($event->getPrefixSpecial(true).'_id'); // StoreSelectedIDs sets this variable
}
return $ret;
}
/**
* Prepares and stores selected_ids string
* in Session and Application Variables
* by getting all checked ids from grid plus
* id passed in get/post as prefix_id
*
* @param kEvent $event
*/
function StoreSelectedIDs(&$event)
{
$ret = Array();
// May be we don't need this part: ?
$passed = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if($passed !== false && $passed != '')
{
array_push($ret, $passed);
}
$ids = Array();
// get selected ids from post & save them to session
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
$id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
foreach($items_info as $id => $field_values)
{
if( getArrayValue($field_values,$id_field) ) array_push($ids,$id);
}
//$ids=array_keys($items_info);
}
$ret = array_unique(array_merge($ret, $ids));
$this->Application->SetVar($event->getPrefixSpecial().'_selected_ids',implode(',',$ret));
$this->Application->LinkVar($event->getPrefixSpecial().'_selected_ids');
// This is critical - otherwise getPassedID will return last ID stored in session! (not exactly true)
// this smells... needs to be refactored
$first_id = getArrayValue($ret,0);
if($first_id === false)
{
/*if ($event->getPrefixSpecial() == 'lang.current ')
{
$this->Application->Debugger->appendTrace();
}*/
trigger_error('Requested ID for prefix <b>'.$event->getPrefixSpecial().'</b> <span class="debug_error">not passed</span>',E_USER_NOTICE);
}
$this->Application->SetVar($event->getPrefixSpecial(true).'_id', $first_id);
}
/**
* Returns stored selected ids as an array
*
* @param kEvent $event
* @return array
*/
function getSelectedIDs(&$event)
{
return explode(',', $this->Application->GetVar($event->getPrefixSpecial().'_selected_ids'));
}
/**
* Returs associative array of submitted fields for current item
* Could be used while creating/editing single item -
* meaning on any edit form, except grid edit
*
* @param kEvent $event
*/
function getSubmittedFields(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$field_values = $items_info ? array_shift($items_info) : Array();
return $field_values;
}
/**
* Removes any information about current/selected ids
* from Application variables and Session
*
* @param kEvent $event
*/
function clearSelectedIDs(&$event)
{
$prefix_special = $event->getPrefixSpecial();
$ids = $this->Application->RecallVar($prefix_special.'_selected_ids');
$event->setEventParam('ids', $ids);
$this->Application->RemoveVar($prefix_special.'_selected_ids');
$this->Application->SetVar($prefix_special.'_selected_ids', '');
$this->Application->SetVar($prefix_special.'_id', ''); // $event->getPrefixSpecial(true).'_id' too may be
}
/*function SetSaveEvent(&$event)
{
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnUpdate');
$this->Application->LinkVar($event->Prefix_Special.'_SaveEvent');
}*/
/**
* Common builder part for Item & List
*
* @param kDBBase $object
* @param kEvent $event
* @access private
*/
function dbBuild(&$object,&$event)
{
$object->Configure();
$this->PrepareObject($object, $event);
$live_table = $event->getEventParam('live_table');
if( $this->UseTempTables($event) && !$live_table )
{
$object->SwitchToTemp();
}
// This strange constuction creates hidden field for storing event name in form submit
// It pass SaveEvent to next screen, otherwise after unsuccsefull create it will try to update rather than create
$current_event = $this->Application->GetVar($event->Prefix_Special.'_event');
// $this->Application->setEvent($event->Prefix_Special, $current_event);
$this->Application->setEvent($event->Prefix_Special, '');
$save_event = $this->UseTempTables($event) && $this->Application->GetTopmostPrefix($event->Prefix) == $event->Prefix ? 'OnSave' : 'OnUpdate';
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent',$save_event);
}
/**
* Builds item (loads if needed)
*
* @param kEvent $event
* @access protected
*/
function OnItemBuild(&$event)
{
$object =& $event->getObject();
$this->dbBuild($object,$event);
$sql = $this->ItemPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
// 2. loads if allowed
$auto_load = $this->Application->getUnitOption($event->Prefix,'AutoLoad');
$skip_autload = $event->getEventParam('skip_autoload');
if($auto_load && !$skip_autload) $this->LoadItem($event);
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_GoTab', '');
$actions->Set($event->Prefix_Special.'_GoId', '');
}
/**
* Build subtables array from configs
*
* @param kEvent $event
*/
function OnTempHandlerBuild(&$event)
{
$object =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$object->BuildTables( $event->Prefix, $this->getSelectedIDs($event) );
}
/**
* Enter description here...
*
* @param kEvent $event
* @return unknown
*/
function UseTempTables(&$event)
{
$object = &$event->getObject();
$top_prefix = $this->Application->GetTopmostPrefix($event->Prefix);
return $this->Application->GetVar($top_prefix.'_mode') == 't';
}
/**
* Returns table prefix from event (temp or live)
*
* @param kEvent $event
* @return string
* @todo Needed? Should be refactored (by Alex)
*/
function TablePrefix(&$event)
{
return $this->UseTempTables($event) ? kTempTablesHandler::GetTempTablePrefix().TABLE_PREFIX : TABLE_PREFIX;
}
function LoadItem(&$event)
{
$object =& $event->getObject();
$id = $this->getPassedID($event);
if ($object->Load($id) )
{
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_id', $object->GetId() );
}
else
{
$object->setID($id);
}
}
/**
* Builds list
*
* @param kEvent $event
* @access protected
*/
function OnListBuild(&$event)
{
$object =& $event->getObject();
$this->dbBuild($object,$event);
$sql = $this->ListPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
$object->linkToParent( $this->getMainSpecial($event) );
$this->AddFilters($event);
$this->SetCustomQuery($event); // new!, use this for dynamic queries based on specials for ex.
$this->SetPagination($event);
$this->SetSorting($event);
$object->CalculateTotals();
$actions =& $this->Application->recallObject('kActions');
$actions->Set('remove_specials['.$event->Prefix_Special.']', '0');
$actions->Set($event->Prefix_Special.'_GoTab', '');
}
/**
* Get's special of main item for linking with subitem
*
* @param kEvent $event
* @return string
*/
function getMainSpecial(&$event)
{
$special = $event->getEventParam('main_special');
if($special === false || $special == '$main_special')
{
$special = $event->Special;
}
return $special;
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
}
/**
* Set's new perpage for grid
*
* @param kEvent $event
*/
function OnSetPerPage(&$event)
{
$per_page = $this->Application->GetVar($event->getPrefixSpecial(true).'_PerPage');
$this->Application->StoreVar( $event->getPrefixSpecial().'_PerPage', $per_page );
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page) {
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page) {
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
// $page = $this->Application->GetLinkedVar($event->getPrefixSpecial(true).'_Page', $event->getPrefixSpecial().'_Page');
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
$object->SetPage($page);
}
function getPerPage(&$event)
{
$per_page = $event->getEventParam('per_page');
$config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
if ( $config_mapping ) {
switch ( $per_page ){
case 'short_list' :
$per_page = $this->Application->ConfigValue($config_mapping['ShortListPerPage']);
break;
case 'default' :
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
break;
}
}
if(!$per_page)
{
$per_page_var = $event->getPrefixSpecial().'_PerPage';
$per_page = $this->Application->RecallVar($per_page_var);
if(!$per_page)
{
if ( $config_mapping ) {
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
}
if(!$per_page) $per_page = 10;
}
}
return $per_page;
}
/**
* Set's correct sorting for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetSorting(&$event)
{
$event->setPseudoClass('_List');
$object =& $event->getObject();
$cur_sort1 = $this->Application->RecallVar($event->Prefix_Special.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort1_Dir');
$cur_sort2 = $this->Application->RecallVar($event->Prefix_Special.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort2_Dir');
$sorting_configs = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
$list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings');
$sorting_prefix = getArrayValue($list_sortings, $event->Special) ? $event->Special : '';
$tag_sort_by = $event->getEventParam('sort_by');
if ($tag_sort_by) {
list($by, $dir) = explode(',', $tag_sort_by);
if ($by == 'random') $by = 'RAND()';
$object->AddOrderField($by, $dir);
}
if ($sorting_configs && isset ($sorting_configs['DefaultSorting1Field'])){
$list_sortings[$sorting_prefix]['Sorting'] = Array(
$this->Application->ConfigValue($sorting_configs['DefaultSorting1Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting1Dir']),
$this->Application->ConfigValue($sorting_configs['DefaultSorting2Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting2Dir']),
);
}
// Use default if not specified
if ( !$cur_sort1 || !$cur_sort1_dir)
{
if ( $sorting = getArrayValue($list_sortings, $sorting_prefix, 'Sorting') ) {
reset($sorting);
$cur_sort1 = key($sorting);
$cur_sort1_dir = current($sorting);
if (next($sorting)) {
$cur_sort2 = key($sorting);
$cur_sort2_dir = current($sorting);
}
}
}
if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
foreach ($forced_sorting as $field => $dir) {
$object->AddOrderField($field, $dir);
}
}
if($cur_sort1 != '' && $cur_sort1_dir != '')
{
$object->AddOrderField($cur_sort1, $cur_sort1_dir);
}
if($cur_sort2 != '' && $cur_sort2_dir != '')
{
$object->AddOrderField($cur_sort2, $cur_sort2_dir);
}
}
/**
* Add filters found in session
*
* @param kEvent $event
*/
function AddFilters(&$event)
{
$object =& $event->getObject();
$search_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_search_filter');
if($search_filter)
{
$search_filter = unserialize($search_filter);
foreach($search_filter as $search_field => $filter_params)
{
$filter_type = ($filter_params['type'] == 'having') ? HAVING_FILTER : WHERE_FILTER;
$object->addFilter($search_field, $filter_params['value'], $filter_type, FLT_SEARCH);
}
}
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
if($view_filter)
{
$view_filter = unserialize($view_filter);
$temp_filter =& $this->Application->makeClass('kMultipleFilter');
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
$group_key = 0; $group_count = count($filter_menu['Groups']);
while($group_key < $group_count)
{
$group_info = $filter_menu['Groups'][$group_key];
$temp_filter->setType( constant('FLT_TYPE_'.$group_info['mode']) );
$temp_filter->clearFilters();
foreach ($group_info['filters'] as $flt_id)
{
$sql_key = getArrayValue($view_filter,$flt_id) ? 'on_sql' : 'off_sql';
if ($filter_menu['Filters'][$flt_id][$sql_key] != '')
{
$temp_filter->addFilter('view_filter_'.$flt_id, $filter_menu['Filters'][$flt_id][$sql_key]);
}
}
$object->addFilter('view_group_'.$group_key, $temp_filter, $group_info['type'] , FLT_VIEW);
$group_key++;
}
}
}
/**
* Set's new sorting for list
*
* @param kEvent $event
* @access protected
*/
function OnSetSorting(&$event)
{
$cur_sort1 = $this->Application->RecallVar($event->Prefix_Special.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort1_Dir');
$cur_sort2 = $this->Application->RecallVar($event->Prefix_Special.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort2_Dir');
$passed_sort1 = $this->Application->GetVar($event->getPrefixSpecial(true).'_Sort1');
if ($cur_sort1 == $passed_sort1) {
$cur_sort1_dir = $cur_sort1_dir == 'asc' ? 'desc' : 'asc';
}
else {
$cur_sort2 = $cur_sort1;
$cur_sort2_dir = $cur_sort1_dir;
$cur_sort1 = $passed_sort1;
$cur_sort1_dir = 'asc';
}
$this->Application->StoreVar($event->Prefix_Special.'_Sort1', $cur_sort1);
$this->Application->StoreVar($event->Prefix_Special.'_Sort1_Dir', $cur_sort1_dir);
$this->Application->StoreVar($event->Prefix_Special.'_Sort2', $cur_sort2);
$this->Application->StoreVar($event->Prefix_Special.'_Sort2_Dir', $cur_sort2_dir);
}
/**
* Set sorting directly to session
*
* @param kEvent $event
*/
function OnSetSortingDirect(&$event)
{
$combined = $this->Application->GetVar($event->getPrefixSpecial(true).'_CombinedSorting');
if ($combined) {
list($field,$dir) = explode('|',$combined);
$this->Application->StoreVar($event->Prefix_Special.'_Sort1', $field);
$this->Application->StoreVar($event->Prefix_Special.'_Sort1_Dir', $dir);
return;
}
$field_pos = $this->Application->GetVar($event->getPrefixSpecial(true).'_SortPos');
$this->Application->LinkVar( $event->getPrefixSpecial(true).'_Sort'.$field_pos, $event->Prefix_Special.'_Sort'.$field_pos);
$this->Application->LinkVar( $event->getPrefixSpecial(true).'_Sort'.$field_pos.'_Dir', $event->Prefix_Special.'_Sort'.$field_pos.'_Dir');
}
/**
* Reset grid sorting to default (from config)
*
* @param kEvent $event
*/
function OnResetSorting(&$event)
{
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1_Dir');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2_Dir');
}
/**
* Creates needed sql query to load item,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ItemPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix,'ItemSQLs');
return isset($sqls[$event->Special]) ? $sqls[$event->Special] : $sqls[''];
}
/**
* Creates needed sql query to load list,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ListPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix,'ListSQLs');
return isset( $sqls[$event->Special] ) ? $sqls[$event->Special] : $sqls[''];
}
/**
* Apply custom processing to item
*
* @param kEvent $event
*/
function customProcessing(&$event, $type)
{
}
/* Edit Events mostly used in Admin */
/**
* Creates new kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnCreate(&$event)
{
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
list($id,$field_values) = each($items_info);
$object->SetFieldsFromHash($field_values);
}
$this->customProcessing($event,'before');
//look at kDBItem' Create for ForceCreateId description, it's rarely used and is NOT set by default
if( $object->Create($event->getEventParam('ForceCreateId')) )
{
if( $object->IsTempTable() ) $object->setTempID();
$this->customProcessing($event,'after');
$event->status=erSUCCESS;
$event->redirect_params = Array('opener'=>'u');
}
else
{
$event->status = erFAIL;
$event->redirect = false;
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnCreate');
$object->setID($id);
}
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnUpdate(&$event)
{
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
break;
}
}
}
$event->redirect_params = Array('opener'=>'u');
}
/**
* Delete's kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnDelete(&$event)
{
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$object->ID = $this->getPassedID($event);
if( $object->Delete() )
{
$event->status = erSUCCESS;
}
else
{
$event->status = erFAIL;
$event->redirect = false;
}
}
/**
* Prepares new kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnNew(&$event)
{
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$object->setID(0);
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnCreate');
$table_info = $object->getLinkedInfo();
$object->SetDBField($table_info['ForeignKey'], $table_info['ParentId']);
$this->Application->setUnitOption($event->Prefix,'AutoLoad',true);
$event->redirect = false;
}
/**
* Cancel's kDBItem Editing/Creation
*
* @param kEvent $event
* @access protected
*/
function OnCancel(&$event)
{
$event->redirect_params = Array('opener'=>'u');
}
/**
* Deletes all selected items.
* Automatically recurse into sub-items using temp handler, and deletes sub-items
* by calling its Delete method if sub-item has AutoDelete set to true in its config file
*
* @param kEvent $event
*/
function OnMassDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 0)) {
return;
}
$event->status=erSUCCESS;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$this->StoreSelectedIDs($event);
$event->setEventParam('ids', $this->getSelectedIDs($event) );
$this->customProcessing($event, 'before');
$ids = $event->getEventParam('ids');
if($ids)
{
$temp->DeleteItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
$this->StoreSelectedIDs($event);
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->PrepareEdit();
$event->redirect=false;
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
*/
function OnSave(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status==erSUCCESS) {
$skip_master=false;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
// newly created item
/*if($this->getPassedID($event) == 0)
{
$master_id = $temp->CopyMasterToOriginal();
$temp->UpdateForeignKeys($master_id); // save linked field values
$skip_master = true; //we've already copied master table to get the id
}*/
if (!$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 0)) {
$temp->SaveEdit($skip_master);
}
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener'=>'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
}
}
/**
* Cancels edit
* Removes all temp tables and clears selected ids
*
* @param kEvent $event
*/
function OnCancelEdit(&$event)
{
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->CancelEdit();
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener'=>'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
}
/**
* Saves edited item into temp table
* If there is no id, new item is created in temp table
*
* @param kEvent $event
*/
function OnPreSave(&$event)
{
//$event->redirect = false;
// if there is no id - it means we need to create an item
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',false);
}
$item_id = $this->getPassedID($event);
if($item_id == '')
{
$event->CallSubEvent('OnPreSaveCreated');
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',true);
}
return;
}
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->SetDefaultValues();
$object->Load($id);
$object->SetFieldsFromHash($field_values);
if( $object->Update($id) )
{
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
break;
}
}
}
}
/**
* Saves edited item in temp table and loads
* item with passed id in current template
* Used in Prev/Next buttons
*
* @param kEvent $event
*/
function OnPreSaveAndGo(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status==erSUCCESS) {
$event->redirect_params[$event->getPrefixSpecial(true).'_id'] = $this->Application->GetVar($event->Prefix_Special.'_GoId');
}
}
/**
* Saves edited item in temp table and goes
* to passed tabs, by redirecting to it with OnPreSave event
*
* @param kEvent $event
*/
function OnPreSaveAndGoToTab(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Saves editable list and goes to passed tab,
* by redirecting to it with empty event
*
* @param kEvent $event
*/
function OnUpdateAndGoToTab(&$event)
{
$event->setPseudoClass('_List');
$event->CallSubEvent('OnUpdate');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
$this->clearSelectedIDs($event);
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$object =& $event->getObject();
$temp =& $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler');
$temp->PrepareEdit();
$object->setID(0);
$event->redirect=false;
}
/**
* Creates a new item in temp table and
* stores item id in App vars and Session on succsess
*
* @param kEvent $event
*/
function OnPreSaveCreated(&$event)
{
$this->Application->setUnitOption($event->Prefix,'AutoLoad',false);
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info) $field_values = array_shift($items_info);
$object =& $event->getObject();
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Create() )
{
$this->customProcessing($event, 'after');
$event->redirect_params[$event->getPrefixSpecial(true).'_id'] = $object->GetId();
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
$object->setID(0);
}
}
/* End of Edit events */
// III. Events that allow to put some code before and after Update,Load,Create and Delete methods of item
/**
* Occurse before loading item, 'id' parameter
* allows to get id of item beeing loaded
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemLoad(&$event)
{
}
/**
* Occurse after loading item, 'id' parameter
* allows to get id of item that was loaded
*
* @param kEvent $event
* @access public
*/
function OnAfterItemLoad(&$event)
{
}
/**
* Occurse before creating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemCreate(&$event)
{
}
/**
* Occurse after creating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemCreate(&$event)
{
}
/**
* Occurse before updating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemUpdate(&$event)
{
}
/**
* Occurse after updating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemUpdate(&$event)
{
}
/**
* Occurse before deleting item, id of item beeing
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemDelete(&$event)
{
}
/**
* Occurse after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @access public
*/
function OnAfterItemDelete(&$event)
{
}
/**
* Occurs after successful item validation
*
* @param kEvent $event
*/
function OnAfterItemValidate(&$event)
{
}
/**
* Occures after an item has been copied to temp
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToTemp(&$event)
{
}
/**
* Occures before an item is deleted from live table when copying from temp
* (temp handler deleted all items from live and then copy over all items from temp)
* Id of item being deleted is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeDeleteFromLive(&$event)
{
}
/**
* Occures before an item is copied to live table (after all foreign keys have been updated)
* Id of item being copied is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeCopyToLive(&$event)
{
}
/**
* !!! NOT FULLY IMPLEMENTED - SEE TEMP HANDLER COMMENTS (search by event name)!!!
* Occures after an item has been copied to live table
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$event)
{
}
/**
* Occures before an item is cloneded
* Id of ORIGINAL item is passed as event' 'id' param
* Do not call object' Update method in this event, just set needed fields!
*
* @param kEvent $event
*/
function OnBeforeClone(&$event)
{
}
/**
* Occures after an item has been cloned
* Id of newly created item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterClone(&$event)
{
}
/**
* Enter description here...
*
* @param kEvent $event
* @param string $search_field
* @param string $type
* @param string $value
* @param string $formatter_class
*/
function processRangeField(&$event, $search_field, $type, $value, $formatter_class)
{
$field = $search_field.'_'.$type;
$lang_current =& $this->Application->recallObject('lang.current');
$object =& $event->getObject();
$dt_separator = getArrayValue( $object->GetFieldOptions($field_name), 'date_time_separator' );
if(!$dt_separator) $dt_separator = ' ';
$time = ($type == 'datefrom') ? adodb_mktime(0,0,0) : adodb_mktime(23,59,59);
$time = adodb_date( $lang_current->GetDBField('TimeFormat'), $time);
$full_value = $value.$dt_separator.$time;
$formatter =& $this->Application->recallObject($formatter_class);
$value_ts = $formatter->Parse($full_value, $search_field, $object);
$pseudo = getArrayValue($object->FieldErrors, $search_field, 'pseudo');
if($pseudo)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_'.$field.'_error', $pseudo);
return -1;
}
return $value_ts;
}
/**
* Ensures that popup will be closed automatically
* and parent window will be refreshed with template
* passed
*
* @param kEvent $event
* @access public
*/
function finalizePopup(&$event, $main_prefix, $t)
{
$event->redirect = 'incs/close_popup';
// 2. substitute opener
$opener_stack = $this->Application->RecallVar('opener_stack');
$opener_stack = $opener_stack ? unserialize($opener_stack) : Array();
//array_pop($opener_stack);
- $new_level = 'index4.php|'.ltrim($this->Application->BuildEnv($t, Array('m_opener' => 'u'), 'all'), ENV_VAR_NAME.'=');
+ $pass_events = $event->getEventParam('pass_events');
+ $new_level = 'index4.php|'.ltrim($this->Application->BuildEnv($t, Array('m_opener' => 'u'), 'all', $pass_events), ENV_VAR_NAME.'=');
array_push($opener_stack,$new_level);
$this->Application->StoreVar('opener_stack',serialize($opener_stack));
}
/**
* Create search filters based on search query
*
* @param kEvent $event
* @access protected
*/
function OnSearch(&$event)
{
$event->setPseudoClass('_List');
$object =& $event->getObject();
$keyword = $this->Application->GetVar( $event->getPrefixSpecial(true).'_search_keyword');
$this->Application->StoreVar( $event->getPrefixSpecial().'_search_keyword', $keyword);
$custom_filters = $this->Application->RecallVar( $event->getPrefixSpecial().'_custom_filters');
$custom_filters = $custom_filters ? unserialize($custom_filters) : Array();
$submit_custom_filters = $this->Application->GetVar('custom_filters');
if($submit_custom_filters)
{
$submit_custom_filters = getArrayValue($submit_custom_filters, $event->getPrefixSpecial() );
if($submit_custom_filters)
{
foreach($submit_custom_filters as $cf_name => $cf_value)
{
if($cf_value)
{
$custom_filters[$cf_name] = $cf_value;
}
else
{
unset($custom_filters[$cf_name]);
}
}
}
}
$this->Application->StoreVar($event->getPrefixSpecial().'_custom_filters', serialize($custom_filters) );
if( !$keyword && !count($custom_filters) )
{
$this->OnSearchReset($event);
return true;
}
$grid_name = $this->Application->GetVar('grid_name');
$grids = $this->Application->getUnitOption($event->Prefix,'Grids');
$search_fields = array_keys($grids[$grid_name]['Fields']);
$search_filter = Array();
foreach($search_fields as $search_field)
{
$filter_type = isset($object->VirtualFields[$search_field]) ? 'having' : 'where';
$field_type = getArrayValue($object->Fields[$search_field],'type');
if(!$field_type) $field_type = 'string'; // default LIKE filter for all fields without type
$keyword = trim($keyword);
$keyword = str_replace(Array('"',"'"),'',$keyword);
$filter_value = '';
$table_name = ($filter_type == 'where') ? '`'.$object->TableName.'`.' : '';
// get field clause by formatter name and/or parameters
$formatter = getArrayValue($object->Fields[$search_field],'formatter');
switch($formatter)
{
case 'kOptionsFormatter':
$search_keys = Array();
$use_phrases = getArrayValue($object->Fields[$search_field], 'use_phrases');
foreach($object->Fields[$search_field]['options'] as $key => $val)
{
$pattern = '#'.$keyword.'#i';
if ( preg_match($pattern, $use_phrases ? $this->Application->Phrase($val) : $val) ) {
array_push($search_keys, $this->Conn->qstr($key));
}
}
if (count($search_keys) > 0) {
$filter_value = $table_name.'`'.$search_field.'` IN ('.implode(',', $search_keys).')';
}
$field_processed = true;
break;
case 'kDateFormatter':
$custom_filter = getArrayValue($object->Fields[$search_field], 'custom_filter');
if(!$custom_filter)
{
$field_processed = false;
break;
}
$filter_value = Array();
$field_value = getArrayValue($custom_filters, $search_field.'_datefrom');
if($field_value)
{
$value = $this->processRangeField($event, $search_field, 'datefrom', $field_value, $formatter);
$filter_value[] = $table_name.'`'.$search_field.'` >= '.$value;
}
$field_value = getArrayValue($custom_filters, $search_field.'_dateto');
if($field_value)
{
$value = $this->processRangeField($event, $search_field, 'dateto', $field_value, $formatter);
$filter_value[] = $table_name.'`'.$search_field.'` <= '.$value;
}
$filter_value = $filter_value ? '('.implode(') AND (', $filter_value).')' : '';
$field_processed = true;
break;
default:
$field_processed = false;
break;
}
// if not already processed by formatter, then get clause by field type
if(!$field_processed && $keyword)
{
switch($field_type)
{
case 'int':
case 'integer':
case 'numeric':
if( !is_numeric($keyword) ) break;
$filter_value = $table_name.'`'.$search_field.'` = \''.$keyword.'\'';
break;
case 'double':
case 'float':
case 'real':
if( !is_numeric($keyword) ) break;
$filter_value = 'ABS('.$table_name.'`'.$search_field.'` - \''.str_replace(',','.',$keyword).'\') <= 0.0001';
break;
case 'string':
$like_keyword = preg_replace( '/\'(.*)\'/U', '\\1', $this->Conn->qstr( str_replace('\\','\\\\', $keyword) ) );
$keywords = explode(' ', $like_keyword);
foreach($keywords as $keyword_pos => $keyword_value)
{
$keyword_value = trim($keyword_value);
if($keyword_value)
{
$keywords[$keyword_pos] = $table_name.'`'.$search_field.'` LIKE \'%'.$keyword_value.'%\'';
}
else
{
unset($keywords[$keyword_pos]);
}
}
$filter_value = '('.implode(') OR (',$keywords).')';
break;
}
}
if($filter_value) $search_filter[$search_field] = Array('type' => $filter_type, 'value' => $filter_value);
}
$this->Application->StoreVar($event->getPrefixSpecial().'_search_filter', serialize($search_filter) );
}
/**
* Clear search keywords
*
* @param kEvent $event
* @access protected
*/
function OnSearchReset(&$event)
{
$this->Application->RemoveVar($event->getPrefixSpecial().'_search_filter');
$this->Application->RemoveVar($event->getPrefixSpecial().'_search_keyword');
$this->Application->RemoveVar($event->getPrefixSpecial().'_custom_filters');
}
/**
* Set's new filter value (filter_id meaning from config)
*
* @param kEvent $event
*/
function OnSetFilter(&$event)
{
$filter_id = $this->Application->GetVar('filter_id');
$filter_value = $this->Application->GetVar('filter_value');
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
$view_filter = $view_filter ? unserialize($view_filter) : Array();
$view_filter[$filter_id] = $filter_value;
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
/**
* Add/Remove all filters applied to list from "View" menu
*
* @param kEvent $event
*/
function FilterAction(&$event)
{
$view_filter = Array();
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
switch ($event->Name)
{
case 'OnRemoveFilters':
$filter_value = 1;
break;
case 'OnApplyFilters':
$filter_value = 0;
break;
}
foreach($filter_menu['Filters'] as $filter_key => $filter_params)
{
if(!$filter_params) continue;
$view_filter[$filter_key] = $filter_value;
}
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnPreSaveAndOpenTranslator(&$event)
{
$this->Application->SetVar('allow_translation', true);
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$event->redirect = $this->Application->GetVar('translator_t');
$event->redirect_params = Array('pass'=>'all,trans,'.$this->Application->GetVar('translator_prefixes'),
$event->getPrefixSpecial(true).'_id' => $object->GetId(),
'trans_event'=>'OnLoad',
'trans_prefix'=> $this->Application->GetVar('translator_prefixes'),
'trans_field'=>$this->Application->GetVar('translator_field'),
'trans_multi_line'=>$this->Application->GetVar('translator_multi_line'),
);
}
}
function RemoveRequiredFields(&$object)
{
// making all field non-required to achieve successful presave
foreach($object->Fields as $field => $options)
{
if(isset($options['required']))
{
unset($object->Fields[$field]['required']);
}
}
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/db_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.32
\ No newline at end of property
+1.33
\ No newline at end of property
Index: trunk/core/kernel/db/dbitem.php
===================================================================
--- trunk/core/kernel/db/dbitem.php (revision 3542)
+++ trunk/core/kernel/db/dbitem.php (revision 3543)
@@ -1,888 +1,890 @@
<?php
/**
* DBItem
*
* Desciption
* @package kernel4
*/
class kDBItem extends kDBBase {
/**
* Description
*
* @var array Associative array of current item' field values
* @access public
*/
var $FieldValues;
/**
* Unformatted field values, before parse
*
* @var Array
* @access private
*/
var $DirtyFieldValues = Array();
var $FieldErrors;
var $ErrorMsgs = Array();
/**
* If set to true, Update will skip Validation before running
*
* @var array Associative array of current item' field values
* @access public
*/
var $IgnoreValidation = false;
var $Loaded = false;
/**
* Holds item' primary key value
*
* @var int Value of primary key field for current item
* @access public
*/
var $ID;
function kDBItem()
{
parent::kDBBase();
$this->ErrorMsgs['required'] = 'Field is required';
$this->ErrorMsgs['unique'] = 'Field value must be unique';
$this->ErrorMsgs['value_out_of_range'] = 'Field is out of range, possible values from %s to %s';
$this->ErrorMsgs['length_out_of_range'] = 'Field is out of range';
$this->ErrorMsgs['bad_type'] = 'Incorrect data format, please use %s';
$this->ErrorMsgs['bad_date_format'] = 'Incorrect date format, please use (%s) ex. (%s)';
}
function SetDirtyField($field_name, $field_value)
{
$this->DirtyFieldValues[$field_name] = $field_value;
}
function GetDirtyField($field_name)
{
return $this->DirtyFieldValues[$field_name];
}
/**
* Set's default values for all fields
*
* @access public
*/
function SetDefaultValues()
{
parent::SetDefaultValues();
foreach ($this->Fields as $field => $params) {
if ( isset($params['default']) ) {
$this->SetDBField($field, $params['default']);
}
else {
$this->SetDBField($field, NULL);
}
}
}
/**
* Sets current item field value
* (applies formatting)
*
* @access public
* @param string $name Name of the field
* @param mixed $value Value to set the field to
* @return void
*/
function SetField($name,$value)
{
$options = $this->GetFieldOptions($name);
$parsed = $value;
if ($value == '') $parsed = NULL;
if (isset($options['formatter'])) {
$formatter =& $this->Application->recallObject($options['formatter']);
// $parsed = $formatter->Parse($value, $options, $err);
$parsed = $formatter->Parse($value, $name, $this);
}
$this->SetDBField($name,$parsed);
}
/**
* Sets current item field value
* (doesn't apply formatting)
*
* @access public
* @param string $name Name of the field
* @param mixed $value Value to set the field to
* @return void
*/
function SetDBField($name,$value)
{
$this->FieldValues[$name] = $value;
/*if (isset($this->Fields[$name]['formatter'])) {
$formatter =& $this->Application->recallObject($this->Fields[$name]['formatter']);
$formatter->UpdateSubFields($name, $value, $this->Fields[$name], $this);
}*/
}
/**
* Set's field error, if pseudo passed not found then create it with message text supplied.
* Don't owerrite existing pseudo translation.
*
* @param string $field
* @param string $pseudo
* @param string $error_label
*/
function SetError($field, $pseudo, $error_label = '')
{
- $error_msg = $this->Application->Phrase($error_label);
- if( !($error_msg && getArrayValue($this->ErrorMsgs,$pseudo)) )
+ $error_field = isset($this->Fields[$field]['error_field']) ? $this->Fields[$field]['error_field'] : $field;
+ $this->FieldErrors[$error_field]['pseudo'] = $pseudo;
+
+ $error_msg = $error_label ? $this->Application->Phrase($error_label) : '';
+ if ($error_label && !getArrayValue($this->ErrorMsgs, $pseudo))
{
$this->ErrorMsgs[$pseudo] = $error_msg;
}
- $this->FieldErrors[$field]['pseudo'] = $pseudo;
}
/**
* Return current item' field value by field name
* (doesn't apply formatter)
*
* @access public
* @param string $name field name to return
* @return mixed
*/
function GetDBField($name)
{
return $this->FieldValues[$name];
}
function HasField($name)
{
return isset($this->FieldValues[$name]);
}
function GetFieldValues()
{
return $this->FieldValues;
}
/**
* Sets item' fields corresponding to elements in passed $hash values.
*
* The function sets current item fields to values passed in $hash, by matching $hash keys with field names
* of current item. If current item' fields are unknown {@link kDBItem::PrepareFields()} is called before acutally setting the fields
*
* @access public
* @param Array $hash
* @param Array $set_fields Optional param, field names in target object to set, other fields will be skipped
* @return void
*/
function SetFieldsFromHash($hash, $set_fields=null)
{
// used in formatter which work with multiple fields together
foreach($hash as $field_name => $field_value)
{
if( eregi("^[0-9]+$", $field_name) || !array_key_exists($field_name,$this->Fields) ) continue;
if ( is_array($set_fields) && !in_array($field_name, $set_fields) ) continue;
$this->SetDirtyField($field_name, $field_value);
}
// formats all fields using associated formatters
foreach ($hash as $field_name => $field_value)
{
if( eregi("^[0-9]+$", $field_name) || !array_key_exists($field_name,$this->Fields) ) continue;
if ( is_array($set_fields) && !in_array($field_name, $set_fields) ) continue;
$this->SetField($field_name,$field_value);
}
}
function SetDBFieldsFromHash($hash, $set_fields=null)
{
foreach ($hash as $field_name => $field_value)
{
if( eregi("^[0-9]+$", $field_name) || !array_key_exists($field_name,$this->Fields) ) continue;
if ( is_array($set_fields) && !in_array($field_name, $set_fields) ) continue;
$this->SetDBField($field_name, $field_value);
}
}
/**
* Returns part of SQL WHERE clause identifing the record, ex. id = 25
*
* @access public
* @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method
* @param Array $keys_hash alternative, then item id, keys hash to load item by
* @return void
* @see kDBItem::Load()
* @see kDBItem::Update()
* @see kDBItem::Delete()
*/
function GetKeyClause($method=null, $keys_hash = null)
{
if( !isset($keys_hash) ) $keys_hash = Array($this->IDField => $this->ID);
$ret = '';
foreach($keys_hash as $field => $value)
{
$ret .= '(`'.$this->TableName.'`.'.$field.' = '.$this->Conn->qstr($value).') AND ';
}
return preg_replace('/(.*) AND $/', '\\1', $ret);
}
/**
* Loads item from the database by given id
*
* @access public
* @param mixed $id item id of keys->values hash to load item by
* @param string $id_field_name Optional parameter to load item by given Id field
* @return bool True if item has been loaded, false otherwise
*/
function Load($id, $id_field_name = null)
{
if ( isset($id_field_name) ) $this->SetIDField( $id_field_name );
$keys_sql = '';
if( is_array($id) )
{
$keys_sql = $this->GetKeyClause('load', $id);
}
else
{
$this->setID($id);
$keys_sql = $this->GetKeyClause('load');
}
if ( isset($id_field_name) ) $this->setIDField( $this->Application->getUnitOption($this->Prefix, 'IDField') );
if( ($id === false) || !$keys_sql ) return $this->Clear();
if( !$this->raiseEvent('OnBeforeItemLoad', $id) ) return false;
$q = $this->GetSelectSQL().' WHERE '.$keys_sql;
$field_values = $this->Conn->GetRow($q);
if($field_values)
{
$this->FieldValues = array_merge_recursive2($this->FieldValues, $field_values);
}
else
{
return $this->Clear();
}
if( is_array($id) || isset($id_field_name) ) $this->setID( $this->FieldValues[$this->IDField] );
$this->UpdateFormattersSubFields(); // used for updating separate virtual date/time fields from DB timestamp (for example)
$this->raiseEvent('OnAfterItemLoad', $this->GetID() );
$this->Loaded = true;
return true;
}
/**
* Builds select sql, SELECT ... FROM parts only
*
* @access public
* @return string
*/
function GetSelectSQL()
{
$sql = $this->addCalculatedFields($this->SelectClause);
return parent::GetSelectSQL($sql);
}
function UpdateFormattersMasterFields()
{
foreach ($this->Fields as $field => $options) {
if (isset($options['formatter'])) {
$formatter =& $this->Application->recallObject($options['formatter']);
$formatter->UpdateMasterFields($field, $this->GetDBField($field), $options, $this);
}
}
}
function SkipField($field_name, $force_id=false)
{
$skip = false;
$skip = $skip || ( isset($this->VirtualFields[$field_name]) ); //skipping 'virtual' field
$skip = $skip || ( !getArrayValue($this->FieldValues, $field_name) && getArrayValue($this->Fields[$field_name], 'skip_empty') ); //skipping 'virtual' field
// $skip = $skip || ($field_name == $this->IDField && !$force_id); //skipping Primary Key
// $table_name = preg_replace("/^(.*)\./", "$1", $field_name);
// $skip = $skip || ($table_name && ($table_name != $this->TableName)); //skipping field from other tables
$skip = $skip || ( !isset($this->Fields[$field_name]) ); //skipping field not in Fields (nor virtual, nor real)
return $skip;
}
/**
* Updates previously loaded record with current item' values
*
* @access public
* @param int Primery Key Id to update
* @return bool
*/
function Update($id=null, $system_update=false)
{
if( isset($id) ) $this->setID($id);
if( !$this->raiseEvent('OnBeforeItemUpdate') ) return false;
if( !isset($this->ID) ) return false;
// Validate before updating
if( !$this->IgnoreValidation && !$this->Validate() ) return false;
if( !$this->raiseEvent('OnAfterItemValidate') ) return false;
//Nothing to update
if(!$this->FieldValues) return true;
$sql = sprintf('UPDATE %s SET ',$this->TableName);
foreach ($this->FieldValues as $field_name => $field_value)
{
if ($this->SkipField($field_name)) continue;
$real_field_name = eregi_replace("^.*\.", '',$field_name); //removing table names from field names
//Adding part of SET clause for current field, escaping data with ADODB' qstr
if (is_null( $this->FieldValues[$field_name] )) {
if (isset($this->Fields[$field_name]['not_null']) && $this->Fields[$field_name]['not_null']) {
$sql .= '`'.$real_field_name.'` = '.$this->Conn->qstr($this->Fields[$field_name]['default']).', ';
}
else {
$sql .= '`'.$real_field_name.'` = NULL, ';
}
}
else {
$sql.= sprintf('`%s`=%s, ', $real_field_name, $this->Conn->qstr($this->FieldValues[$field_name], 0));
}
}
$sql = ereg_replace(", $", '', $sql); //Removing last comma and space
$sql.= sprintf(' WHERE %s', $this->GetKeyClause('update')); //Adding WHERE clause with Primary Key
if( $this->Conn->ChangeQuery($sql) === false ) return false;
$affected = $this->Conn->getAffectedRows();
if (!$system_update && $affected == 1){
$this->setModifiedFlag();
}
$this->raiseEvent('OnAfterItemUpdate');
return true;
}
/**
* Validate all item fields based on
* constraints set in each field options
* in config
*
* @return bool
* @access private
*/
function Validate()
{
$this->UpdateFormattersMasterFields(); //order is critical - should be called BEFORE checking errors
$global_res = true;
foreach ($this->Fields as $field => $params) {
$res = true;
$res = $res && $this->ValidateType($field, $params);
$res = $res && $this->ValidateRange($field, $params);
$res = $res && $this->ValidateUnique($field, $params);
$res = $res && $this->ValidateRequired($field, $params);
$res = $res && $this->CustomValidation($field, $params);
// If Formatter has set some error messages during values parsing
$error_field = isset($params['error_field']) ? $params['error_field'] : $field;
if (isset($this->FieldErrors[$error_field]['pseudo']) && $this->FieldErrors[$error_field] != '') {
$global_res = false;
}
$global_res = $global_res && $res;
}
if (!$global_res && $this->Application->isDebugMode() )
{
global $debugger;
$error_msg = "Validation failed in prefix <b>".$this->Prefix."</b>, FieldErrors follow (look at items with 'pseudo' key set)<br>
You may ignore this notice if submitted data really has a validation error ";
trigger_error( $error_msg, E_USER_NOTICE);
$debugger->dumpVars($this->FieldErrors);
}
return $global_res;
}
/**
* Check field value by user-defined alghoritm
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
*/
function CustomValidation($field, $params)
{
return true;
}
/**
* Check if item has errors
*
* @param Array $skip_fields fields to skip during error checking
* @return bool
*/
function HasErrors($skip_fields)
{
$global_res = false;
foreach ($this->Fields as $field => $field_params) {
// If Formatter has set some error messages during values parsing
if ( !( in_array($field, $skip_fields) ) &&
isset($this->FieldErrors[$field]['pseudo']) && $this->FieldErrors[$field] != '') {
$global_res = true;
}
}
return $global_res;
}
/**
* Check if value in field matches field type specified in config
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
*/
function ValidateType($field, $params)
{
$res = true;
$val = $this->FieldValues[$field];
$error_field = isset($params['error_field']) ? $params['error_field'] : $field;
if ( $val != '' &&
isset($params['type']) &&
preg_match("#int|integer|double|float|real|numeric|string#", $params['type'])
) {
$res = is_numeric($val);
if($params['type']=='string' || $res)
{
$f = 'is_'.$params['type'];
settype($val, $params['type']);
$res = $f($val) && ($val==$this->FieldValues[$field]);
}
if (!$res)
{
$this->FieldErrors[$error_field]['pseudo'] = 'bad_type';
$this->FieldErrors[$error_field]['params'] = $params['type'];
}
}
return $res;
}
/**
* Check if value is set for required field
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
* @access private
*/
function ValidateRequired($field, $params)
{
$res = true;
$error_field = isset($params['error_field']) ? $params['error_field'] : $field;
if ( getArrayValue($params,'required') )
{
$res = ( (string) $this->FieldValues[$field] != '');
}
$options = $this->GetFieldOptions($field);
if (!$res && getArrayValue($options, 'formatter') != 'kUploadFormatter') $this->FieldErrors[$error_field]['pseudo'] = 'required';
return $res;
}
/**
* Validates that current record has unique field combination among other table records
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
* @access private
*/
function ValidateUnique($field, $params)
{
$res = true;
$error_field = isset($params['error_field']) ? $params['error_field'] : $field;
$unique_fields = getArrayValue($params,'unique');
if($unique_fields !== false)
{
$where = Array();
array_push($unique_fields,$field);
foreach($unique_fields as $unique_field)
{
$where[] = '`'.$unique_field.'` = '.$this->Conn->qstr( $this->GetDBField($unique_field) );
}
$sql = 'SELECT COUNT(*) FROM %s WHERE ('.implode(') AND (',$where).') AND ('.$this->IDField.' <> '.(int)$this->ID.')';
$res_temp = $this->Conn->GetOne( str_replace('%s', $this->TableName, $sql) );
$current_table_only = getArrayValue($params, 'current_table_only'); // check unique record only in current table
$res_live = $current_table_only ? 0 : $this->Conn->GetOne( str_replace('%s', kTempTablesHandler::GetLiveName($this->TableName), $sql) );
$res = ($res_temp == 0) && ($res_live == 0);
if(!$res) $this->FieldErrors[$error_field]['pseudo'] = 'unique';
}
return $res;
}
/**
* Check if field value is in range specified in config
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
* @access private
*/
function ValidateRange($field, $params)
{
$res = true;
$val = $this->FieldValues[$field];
$error_field = isset($params['error_field']) ? $params['error_field'] : $field;
if ( isset($params['type']) && preg_match("#int|integer|double|float|real#", $params['type']) && strlen($val) > 0 ) {
if ( isset($params['max_value_inc'])) {
$res = $res && $val <= $params['max_value_inc'];
$max_val = $params['max_value_inc'].' (inclusive)';
}
if ( isset($params['min_value_inc'])) {
$res = $res && $val >= $params['min_value_inc'];
$min_val = $params['min_value_inc'].' (inclusive)';
}
if ( isset($params['max_value_exc'])) {
$res = $res && $val < $params['max_value_exc'];
$max_val = $params['max_value_exc'].' (exclusive)';
}
if ( isset($params['min_value_exc'])) {
$res = $res && $val > $params['min_value_exc'];
$min_val = $params['min_value_exc'].' (exclusive)';
}
}
if (!$res) {
$this->FieldErrors[$error_field]['pseudo'] = 'value_out_of_range';
if ( !isset($min_val) ) $min_val = '-&infin;';
if ( !isset($max_val) ) $max_val = '&infin;';
$this->FieldErrors[$error_field]['params'] = Array( $min_val, $max_val );
return $res;
}
if ( isset($params['max_len'])) {
$res = $res && strlen($val) <= $params['max_len'];
}
if ( isset($params['min_len'])) {
$res = $res && strlen($val) >= $params['min_len'];
}
if (!$res) {
$this->FieldErrors[$error_field]['pseudo'] = 'length_out_of_range';
$this->FieldErrors[$error_field]['params'] = Array( getArrayValue($params,'min_len'), getArrayValue($params,'max_len') );
return $res;
}
return $res;
}
/**
* Return error message for field
*
* @param string $field
* @return string
* @access public
*/
function GetErrorMsg($field, $force_escape = null)
{
if( !isset($this->FieldErrors[$field]) ) return '';
$err = getArrayValue($this->FieldErrors[$field], 'pseudo');
if( isset($this->Fields[$field]['error_msgs'][$err]) )
{
$msg = $this->Fields[$field]['error_msgs'][$err];
$msg = $this->Application->ReplaceLanguageTags($msg, $force_escape);
}
else
{
if( !isset($this->ErrorMsgs[$err]) ) return $err;
$msg = $this->ErrorMsgs[$err];
}
if ( isset($this->FieldErrors[$field]['params']) )
{
return vsprintf($msg, $this->FieldErrors[$field]['params']);
}
return $msg;
}
/**
* Creates a record in the database table with current item' values
*
* @param mixed $force_id Set to TRUE to force creating of item's own ID or to value to force creating of passed id. Do not pass 1 for true, pass exactly TRUE!
* @access public
* @return bool
*/
function Create($force_id=false, $system_create=false)
{
if( !$this->raiseEvent('OnBeforeItemCreate') ) return false;
// Validating fields before attempting to create record
if( !$this->IgnoreValidation && !$this->Validate() ) return false;
if( !$this->raiseEvent('OnAfterItemValidate') ) return false;
if (is_int($force_id)) {
$this->FieldValues[$this->IDField] = $force_id;
}
elseif (!$force_id || !is_bool($force_id)) {
$this->FieldValues[$this->IDField] = $this->generateID();
}
$fields_sql = '';
$values_sql = '';
foreach ($this->FieldValues as $field_name => $field_value)
{
if ($this->SkipField($field_name, $force_id)) continue;
$fields_sql .= sprintf('`%s`, ',$field_name); //Adding field name to fields block of Insert statement
//Adding field' value to Values block of Insert statement, escaping it with ADODB' qstr
if (is_null( $this->FieldValues[$field_name] ))
{
if (isset($this->Fields[$field_name]['not_null']) && $this->Fields[$field_name]['not_null'])
{
$values_sql .= $this->Conn->qstr($this->Fields[$field_name]['default']).', ';
}
else
{
$values_sql .= 'NULL, ';
}
}
else
{
$values_sql .= sprintf('%s, ',$this->Conn->qstr($this->FieldValues[$field_name], 0));
}
}
//Cutting last commas and spaces
$fields_sql = ereg_replace(", $", '', $fields_sql);
$values_sql = ereg_replace(", $", '', $values_sql);
$sql = sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->TableName, $fields_sql, $values_sql); //Formatting query
//Executing the query and checking the result
if($this->Conn->ChangeQuery($sql) === false) return false;
$insert_id = $this->Conn->getInsertID();
if($insert_id == 0) $insert_id = $this->FieldValues[$this->IDField];
$this->setID($insert_id);
if (!$system_create){
$this->setModifiedFlag();
}
$this->raiseEvent('OnAfterItemCreate');
return true;
}
/**
* Deletes the record from databse
*
* @access public
* @return bool
*/
function Delete($id = null)
{
if( isset($id) ) $this->setID($id);
if( !$this->raiseEvent('OnBeforeItemDelete') ) return false;
$q = 'DELETE FROM '.$this->TableName.' WHERE '.$this->GetKeyClause('Delete');
$ret = $this->Conn->ChangeQuery($q);
$this->setModifiedFlag();
$this->raiseEvent('OnAfterItemDelete');
return $ret;
}
/**
* Sets new name for item in case if it is beeing copied
* in same table
*
* @param array $master Table data from TempHandler
* @param int $foreign_key ForeignKey value to filter name check query by
* @access private
*/
function NameCopy($master=null, $foreign_key=null)
{
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
if (!$title_field || isset($this->CalculatedFields[$title_field]) ) return;
$new_name = $this->GetDBField($title_field);
$original_checked = false;
do {
if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) {
$new_name = 'Copy '.($regs[1]+1).' of '.$regs[2];
}
elseif ($original_checked) {
$new_name = 'Copy of '.$new_name;
}
// if we are cloning in temp table this will look for names in temp table,
// since object' TableName contains correct TableName (for temp also!)
// if we are cloning live - look in live
$query = 'SELECT '.$title_field.' FROM '.$this->TableName.'
WHERE '.$title_field.' = '.$this->Conn->qstr($new_name);
$foreign_key_field = getArrayValue($master, 'ForeignKey');
$foreign_key_field = is_array($foreign_key_field) ? $foreign_key_field[ $master['ParentPrefix'] ] : $foreign_key_field;
if ($foreign_key_field && isset($foreign_key)) {
$query .= ' AND '.$foreign_key_field.' = '.$foreign_key;
}
$res = $this->Conn->GetOne($query);
/*// if not found in live table, check in temp table if applicable
if ($res === false && $object->Special == 'temp') {
$query = 'SELECT '.$name_field.' FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$name_field.' = '.$this->Conn->qstr($new_name);
$res = $this->Conn->GetOne($query);
}*/
$original_checked = true;
} while ($res !== false);
$this->SetDBField($title_field, $new_name);
}
function raiseEvent($name, $id=null)
{
if( !isset($id) ) $id = $this->GetID();
$event = new kEvent( Array('name'=>$name,'prefix'=>$this->Prefix,'special'=>$this->Special) );
$event->setEventParam('id', $id);
$this->Application->HandleEvent($event);
return $event->status == erSUCCESS ? true : false;
}
/**
* Set's new ID for item
*
* @param int $new_id
* @access public
*/
function setID($new_id)
{
$this->ID = $new_id;
$this->SetDBField($this->IDField, $new_id);
}
/**
* Generate and set new temporary id
*
* @access private
*/
function setTempID()
{
$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$this->IDField.') FROM '.$this->TableName);
if($new_id > 0) $new_id = 0;
--$new_id;
$this->Conn->Query('UPDATE '.$this->TableName.' SET `'.$this->IDField.'` = '.$new_id.' WHERE `'.$this->IDField.'` = '.$this->GetID());
$this->SetID($new_id);
}
/**
* Set's modification flag for main prefix of current prefix to true
*
* @access private
* @author Alexey
*/
function setModifiedFlag()
{
$main_prefix = $this->Application->GetTopmostPrefix($this->Prefix);
$this->Application->StoreVar($main_prefix.'_modified', '1');
}
/**
* Returns ID of currently processed record
*
* @return int
* @access public
*/
function GetID()
{
return $this->ID;
}
/**
* Generates ID for new items before inserting into database
*
* @return int
* @access private
*/
function generateID()
{
return 0;
}
/**
* Returns true if item was loaded successfully by Load method
*
* @return bool
*/
function isLoaded()
{
return $this->Loaded;
}
/**
* Checks if field is required
*
* @param string $field
* @return bool
*/
function isRequired($field)
{
return getArrayValue( $this->Fields[$field], 'required' );
}
/**
* Sets new required flag to field
*
* @param string $field
* @param bool $is_required
*/
function setRequired($field, $is_required = true)
{
$this->Fields[$field]['required'] = $is_required;
}
function Clear()
{
$this->setID(null);
$this->Loaded = false;
$this->FieldValues = Array();
$this->SetDefaultValues();
$this->FieldErrors = Array();
return $this->Loaded;
}
function Query($force = false)
{
if( $this->Application->isDebugMode() )
{
$this->Application->Debugger->appendTrace();
}
trigger_error('<b>Query</b> method is called in class <b>'.get_class($this).'</b> for prefix <b>'.$this->getPrefixSpecial().'</b>', E_USER_ERROR);
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/db/dbitem.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.21
\ No newline at end of property
+1.22
\ No newline at end of property
Index: trunk/core/kernel/globals.php
===================================================================
--- trunk/core/kernel/globals.php (revision 3542)
+++ trunk/core/kernel/globals.php (revision 3543)
@@ -1,398 +1,447 @@
<?php
if( !function_exists('array_merge_recursive2') )
{
/**
* array_merge_recursive2()
*
* Similar to array_merge_recursive but keyed-valued are always overwritten.
* Priority goes to the 2nd array.
*
* @static yes
* @param $paArray1 array
* @param $paArray2 array
* @return array
* @access public
*/
function array_merge_recursive2($paArray1, $paArray2)
{
if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; }
foreach ($paArray2 AS $sKey2 => $sValue2)
{
$paArray1[$sKey2] = array_merge_recursive2( getArrayValue($paArray1,$sKey2), $sValue2);
}
return $paArray1;
}
}
/**
* @return int
* @param $array array
* @param $value mixed
* @desc Prepend a reference to an element to the beginning of an array. Renumbers numeric keys, so $value is always inserted to $array[0]
*/
function array_unshift_ref(&$array, &$value)
{
$return = array_unshift($array,'');
$array[0] =& $value;
return $return;
}
if (!function_exists('print_pre')) {
/**
* Same as print_r, budet designed for viewing in web page
*
* @param Array $data
* @param string $label
*/
function print_pre($data, $label='')
{
if( constOn('DEBUG_MODE') )
{
global $debugger;
if($label) $debugger->appendHTML('<b>'.$label.'</b>');
$debugger->dumpVars($data);
}
else
{
if($label) echo '<b>',$label,'</b><br>';
echo '<pre>',print_r($data,true),'</pre>';
}
}
}
if (!function_exists('getArrayValue')) {
/**
* Returns array value if key exists
*
* @param Array $array searchable array
* @param int $key array key
* @return string
* @access public
*/
//
function getArrayValue(&$array,$key)
{
$ret = isset($array[$key]) ? $array[$key] : false;
if ($ret && func_num_args() > 2) {
for ($i = 2; $i < func_num_args(); $i++) {
$cur_key = func_get_arg($i);
$ret = getArrayValue( $ret, $cur_key );
if ($ret === false) break;
}
}
return $ret;
}
}
/**
* Rename key in associative array, maintaining keys order
*
* @param Array $array Associative Array
* @param mixed $old Old key name
* @param mixed $new New key name
* @access public
*/
function array_rename_key(&$array, $old, $new)
{
foreach ($array as $key => $val)
{
$new_array[ $key == $old ? $new : $key] = $val;
}
$array = $new_array;
}
if( !function_exists('safeDefine') )
{
/**
* Define constant if it was not already defined before
*
* @param string $const_name
* @param string $const_value
* @access public
*/
function safeDefine($const_name, $const_value)
{
if(!defined($const_name)) define($const_name,$const_value);
}
}
if( !function_exists('parse_portal_ini') )
{
function parse_portal_ini($file, $parse_section = false)
{
if (!file_exists($file)) return false;
if( file_exists($file) && !is_readable($file) ) die('Could Not Open Ini File');
$contents = file($file);
$retval = Array();
$section = '';
$ln = 1;
$resave = false;
foreach($contents as $line) {
if ($ln == 1 && $line != '<'.'?'.'php die() ?'.">\n") {
$resave = true;
}
$ln++;
$line = trim($line);
$line = eregi_replace(';[.]*','',$line);
if(strlen($line) > 0) {
//echo $line . " - ";
if(eregi('^[[a-z]+]$',str_replace(' ', '', $line))) {
//echo 'section';
$section = substr($line,1,(strlen($line)-2));
if ($parse_section) {
$retval[$section] = array();
}
continue;
} elseif(eregi('=',$line)) {
//echo 'main element';
list($key,$val) = explode(' = ',$line);
if (!$parse_section) {
$retval[trim($key)] = str_replace('"', '', $val);
}
else {
$retval[$section][trim($key)] = str_replace('"', '', $val);
}
} //end if
//echo '<br />';
} //end if
} //end foreach
if($resave)
{
$fp = fopen($file, 'w');
reset($contents);
fwrite($fp,'<'.'?'.'php die() ?'.">\n\n");
foreach($contents as $line) fwrite($fp,"$line");
fclose($fp);
}
return $retval;
}
}
if( !function_exists('getmicrotime') )
{
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
}
if( !function_exists('k4_include_once') )
{
function k4_include_once($file)
{
if ( constOn('DEBUG_MODE') && isset($debugger) && constOn('DBG_PROFILE_INCLUDES') )
{
if ( in_array($file, get_required_files()) ) return;
global $debugger;
$debugger->IncludeLevel++;
$before_time = getmicrotime();
$before_mem = memory_get_usage();
include_once($file);
$used_time = getmicrotime() - $before_time;
$used_mem = memory_get_usage() - $before_mem;
$debugger->IncludeLevel--;
$debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file);
$debugger->IncludesData['mem'][] = $used_mem;
$debugger->IncludesData['time'][] = $used_time;
$debugger->IncludesData['level'][] = $debugger->IncludeLevel;
}
else
{
include_once($file);
}
}
}
/**
* Checks if string passed is serialized array
*
* @param string $string
* @return bool
*/
function IsSerialized($string)
{
if( is_array($string) ) return false;
return preg_match('/a:([\d]+):{/', $string);
}
if (!function_exists('makepassword4')){
function makepassword4($length=10)
{
$pass_length=$length;
$p1=array('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z');
$p2=array('a','e','i','o','u');
$p3=array('1','2','3','4','5','6','7','8','9');
$p4=array('(','&',')',';','%'); // if you need real strong stuff
// how much elements in the array
// can be done with a array count but counting once here is faster
$s1=21;// this is the count of $p1
$s2=5; // this is the count of $p2
$s3=9; // this is the count of $p3
$s4=5; // this is the count of $p4
// possible readable combinations
$c1='121'; // will be like 'bab'
$c2='212'; // will be like 'aba'
$c3='12'; // will be like 'ab'
$c4='3'; // will be just a number '1 to 9' if you dont like number delete the 3
// $c5='4'; // uncomment to active the strong stuff
$comb='4'; // the amount of combinations you made above (and did not comment out)
for ($p=0;$p<$pass_length;)
{
mt_srand((double)microtime()*1000000);
$strpart=mt_rand(1,$comb);
// checking if the stringpart is not the same as the previous one
if($strpart<>$previous)
{
$pass_structure.=${'c'.$strpart};
// shortcutting the loop a bit
$p=$p+strlen(${'c'.$strpart});
}
$previous=$strpart;
}
// generating the password from the structure defined in $pass_structure
for ($g=0;$g<strlen($pass_structure);$g++)
{
mt_srand((double)microtime()*1000000);
$sel=substr($pass_structure,$g,1);
$pass.=${'p'.$sel}[mt_rand(0,-1+${'s'.$sel})];
}
return $pass;
}
}
if( !function_exists('unhtmlentities') )
{
function unhtmlentities($string)
{
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip ($trans_tbl);
return strtr($string, $trans_tbl);
}
}
if( !function_exists('curl_post') )
{
/**
* submits $url with $post as POST
*
* @param string $url
* @param unknown_type $post
* @return unknown
*/
function curl_post($url, $post)
{
if( is_array($post) )
{
$params_str = '';
foreach($post as $key => $value) $params_str .= $key.'='.urlencode($value).'&';
$post = $params_str;
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_REFERER, PROTOCOL.SERVER_NAME);
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION, 0);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
}
if( !function_exists('memory_get_usage') )
{
function memory_get_usage(){ return -1; }
}
function &ref_call_user_func_array($callable, $args)
{
if( is_scalar($callable) )
{
// $callable is the name of a function
$call = $callable;
}
else
{
if( is_object($callable[0]) )
{
// $callable is an object and a method name
$call = "\$callable[0]->{$callable[1]}";
}
else
{
// $callable is a class name and a static method
$call = "{$callable[0]}::{$callable[1]}";
}
}
// Note because the keys in $args might be strings
// we do this in a slightly round about way.
$argumentString = Array();
$argumentKeys = array_keys($args);
foreach($argumentKeys as $argK)
{
$argumentString[] = "\$args[$argumentKeys[$argK]]";
}
$argumentString = implode($argumentString, ', ');
// Note also that eval doesn't return references, so we
// work around it in this way...
eval("\$result =& {$call}({$argumentString});");
return $result;
}
if( !function_exists('constOn') )
{
/**
* Checks if constant is defined and has positive value
*
* @param string $const_name
* @return bool
*/
function constOn($const_name)
{
return defined($const_name) && constant($const_name);
}
}
function Kg2Pounds($kg)
{
$major = floor( round($kg / POUND_TO_KG, 3) );
$minor = abs(round(($kg - $major * POUND_TO_KG) / POUND_TO_KG * 16, 2));
return array($major, $minor);
}
function Pounds2Kg($pounds, $ounces=0)
{
return round(($pounds + ($ounces / 16)) * POUND_TO_KG, 5);
}
+
+ /**
+ * Formats file/memory size in nice way
+ *
+ * @param int $bytes
+ * @return string
+ * @access public
+ */
+ function formatSize($bytes)
+ {
+ if ($bytes >= 1099511627776) {
+ $return = round($bytes / 1024 / 1024 / 1024 / 1024, 2);
+ $suffix = "TB";
+ } elseif ($bytes >= 1073741824) {
+ $return = round($bytes / 1024 / 1024 / 1024, 2);
+ $suffix = "GB";
+ } elseif ($bytes >= 1048576) {
+ $return = round($bytes / 1024 / 1024, 2);
+ $suffix = "MB";
+ } elseif ($bytes >= 1024) {
+ $return = round($bytes / 1024, 2);
+ $suffix = "KB";
+ } else {
+ $return = $bytes;
+ $suffix = "Byte";
+ }
+ $return .= ' '.$suffix;
+ return $return;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param resource $filePointer the file resource to write to
+ * @param Array $data the data to write out
+ * @param string $delimiter the field separator
+ * @param string $enclosure symbol to enclose field data to
+ * @param string $recordSeparator symbols to separate records with
+ */
+ function fputcsv2($filePointer, $data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
+ {
+ foreach($data as $field_index => $field_value) {
+ // replaces an enclosure with two enclosures
+ $data[$field_index] = str_replace($enclosure, $enclosure.$enclosure, $field_value);
+ }
+
+ $line = $enclosure.implode($enclosure.$delimiter.$enclosure, $data).$enclosure.$recordSeparator;
+ fwrite($filePointer, $line);
+ }
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/globals.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.19
\ No newline at end of property
+1.20
\ No newline at end of property
Index: trunk/core/units/general/cat_dbitem.php
===================================================================
--- trunk/core/units/general/cat_dbitem.php (revision 3542)
+++ trunk/core/units/general/cat_dbitem.php (revision 3543)
@@ -1,275 +1,354 @@
<?php
class kCatDBItem extends kDBItem {
var $CustomFields = Array();
+ /**
+ * Category path, needed for import
+ *
+ * @var Array
+ */
+ var $CategoryPath = Array();
+
function Init($prefix, $special, $event_params = null)
{
parent::Init($prefix, $special, $event_params);
$item_type = $this->Application->getUnitOption($this->Prefix, 'ItemType');
- $sql = 'SELECT CustomFieldId, FieldName FROM '.TABLE_PREFIX.'CustomField WHERE Type = %s';
- $this->CustomFields = $this->Conn->GetCol( sprintf($sql, $item_type), 'FieldName' );
+ $sql = 'SELECT CustomFieldId, FieldName FROM '.TABLE_PREFIX.'CustomField WHERE Type = '.$item_type;
+ $this->CustomFields = $this->Conn->GetCol($sql, 'FieldName');
}
- function Create()
+ function Create($force_id=false, $system_create=false)
{
if (!$this->Validate()) return false;
$this->checkFilename();
$this->SetDBField('ResourceId', $this->Application->NextResourceId());
$this->SetDBField('Modified', adodb_mktime() );
$this->SetDBField('CreatedById', $this->Application->GetVar('u_id'));
$this->generateFilename();
- $ret = parent::Create();
+ $ret = parent::Create($force_id, $system_create);
if($ret)
{
if ( kTempTablesHandler::IsTempTable($this->TableName) ) {
$table = kTempTablesHandler::GetTempName(TABLE_PREFIX.'CategoryItems');
}
else {
$table = TABLE_PREFIX.'CategoryItems';
}
$cat_id = $this->Application->GetVar('m_cat_id');
$query = 'INSERT INTO '.$table.' (CategoryId,ItemResourceId,PrimaryCat)
VALUES ('.$cat_id.','.$this->GetField('ResourceId').',1)';
$this->Conn->Query($query);
}
return $ret;
}
- function Update($id=null)
+ function Update($id=null, $system_update=false)
{
$this->checkFilename();
$this->VirtualFields['ResourceId'] = true;
$this->SetDBField('Modified', adodb_mktime() );
$this->SetDBField('ModifiedById', $this->Application->GetVar('u_id'));
$this->generateFilename();
- return parent::Update($id);
+ return parent::Update($id, $system_update);
}
function checkFilename()
{
if( !$this->GetDBField('AutomaticFilename') )
{
$filename = $this->GetDBField('Filename');
$this->SetDBField('Filename', $this->stripDisallowed($filename) );
}
}
function Copy($cat_id=null)
{
if (!isset($cat_id)) $cat_id = $this->Application->GetVar('m_cat_id');
$this->NameCopy($cat_id);
return $this->Create($cat_id);
}
function NameCopy($master=null, $foreign_key=null)
{
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
if (!$title_field) return;
$new_name = $this->GetDBField($title_field);
$cat_id = $this->Application->GetVar('m_cat_id');
$original_checked = false;
do {
if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) {
$new_name = 'Copy '.( (int)$regs[1] + 1 ).' of '.$regs[2];
}
elseif ($original_checked) {
$new_name = 'Copy of '.$new_name;
}
$query = 'SELECT '.$title_field.' FROM '.$this->TableName.'
LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON
('.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$this->TableName.'.ResourceId)
WHERE ('.TABLE_PREFIX.'CategoryItems.CategoryId = '.$cat_id.') AND '.
$title_field.' = '.$this->Conn->qstr($new_name);
$res = $this->Conn->GetOne($query);
$original_checked = true;
} while ($res !== false);
$this->SetDBField($title_field, $new_name);
}
function MoveToCat($cat_id=null)
{
// $this->NameCopy();
$cat_id = $this->Application->GetVar('m_cat_id');
// check if the product already exists in destination cat
$query = 'SELECT PrimaryCat FROM '.TABLE_PREFIX.'CategoryItems
WHERE CategoryId = '.$cat_id.' AND ItemResourceId = '.$this->GetDBField('ResourceId');
// if it's not found is_primary will be FALSE, if it's found but not primary it will be int 0
$is_primary = $this->Conn->GetOne($query);
$exists = $is_primary !== false;
if ($exists) { // if the Product already exists in destination category
if ($is_primary) return; // do nothing when we paste to primary
// if it's not primary - delete it from destination category,
// as we will move it from current primary below
$query = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems
WHERE ItemResourceId = '.$this->GetDBField('ResourceId').' AND CategoryId = '.$cat_id;
$this->Conn->Query($query);
}
$query = 'UPDATE '.TABLE_PREFIX.'CategoryItems SET CategoryId = '.$cat_id.
' WHERE ItemResourceId = '.$this->GetDBField('ResourceId').' AND PrimaryCat = 1';
$this->Conn->Query($query);
$this->Update();
}
// We need to delete CategoryItems record when deleting product
function Delete($id=null)
{
if( isset($id) ) {
$this->setID($id);
}
$this->Load($this->GetID());
$ret = parent::Delete();
if ($ret) {
$query = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE ItemResourceId = '.$this->GetDBField('ResourceId');
$this->Conn->Query($query);
}
return $ret;
}
/**
* Deletes item from categories
*
* @param Array $delete_category_ids
* @author Alex
*/
function DeleteFromCategories($delete_category_ids)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); // because item was loaded before by ResourceId
$ci_table = $this->Application->getUnitOption('ci', 'TableName');
$resource_id = $this->GetDBField('ResourceId');
$item_cats_sql = 'SELECT CategoryId FROM %s WHERE ItemResourceId = %s';
$delete_category_items_sql = 'DELETE FROM %s WHERE ItemResourceId = %s AND CategoryId IN (%s)';
$category_ids = $this->Conn->GetCol( sprintf($item_cats_sql, $ci_table, $resource_id) );
$cats_left = array_diff($category_ids, $delete_category_ids);
if(!$cats_left)
{
$sql = 'SELECT %s FROM %s WHERE ResourceId = %s';
$ids = $this->Conn->GetCol( sprintf($sql, $id_field, $this->TableName, $resource_id) );
$temp =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->DeleteItems($this->Prefix, $this->Special, $ids);
}
else
{
$this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids) ) );
$sql = 'SELECT CategoryId FROM %s WHERE PrimaryCat = 1 AND ItemResourceId = %s';
$primary_cat_id = $this->Conn->GetCol( sprintf($sql, $ci_table, $resource_id) );
if( count($primary_cat_id) == 0 )
{
$sql = 'UPDATE %s SET PrimaryCat = 1 WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
$this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id ) );
}
}
}
function SetCustomField($field, $value)
{
$cf_id = getArrayValue($this->CustomFields, $field);
if(!$cf_id) return false;
$data_table = TABLE_PREFIX.'CustomMetaData';
$sql = 'SELECT CustomDataId FROM '.$data_table.' WHERE CustomFieldId = %s AND ResourceId = %s';
$data_id = (int)$this->Conn->GetOne( sprintf($sql, $cf_id, $this->GetDBField('ResourceId') ) );
$lang_id = $this->Application->GetVar('lang.current_id');
$sql = 'REPLACE INTO '.$data_table.'(CustomDataId,ResourceId,CustomFieldId,Value,l'.$lang_id.'_Value) VALUES (%1$s,%2$s,%3$s,%4$s,%4$s)';
$this->Conn->Query( sprintf($sql, $data_id, $this->GetDBField('ResourceId'), $cf_id, $this->Conn->qstr($value) ) );
}
/**
* replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
*
* @param string $string
* @return string
*/
function stripDisallowed($string)
{
$not_allowed = Array( ' ', '\\', '/', ':', '*', '?', '"', '<', '>', '|', '`',
'~', '!', '@', '#', '$', '%', '^', '&', '(', ')', '~',
'+', '=', '-', '{', '}', ']', '[', "'", ';', '.', ',');
$string = str_replace($not_allowed, '_', $string);
$string = preg_replace('/(_+)/', '_', $string);
$string = $this->checkAutoFilename($string);
return $string;
}
function checkAutoFilename($filename)
{
if(!$filename) return $filename;
$item_id = !$this->GetID() ? 0 : $this->GetID();
// check temp table
$sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE Filename = '.$this->Conn->qstr($filename);
$found_temp_ids = $this->Conn->GetCol($sql_temp);
// check live table
$sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename);
$found_live_ids = $this->Conn->GetCol($sql_live);
$found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) );
$has_page = preg_match('/(.*)_([\d]+)([a-z]*)$/', $filename, $rets);
$duplicates_found = (count($found_item_ids) > 1) || ($found_item_ids && $found_item_ids[0] != $item_id);
if ($duplicates_found || $has_page) // other category has same filename as ours OR we have filename, that ends with _number
{
$append = $duplicates_found ? '_a' : '';
if($has_page)
{
$filename = $rets[1].'_'.$rets[2];
$append = $rets[3] ? $rets[3] : '_a';
}
// check live & temp table
$sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')';
$sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')';
while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 ||
$this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 )
{
if (substr($append, -1) == 'z') $append .= 'a';
$append = substr($append, 0, strlen($append) - 1) . chr( ord( substr($append, -1) ) + 1 );
}
return $filename.$append;
}
return $filename;
}
/**
* Generate item's filename based on it's title field value
*
* @return string
*/
function generateFilename()
{
if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false;
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
$name = $this->stripDisallowed( $this->GetDBField($title_field) );
if ( $name != $this->GetDBField('Filename') ) $this->SetDBField('Filename', $name);
}
+
+ /**
+ * Check if value is set for required field
+ *
+ * @param string $field field name
+ * @param Array $params field options from config
+ * @return bool
+ * @access private
+ */
+ function ValidateRequired($field, $params)
+ {
+ $res = true;
+ $error_field = isset($params['error_field']) ? $params['error_field'] : $field;
+ if ( getArrayValue($params,'required') )
+ {
+ if (getArrayValue($params, 'formatter') == 'kUploadFormatter')
+ {
+ $value = $this->GetDBField($field);
+ $res = is_array($value) && $value['size'] ? true : false;
+ }
+ else {
+ $res = ( (string) $this->FieldValues[$field] != '');
+ }
+ }
+ if (!$res) $this->FieldErrors[$error_field]['pseudo'] = 'required';
+ return $res;
+ }
+
+ /**
+ * Adds item to other category
+ *
+ * @param int $category_id
+ * @param bool $is_primary
+ */
+ function assignToCategory($category_id, $is_primary = false)
+ {
+ $check_sql = ' SELECT CategoryId
+ FROM '.TABLE_PREFIX.'CategoryItems
+ WHERE (ItemResourceId = '.$this->GetDBField('ResourceId').') AND (PrimaryCat = 1)';
+ $primary_category_id = $this->Conn->GetOne($check_sql);
+ if (!$primary_category_id) $is_primary = true;
+
+ if ($primary_category_id == $category_id) return ;
+
+ $sql = 'INSERT INTO '.TABLE_PREFIX.'CategoryItems (CategoryId,ItemResourceId,PrimaryCat) VALUES (%s,%s,%s)';
+ $this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId'), $is_primary ? 1 : 0) );
+ }
+
+ /**
+ * Removes item from category specified
+ *
+ * @param int $category_id
+ */
+ function removeFromCategory($category_id)
+ {
+ $sql = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
+ $this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId')) );
+ }
+
+ /**
+ * Returns list of columns, that could exist in imported file
+ *
+ * @return Array
+ */
+ function getPossibleExportColumns()
+ {
+ static $columns = null;
+ if (!is_array($columns)) {
+ $columns = array_merge($this->Fields['AvailableColumns']['options'], $this->Fields['ExportColumns']['options']);
+ }
+ return $columns;
+ }
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/cat_dbitem.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.18
\ No newline at end of property
+1.19
\ No newline at end of property
Index: trunk/core/units/general/cat_dbitem_export.php
===================================================================
--- trunk/core/units/general/cat_dbitem_export.php (nonexistent)
+++ trunk/core/units/general/cat_dbitem_export.php (revision 3543)
@@ -0,0 +1,848 @@
+<?php
+
+ define('EXPORT_STEP', 200); // export by 200 items (e.g. links)
+ define('IMPORT_CHUNK', 50120); // 5 KB
+
+ class kCatDBItemExportHelper extends kHelper {
+
+
+ var $cache = Array();
+
+ var $exportFields = Array();
+
+ /**
+ * Export options
+ *
+ * @var Array
+ */
+ var $exportOptions = Array();
+
+ /**
+ * If we have custom fields in export
+ *
+ * @var unknown_type
+ */
+ var $hasCustomFields = false;
+
+ /**
+ * Custom field values for last item beeing exported
+ *
+ * @var Array
+ */
+ var $customValues = 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;
+
+ /**
+ * 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)
+ {
+// if (!isset($this->cache[$type])) $this->cache[$type] = Array();
+ $this->cache[$type][$key] = $value;
+ }
+
+ /**
+ * Fill required fields with dummy values
+ *
+ * @param kEvent $event
+ */
+ function fillRequiredFields(&$event)
+ {
+ $object =& $event->getObject();
+
+ $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;
+
+ $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);
+ }
+ $object->SetDBField($field_name, isset($sample_value) && $sample_value ? $sample_value : 'dummy');
+ }
+ }
+
+ /**
+ * 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);
+
+ $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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+
+ $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;
+ }
+
+ // 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();
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns filename to read import data from
+ *
+ * @return string
+ */
+ function getImportFilename()
+ {
+ if ($this->exportOptions['ImportSource'] == 1)
+ {
+ $ret = $this->exportOptions['ImportFilename']['name'];
+ }
+ 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');
+ }
+ }
+
+ /**
+ * 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
+ $sql = 'SELECT item_table.*, ci.CategoryId
+ 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 ';
+
+ 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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ $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 ($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) );
+ $this->exportOptions['has_custom_fields'] = $this->scanCustomFields();
+ }
+
+ $this->hasCustomFields = $this->exportOptions['has_custom_fields'];
+
+ // 2. export data
+ $records = $this->Conn->Query( $this->getExportSQL() );
+ $records_exported = 0;
+ foreach ($records as $record_info) {
+ $this->curItem->SetDBFieldsFromHash($record_info);
+ if ($this->hasCustomFields)
+ {
+ $this->loadItemCustomFields();
+ }
+
+ $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->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($this->exportOptions) );
+
+ 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]);
+ }
+
+ /**
+ * 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 = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ }
+
+ $this->curItem =& $event->getObject( Array('skip_autoload' => true) );
+
+ $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->cache['new_ids'] = $this->exportOptions['new_ids_hash'];
+ }
+ $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)) {
+ $this->customValues = Array();
+ $data = $this->readRecord();
+ if ($data) {
+ foreach ($data as $field_index => $field_value) {
+ $this->setFieldValue($field_index, $field_value);
+ }
+ $this->curItem->setID( $this->curItem->GetDBField($this->curItem->IDField) );
+ $this->processCurrentItem($event);
+ }
+ $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->exportOptions['new_ids_hash'] = getArrayValue($this->cache, 'new_ids');
+ $this->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($this->exportOptions) );
+
+ return $this->exportOptions;
+ }
+
+ function setFieldValue($field_index, $value)
+ {
+ $field_name = $this->exportFields[$field_index];
+
+ if (substr($field_name, 0, 7) == 'Custom_') {
+ $field_name = substr($field_name, 7);
+ $this->customValues[$field_name] = $value;
+ }
+ elseif ($field_name == 'CategoryPath') {
+ $this->curItem->CategoryPath = explode($this->exportOptions['CategorySeparator'], $value);
+ }
+ elseif (substr($field_name, 0, 8) == 'Category') {
+ $this->curItem->CategoryPath[ (int)substr($field_name, 8) ] = $value;
+ }
+ else {
+ $this->curItem->SetField($field_name, $value);
+ }
+ }
+
+ /**
+ * Returns temporary items for import procedures
+ *
+ * @param kEvent $event
+ * @return kCatDBItem
+ */
+ function &getTempItem(&$event)
+ {
+ return $this->Application->recallObject($event->Prefix.'.-tmpitem', $event->Prefix, Array('skip_autoload' => true));
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function processCurrentItem(&$event)
+ {
+ $tmp_item =& $this->getTempItem($event);
+
+ // create/update categories
+ $backup_category_id = $this->Application->GetVar('m_cat_id');
+
+ foreach ($this->curItem->CategoryPath as $category_name) {
+ if (!$category_name) continue;
+ $category_id = $this->getFromCache('category_names', $category_name);
+ 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 (ParentPath LIKE "'.$parent_path.'%")';
+ $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,
+ );
+ $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_name, $category_id);
+ }
+ }
+ else {
+ $this->addToCache('category_names', $category_name, $category_id);
+ }
+ }
+
+ if ($category_id) {
+ $this->Application->SetVar('m_cat_id', $category_id);
+ }
+ }
+
+ // create main record
+ $save_method = 'Create';
+ if ($this->exportOptions['ReplaceDuplicates']) {
+ if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
+ $load_keys = Array($this->curItem->IDField => $this->curItem->GetID());
+ }
+ else {
+ $key_fields = explode('|', substr($this->exportOptions['DuplicateCheckFields']) );
+ foreach ($key_fields as $key_field) {
+ $load_keys[$key_field] = $this->curItem->GetDBField($key_field);
+ }
+ }
+
+ $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', $where_clause);
+ if (!$item_id) {
+ $parent_path = $this->getParentPath($category_id);
+ $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 (c.ParentPath LIKE "'.$parent_path.'%") AND '.$where_clause;
+ $item_id = $this->Conn->GetOne($sql);
+ }
+ $save_method = $tmp_item->Load($item_id) ? 'Update' : 'Create';
+ }
+
+ $resource_id = $tmp_item->isLoaded() ? $tmp_item->GetDBField('ResourceId') : 0;
+ $tmp_item->SetDBFieldsFromHash($this->curItem->FieldValues);
+ if( ($save_method == 'Update') && $resource_id ) {
+ $tmp_item->SetDBField('ResourceId', $resource_id);
+ }
+
+ if (!$tmp_item->$save_method()) return false;
+
+ if ( ($save_method == 'Create') && $this->exportOptions['ReplaceDuplicates'] ) {
+ // map new id to old id
+ $this->addToCache('new_ids', $where_clause, $tmp_item->GetID() );
+ }
+
+ // set custom fields
+ foreach ($this->customValues as $custom_field => $custom_value) {
+ if (($save_method == 'Create') && !$custom_value) continue;
+ $tmp_item->SetCustomField($custom_field, $custom_value);
+ }
+
+ // assign item to categories
+ $tmp_item->assignToCategory($category_id, false);
+
+ $this->Application->SetVar('m_cat_id', $backup_category_id);
+ return true;
+ }
+
+ /**
+ * 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 loadItemCustomFields()
+ {
+ $sql = 'SELECT meta_data.Value, cf.FieldName
+ FROM '.TABLE_PREFIX.'CustomMetaData meta_data
+ LEFT JOIN '.TABLE_PREFIX.'CustomField cf ON cf.CustomFieldId = meta_data.CustomFieldId
+ WHERE meta_data.ResourceId = '.$this->curItem->GetDBField('ResourceId');
+ $this->customValues = $this->Conn->GetCol($sql, 'FieldName');
+ }
+
+ function getFileExtension()
+ {
+ return $this->exportOptions['ExportFormat'] == 1 ? 'csv' : 'xml';
+ }
+
+ function getLineSeparator($option = 'LineEndings')
+ {
+ return $this->exportOptions[$option] == 1 ? "\r\n" : "\n";
+ }
+
+ function scanCustomFields()
+ {
+ $ret = false;
+ $export_fields = $this->exportOptions['ExportColumns'];
+ foreach ($export_fields as $field)
+ {
+ if (substr($field, 0, 10) == '__CUSTOM__')
+ {
+ $ret = true;
+ break;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * 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();
+ }
+ 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 = substr($field, 10, strlen($field) );
+ $ret = isset($this->customValues[$field]) ? $this->customValues[$field] : '';
+ }
+ elseif (substr($field, 0, 12) == '__CATEGORY__')
+ {
+ return $this->getCategoryPath();
+ }
+ 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()
+ {
+ if ($this->exportOptions['CategoryFormat'] == 1)
+ {
+ // category path in one field
+ return Array('CategoryPath');
+ }
+ else
+ {
+ // category path in separated fields
+ $category_count = $this->getMaxCategoryLevel();
+
+ $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 = explode('>', $category_path);
+
+ if ($this->exportOptions['IsBaseCategory'] ) {
+ $i = $this->exportOptions['BaseLevel'];
+ while ($i > 0) {
+ array_shift($category_path);
+ $i--;
+ }
+ }
+
+ if ($this->exportOptions['CategoryFormat'] == 1) {
+ // category path in single field
+ $category_path = Array( implode($this->exportOptions['CategorySeparator'], $category_path) );
+ }
+ else {
+ // category path in separated fields
+ $category_count = $this->getMaxCategoryLevel();
+ $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']);
+ }
+ }
+
+?>
Property changes on: trunk/core/units/general/cat_dbitem_export.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/core/units/general/cat_tag_processor.php
===================================================================
--- trunk/core/units/general/cat_tag_processor.php (revision 3542)
+++ trunk/core/units/general/cat_tag_processor.php (revision 3543)
@@ -1,28 +1,80 @@
<?php
class kCatDBTagProcessor extends kDBTagProcessor {
function ItemIcon($params)
{
$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$icons =& $grids[ $params['grid'] ]['Icons'];
$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
if(!$status_fields) return $icons['default'];
$value = $object->GetDBField($status_fields[0]); // sets base status icon
if($value == STATUS_ACTIVE)
{
if( $object->GetDBField('IsPop') ) $value = 'POP';
if( $object->GetDBField('IsHot') ) $value = 'HOT';
if( $object->GetDBField('IsNew') ) $value = 'NEW';
if( $object->GetDBField('EditorsPick') ) $value = 'PICK';
}
return isset($icons[$value]) ? $icons[$value] : $icons['default'];
}
+
+ /**
+ * Returns path where exported category items should be saved
+ *
+ * @param Array $params
+ */
+ function ExportPath($params)
+ {
+ $ret = EXPORT_PATH.'/';
+
+ if( getArrayValue($params, 'as_url') )
+ {
+ $ret = str_replace( FULL_PATH.'/', $this->Application->BaseURL(), $ret);
+ }
+
+ $export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial().'_options'));
+ $ret .= $export_options['ExportFilename'].'.'.($export_options['ExportFormat'] == 1 ? 'csv' : 'xml');
+
+ return $ret;
+ }
+
+ function CategoryPath($params)
+ {
+ if (!isset($params['cat_id']))
+ {
+ $params['cat_id'] = $this->Application->RecallVar($params['session_var'], 0);
+ }
+
+ $block_params['separator'] = $params['separator'];
+
+ if($params['cat_id'] == 0)
+ {
+ $block_params['name'] = $params['rootcatblock'];
+ return $this->Application->ParseBlock($block_params);
+ }
+ else
+ {
+ $cat_object =& $this->Application->recallObject('c', 'c_List');
+ $sql = 'SELECT CategoryId, ParentId, Name FROM '.$cat_object->TableName.' WHERE CategoryId = '.$params['cat_id'];
+ $res = $this->Conn->GetRow($sql);
+
+ $block_params['name'] = $params['block'];
+ $block_params['cat_name'] = $res['Name'];
+ $block_params['cat_id'] = $res['CategoryId'];
+
+ $next_params['separator'] = $params['separator'];
+ $next_params['rootcatblock'] = $params['rootcatblock'];
+ $next_params['block'] = $params['block'];
+ $next_params['cat_id'] = $res['ParentId'];
+ return $this->CategoryPath($next_params).$this->Application->ParseBlock($block_params);
+ }
+ }
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/cat_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property
Index: trunk/core/units/general/cat_event_handler.php
===================================================================
--- trunk/core/units/general/cat_event_handler.php (revision 3542)
+++ trunk/core/units/general/cat_event_handler.php (revision 3543)
@@ -1,1011 +1,1385 @@
<?php
$application =& kApplication::Instance();
$application->Factory->includeClassFile('kDBEventHandler');
class kCatDBEventHandler extends InpDBEventHandler {
function OnCopy(&$event)
{
$object = $event->getObject();
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard', implode(',', $ids));
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard_mode', 'copy');
$this->Application->StoreVar('ClipBoard', 'COPY-0.'.$object->TableName.'.ResourceId=0');
$event->redirect_params = Array('opener' => 's', 'pass_events'=>true); //do not go up - STAY
}
function OnCut(&$event)
{
$object = $event->getObject();
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard', implode(',', $ids));
$this->Application->StoreVar($event->getPrefixSpecial().'_clipboard_mode', 'cut');
$this->Application->StoreVar('ClipBoard', 'CUT-0.'.$object->TableName.'.ResourceId=0');
$event->redirect_params = Array('opener' => 's', 'pass_events'=>true); //do not go up - STAY
}
function OnPaste(&$event)
{
$ids = $this->Application->RecallVar($event->getPrefixSpecial().'_clipboard');
if ($ids == '') {
$event->redirect = false;
return;
}
//recalling by different name, because we may get kDBList, if we recall just by prefix
$object =& $this->Application->recallObject($event->getPrefixSpecial().'.item', $event->Prefix);
$this->prepareObject($object, $event);
if ($this->Application->RecallVar($event->getPrefixSpecial().'_clipboard_mode') == 'copy') {
$ids_arr = explode(',', $ids);
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if($ids_arr)
{
$temp->CloneItems($event->Prefix, $event->Special, $ids_arr);
}
}
else { // mode == cut
$ids_arr = explode(',', $ids);
foreach ($ids_arr as $id) {
$object->Load($id);
$object->MoveToCat();
}
}
$event->status = erSUCCESS;
}
/**
* Occurs when pasting category
*
* @param kEvent $event
*/
function OnCatPaste(&$event)
{
$inp_clipboard = $this->Application->RecallVar('ClipBoard');
$inp_clipboard = explode('-', $inp_clipboard, 2);
if($inp_clipboard[0] == 'COPY')
{
$saved_cat_id = $this->Application->GetVar('m_cat_id');
$cat_ids = $event->getEventParam('cat_ids');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$ids_sql = 'SELECT '.$id_field.' FROM '.$table.' WHERE ResourceId IN (%s)';
$resource_ids_sql = 'SELECT ItemResourceId FROM '.TABLE_PREFIX.'CategoryItems WHERE CategoryId = %s AND PrimaryCat = 1';
$this->Application->setUnitOption($event->Prefix,'AutoLoad', false);
$object =& $this->Application->recallObject($event->Prefix.'.item', $event->Prefix);
foreach($cat_ids as $source_cat => $dest_cat)
{
$item_resource_ids = $this->Conn->GetCol( sprintf($resource_ids_sql, $source_cat) );
if(!$item_resource_ids) continue;
$this->Application->SetVar('m_cat_id', $dest_cat);
$item_ids = $this->Conn->GetCol( sprintf($ids_sql, implode(',', $item_resource_ids) ) );
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if($item_ids) $temp->CloneItems($event->Prefix, $event->Special, $item_ids);
}
$this->Application->setUnitOption($event->Prefix,'AutoLoad', true);
$this->Application->SetVar('m_cat_id', $saved_cat_id);
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnPreSaveAndOpenTranslator(&$event)
{
$this->Application->SetVar('allow_translation', true);
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
// $url = $this->Application->HREF($t, '', Array('pass'=>'all', $event->getPrefixSpecial(true).'_id' => $object->GetId()));
// $field = $this->Application->GetVar('translator_field');
$cf_id = $this->Application->GetVar('translator_cf_id');
if($cf_id)
{
$cv =& $this->Application->recallObject('cv.-item', null, Array('skip_autoload' => true) );
$load_params = Array('CustomFieldId' => $cf_id, 'ResourceId'=> $object->GetDBField('ResourceId') );
if( !$cv->Load($load_params) )
{
$cv->SetFieldsFromHash($load_params);
$cv->Create();
}
$this->Application->SetVar('cv_id', $cv->getID() );
}
$event->redirect = $this->Application->GetVar('translator_t');
$event->redirect_params = Array('pass'=>'all,trans,'.$this->Application->GetVar('translator_prefixes'),
$event->getPrefixSpecial(true).'_id' => $object->GetId(),
'trans_event'=>'OnLoad',
'trans_prefix'=> $this->Application->GetVar('translator_prefixes'),
'trans_field'=>$this->Application->GetVar('translator_field'),
'trans_multi_line'=>$this->Application->GetVar('translator_multi_line'),
);
// 1. SAVE LAST TEMPLATE TO SESSION
$last_template = $this->Application->RecallVar('last_template');
preg_match('/index4\.php\|'.$this->Application->GetSID().'-(.*):/U', $last_template, $rets);
// $this->Application->StoreVar('return_template', $rets[1]);
$this->Application->StoreVar('return_template', $this->Application->GetVar('t'));
//$after_script = "openTranslator('".$event->getPrefixSpecial()."', '".$field."', '".$url."', '".$wnd_name."')";
}
// $this->Application->SetVar('after_script', $after_script);
// $event->redirect = false;
}
/**
* Apply scope clause
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
if ($event->Special != 'showall') {
if ( $event->getEventParam('parent_cat_id') ) {
$parent_cat_id = $event->getEventParam('parent_cat_id');
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
if ((string) $parent_cat_id != 'any') {
if ($event->getEventParam('recursive')) {
$current_path = $this->Conn->GetOne('SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId='.$parent_cat_id);
$subcats = $this->Conn->GetCol('SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ParentPath LIKE "'.$current_path.'%" ');
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId IN ('.implode(', ', $subcats).')');
}
else {
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId = '.$parent_cat_id );
}
}
}
else {
$object->addFilter('primary_filter', 'PrimaryCat = 1');
}
$view_perm = 1;
$object->addFilter('perm_filter', 'perm.PermId = '.$view_perm);
if ( !$this->Application->IsAdmin() )
{
$groups = explode( ',', $this->Application->RecallVar('UserGroups') );
foreach($groups as $group)
{
$view_filters[] = 'FIND_IN_SET('.$group.', perm.acl) || ((NOT FIND_IN_SET('.$group.',perm.dacl)) AND perm.acl=\'\')';
}
$view_filter = implode(' OR ', $view_filters);
$object->addFilter('perm_filter2', $view_filter);
$object->addFilter('status_filter', $object->TableName.'.Status = 1');
}
/*$list_type = $event->getEventParam('ListType');
switch($list_type)
{
case 'favorites':
$fav_table = $this->Application->getUnitOption('fav','TableName');
$user_id =& $this->Application->GetVar('u_id');
$sql = 'SELECT DISTINCT f.ResourceId
FROM '.$fav_table.' f
LEFT JOIN '.$object->TableName.' p ON p.ResourceId = f.ResourceId
WHERE f.PortalUserId = '.$user_id;
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.PrimaryCat = 1');
$object->addFilter('favorites_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
case 'search':
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = ' SELECT DISTINCT ResourceId
FROM '.$search_results_table.'
WHERE ItemType=11';
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('search_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
} */
}
/**
* Adds calculates fields for item statuses
*
* @param kCatDBItem $object
* @param kEvent $event
*/
- function PrepareObject(&$object, &$event)
+ function prepareObject(&$object, &$event)
{
+ $this->prepareItemStatuses($event);
+
+ if ($event->Special == 'export' || $event->Special == 'import')
+ {
+ $this->prepareExportColumns($event);
+ }
+ }
+ /**
+ * Creates calculated fields for all item statuses based on config settings
+ *
+ * @param kEvent $event
+ */
+ function prepareItemStatuses(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if($new_days_var)
{
$object->addCalculatedField('IsNew', ' IF(%1$s.NewItem = 2,
IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0),
%1$s.NewItem
)');
}
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_limit_var)
{
$sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = "'.$hot_limit_var.'"';
$hot_limit = $this->Conn->GetOne($sql);
if($hot_limit === false) $hot_limit = $this->CalculateHotLimit($event);
$object->addCalculatedField('IsHot', ' IF(%1$s.HotItem = 2,
IF(%1$s.Hits >= '.$hot_limit.', 1, 0),
%1$s.HotItem
)');
}
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if($votes2pop_var && $rating2pop_var)
{
$object->addCalculatedField('IsPop', ' IF(%1$s.PopItem = 2,
IF(%1$s.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND %1$s.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0),
%1$s.PopItem)');
}
}
-
+
function CalculateHotLimit(&$event)
{
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
$hot_count_var = getArrayValue($property_mappings, 'HotCount');
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_count_var && $hot_limit_var)
{
$last_hot = $this->Application->ConfigValue($hot_count_var) - 1;
$sql = 'SELECT Hits FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
ORDER BY Hits DESC
LIMIT '.$last_hot.', 1';
$res = $this->Conn->GetCol($sql);
$hot_limit = (double)array_shift($res);
$this->Conn->Query('REPLACE INTO '.TABLE_PREFIX.'Cache VALUES ("'.$hot_limit_var.'", "'.$hot_limit.'", '.adodb_mktime().')');
return $hot_limit;
}
return 0;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$object =& $event->getObject();
if( $this->Application->IsAdmin() && ($this->Application->GetVar('Hits_original') !== false) &&
floor($this->Application->GetVar('Hits_original')) != $object->GetDBField('Hits') )
{
$sql = 'SELECT MAX(Hits) FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE FLOOR(Hits) = '.$object->GetDBField('Hits');
$hits = ( $res = $this->Conn->GetOne($sql) ) ? $res + 0.000001 : $object->GetDBField('Hits');
$object->SetDBField('Hits', $hits);
}
}
function OnAfterItemUpdate(&$event)
{
$this->CalculateHotLimit($event);
}
/**
* Makes simple search for products
* based on keywords string
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnSimpleSearch(&$event)
{
if($this->Application->GetVar('INPORTAL_ON') && !($this->Application->GetVar('Action') == 'm_simple_search'))
{
return;
}
$event->redirect = false;
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$keywords = trim($this->Application->GetVar('keywords'));
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$keywords = unhtmlentities($keywords);
}
$query_object =& $this->Application->recallObject('HTTPQuery');
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if(!isset($query_object->Get['keywords']) &&
!isset($query_object->Post['keywords']) &&
$this->Conn->Query($sql))
{
return; // used when navigating by pages or changing sorting in search results
}
if(!$keywords || strlen($keywords) < $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$this->Application->SetVar('keywords_too_short', 1);
return; // if no or too short keyword entered, doing nothing
}
$this->Application->StoreVar('keywords', $keywords);
$keywords = strtr($keywords, Array('%' => '\\%', '_' => '\\_'));
$event->setPseudoClass('_List');
$object =& $event->getObject();
$this->Application->SetVar($event->getPrefixSpecial().'_Page', 1);
$lang = $this->Application->GetVar('m_lang');
$product_table = $this->Application->getUnitOption('p', 'TableName');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="In-Commerce"
AND SimpleSearch=1';
$search_config = $this->Conn->Query($sql, 'FieldName');
$field_list = array_keys($search_config);
$join_clauses = Array();
// field processing
$weight_sum = 0;
foreach($field_list as $key => $field)
{
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$search_config[$field]['TableName'];
$weight_sum += $search_config[$field]['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if($options['formatter'] == 'kMultiLanguage')
{
$field_list[$key] = 'l'.$lang.'_'.$field;
}
// processing fields from other tables
if($foreign_field = $search_config[$field]['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
unset($field_list[$key]);
continue; // ignoring having type clauses in simple search
/*$user_object =& $this->Application->recallObject('u');
$user_groups = $user_object->GetDBField('PortalUserId') ?
implode(',', $this->Conn->GetCol(' SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE PortalUserId='.$user_object->GetDBField('PortalUserId'))) : 0;
$having_list[$key] = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$join_clauses[] = $join_clause;*/
}
else
{
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
$field_list[$key] = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{LocalTable}', $product_table, $join_clause);
if($search_config[$field]['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$search_config[$field]['CustomFieldId'];
}
$join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
$field_list[$key] = $local_table.'.'.$field_list[$key];
}
}
// keyword string processing
$normal_keywords = Array();
$plus_keywords = Array();
$minus_keywords = Array();
for($i = 0; $i < strlen($keywords); $i++)
{
if(substr($keywords, $i, 1) == ' ') continue;
$extra_skip = 0;
switch(substr($keywords, $i, 1))
{
case '+':
if(substr($keywords, $i + 1, 1) == '"')
{
$keyword_start = $i + 2;
$keyword_end = strpos($keywords, '"', $i + 2);
$extra_skip = 2;
}
else
{
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, ' ', $i + 1);
$extra_skip = 0;
}
$target_array =& $plus_keywords;
break;
case '-':
if(substr($keywords, $i + 1, 1) == '"')
{
$keyword_start = $i + 2;
$keyword_end = strpos($keywords, '"', $i + 2);
$extra_skip = 2;
}
else
{
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, ' ', $i + 1);
$extra_skip = 0;
}
$target_array =& $minus_keywords;
break;
case '"':
$keyword_start = $i + 1;
$keyword_end = strpos($keywords, '"', $i + 1);
$extra_skip = 1;
$target_array =& $normal_keywords;
break;
default:
$keyword_start = $i;
$keyword_end = strpos($keywords, ' ', $i + 1);
$target_array =& $normal_keywords;
}
if($keyword_end === false)
{
$keyword_end = strlen($keywords);
}
$keyword_length = $keyword_end - $keyword_start;
$keyword = substr($keywords, $keyword_start, $keyword_length);
if(strlen($keyword) >= $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$target_array[] = addcslashes($keyword, '"');
}
$i += $keyword_length + $extra_skip;
}
// preparing conditions
$normal_conditions = Array();
$plus_conditions = Array();
$minus_conditions = Array();
foreach($normal_keywords as $keyword)
{
$normal_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $field_list).' LIKE "%'.$keyword.'%"';
}
foreach($plus_keywords as $keyword)
{
$plus_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $field_list).' LIKE "%'.$keyword.'%"';
}
foreach($minus_keywords as $keyword)
{
foreach($field_list as $field)
{
$condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL';
}
$minus_conditions[] = '('.implode(') AND (', $condition).')';
}
// building where clause
if($normal_conditions)
{
$where_clause = '('.implode(') OR (', $normal_conditions).')';
}
else
{
$where_clause = '1';
}
if($plus_conditions)
{
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $plus_conditions).')';
}
if($minus_conditions)
{
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $minus_conditions).')';
}
$where_clause = $where_clause.' AND '.$product_table.'.Status=1';
if($this->Application->GetVar('Action') == 'm_simple_subsearch') // subsearch, In-portal
{
if( $event->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$product_table.'.ResourceId IN ('.implode(',', $event->specificParams['ResultIds']).')';
}
}
if( $event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild' ) // subsearch, k4
{
if( $event->MasterEvent->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$product_table.'.ResourceId IN ('.implode(',', $event->MasterEvent->getEventParam('ResultIds')).')';
}
}
// building having clause
// making relevance clause
$positive_words = array_merge($normal_keywords, $plus_keywords);
$this->Application->StoreVar('highlight_keywords', serialize($positive_words));
$revelance_parts = Array();
reset($search_config);
foreach($field_list as $field)
{
$config_elem = each($search_config);
$weight = $search_config[$field]['Priority'];
$revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)';
foreach($positive_words as $keyword)
{
$revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$config_elem['value']['Priority'].', 0)';
}
}
$rel_keywords = $this->Application->ConfigValue('SearchRel_DefaultKeyword_products') / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_DefaultPop_products') / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_DefaultRating_products') / 100;
$relevance_clause = '('.implode(' + ', $revelance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
// building final search query
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table); // erase old search table if clean k4 event
}
if($this->Conn->Query('SHOW TABLES LIKE "'.$search_table.'"'))
{
$select_intro = 'INSERT INTO '.$search_table.' (Relevance, ItemId, ResourceId, ItemType, EdPick) ';
}
else
{
$select_intro = 'CREATE TABLE '.$search_table.' AS ';
}
$sql = $select_intro.' SELECT '.$relevance_clause.' AS Relevance,
'.$product_table.'.ProductId AS ItemId,
'.$product_table.'.ResourceId,
11 AS ItemType,
'.$product_table.'.EditorsPick AS EdPick
FROM '.$object->TableName.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$product_table.'.ProductId';
$res = $this->Conn->Query($sql);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSubSearch(&$event)
{
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if($this->Conn->Query($sql))
{
$sql = 'SELECT DISTINCT ResourceId FROM '.$search_table;
$ids = $this->Conn->GetCol($sql);
}
$event->setEventParam('ResultIds', $ids);
$event->CallSubEvent('OnSimpleSearch');
}
/**
* Enter description here...
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnAdvancedSearch(&$event)
{
$query_object =& $this->Application->recallObject('HTTPQuery');
if(!isset($query_object->Post['andor']))
{
return; // used when navigating by pages or changing sorting in search results
}
$this->Application->RemoveVar('keywords');
$this->Application->RemoveVar('Search_Keywords');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="In-Commerce"
AND AdvancedSearch=1';
$search_config = $this->Conn->Query($sql);
$lang = $this->Application->GetVar('m_lang');
$object =& $event->getObject();
$object->SetPage(1);
$user_object =& $this->Application->recallObject('u');
$product_table = $this->Application->getUnitOption('p', 'TableName');
$keywords = $this->Application->GetVar('value');
$verbs = $this->Application->GetVar('verb');
$glues = $this->Application->GetVar('andor');
$and_conditions = Array();
$or_conditions = Array();
$and_having_conditions = Array();
$or_having_conditions = Array();
$join_clauses = Array();
$highlight_keywords = Array();
$relevance_parts = Array();
$condition_patterns = Array( 'any' => '%s LIKE %s',
'contains' => '%s LIKE %s',
'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
'is' => '%s = %s',
'isnot' => '(%1$s != %2$s OR %1$s IS NULL)');
$alias_counter = 0;
$weight_sum = 0;
// processing fields and preparing conditions
foreach($search_config as $record)
{
$field = $record['FieldName'];
$join_clause = '';
$condition_mode = 'WHERE';
// field processing
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$record['TableName'];
$weight_sum += $record['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if($options['formatter'] == 'kMultiLanguage')
{
$field_name = 'l'.$lang.'_'.$field;
}
else
{
$field_name = $field;
}
// processing fields from other tables
if($foreign_field = $record['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
$user_groups = $user_object->GetDBField('PortalUserId') ?
implode(',', $this->Conn->GetCol(' SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE PortalUserId='.$user_object->GetDBField('PortalUserId'))) : 0;
$field_name = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $record['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$condition_mode = 'HAVING';
}
else
{
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
$field_name = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $record['JoinClause']);
$join_clause = str_replace('{LocalTable}', $product_table, $join_clause);
if($record['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$record['CustomFieldId'];
}
$join_clause = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
$field_name = $local_table.'.'.$field_name;
}
$condition = '';
switch($record['FieldType'])
{
case 'text':
if( !$this->Application->GetVar('INPORTAL_ON') )
{
$keywords[$field] = unhtmlentities( $keywords[$field] );
}
if(strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$highlight_keywords[] = $keywords[$field];
if( in_array($verbs[$field], Array('any', 'contains', 'notcontains')) )
{
$keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
}
$condition = sprintf( $condition_patterns[$verbs[$field]],
$field_name,
$this->Conn->qstr( $keywords[$field] ));
}
break;
case 'boolean':
if($keywords[$field] != -1)
{
$property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
switch($field)
{
case 'HotItem':
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if($hot_limit_var)
{
$sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName="'.$hot_limit_var.'"';
$hot_limit = (int)$this->Conn->GetOne($sql);
$condition = 'IF('.$product_table.'.HotItem = 2,
IF('.$product_table.'.Hits >= '.
$hot_limit.
', 1, 0), '.$product_table.'.HotItem) = '.$keywords[$field];
}
break;
case 'PopItem':
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if($votes2pop_var && $rating2pop_var)
{
$condition = 'IF('.$product_table.'.PopItem = 2, IF('.$product_table.'.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND '.$product_table.'.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0), '.$product_table.'.PopItem) = '.$keywords[$field];
}
break;
case 'NewItem':
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if($new_days_var)
{
$condition = 'IF('.$product_table.'.NewItem = 2,
IF('.$product_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0), '.$product_table.'.NewItem) = '.$keywords[$field];
}
break;
case 'EditorsPick':
$condition = $product_table.'.EditorsPick = '.$keywords[$field];
break;
}
}
break;
case 'range':
$range_conditions = Array();
if($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from']))
{
$range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
}
if($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to']))
{
$range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
}
if($range_conditions)
{
$condition = implode(' AND ', $range_conditions);
}
break;
case 'date':
if($keywords[$field])
{
if( in_array($keywords[$field], Array('today', 'yesterday')) )
{
$current_time = getdate();
$day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
$time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
$min_time = $time_mapping[$keywords[$field]];
}
else
{
$time_mapping = Array( 'last_week' => 604800, 'last_month' => 2628000,
'last_3_months' => 7884000, 'last_6_months' => 15768000,
'last_year' => 31536000
);
$min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
}
$condition = $field_name.' > '.$min_time;
}
break;
}
if($condition)
{
if($join_clause)
{
$join_clauses[] = $join_clause;
}
$relevance_parts[] = 'IF('.$condition.', '.$record['Priority'].', 0)';
if($glues[$field] == 1) // and
{
if($condition_mode == 'WHERE')
{
$and_conditions[] = $condition;
}
else
{
$and_having_conditions[] = $condition;
}
}
else // or
{
if($condition_mode == 'WHERE')
{
$or_conditions[] = $condition;
}
else
{
$or_having_conditions[] = $condition;
}
}
}
}
$this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords));
// making relevance clause
if($relevance_parts)
{
$rel_keywords = $this->Application->ConfigValue('SearchRel_DefaultKeyword_products') / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_DefaultPop_products') / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_DefaultRating_products') / 100;
$relevance_clause = '('.implode(' + ', $relevance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
else
{
$relevance_clause = '0';
}
// building having clause
if($or_having_conditions)
{
$and_having_conditions[] = '('.implode(' OR ', $or_having_conditions).')';
}
$having_clause = implode(' AND ', $and_having_conditions);
$having_clause = $having_clause ? ' HAVING '.$having_clause : '';
// building where clause
if($or_conditions)
{
$and_conditions[] = '('.implode(' OR ', $or_conditions).')';
}
// $and_conditions[] = $product_table.'.Status = 1';
$where_clause = implode(' AND ', $and_conditions);
if(!$where_clause)
{
if($having_clause)
{
$where_clause = '1';
}
else
{
$where_clause = '0';
$this->Application->SetVar('adv_search_error', 1);
}
}
$where_clause .= ' AND '.$product_table.'.Status = 1';
// building final search query
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$sql = ' CREATE TABLE '.$search_table.'
SELECT '.$relevance_clause.' AS Relevance,
'.$product_table.'.ProductId AS ItemId,
'.$product_table.'.ResourceId AS ResourceId,
11 AS ItemType,
'.$product_table.'.EditorsPick AS EdPick
FROM '.$product_table.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$product_table.'.ProductId'.
$having_clause;
$res = $this->Conn->Query($sql);
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page)
{
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page)
{
if( $this->Application->RewriteURLs() )
{
$page = $this->Application->GetVar($event->Prefix.'_Page');
if (!$page)
{
$page = $this->Application->RecallVar($event->Prefix.'_Page');
}
if($page) $this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
else
{
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
// $page = $this->Application->GetLinkedVar($event->getPrefixSpecial(true).'_Page', $event->getPrefixSpecial().'_Page');
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
$object->SetPage($page);
}
+
+/* === RELATED TO IMPORT/EXPORT: BEGIN === */
+
+ /**
+ * Returns module folder
+ *
+ * @param kEvent $event
+ * @return string
+ */
+ function getModuleFolder(&$event)
+ {
+ return $this->Application->getUnitOption($event->Prefix, 'ModuleFolder');
+ }
+
+ /**
+ * Shows export dialog
+ *
+ * @param kEvent $event
+ */
+ function OnExport(&$event)
+ {
+ $selected_ids = $this->Application->GetVar('linklist');
+ $selected_cats_ids = $this->Application->GetVar('export_categories');
+
+ $this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
+ $this->Application->StoreVar($event->Prefix.'_export_cats_ids', $selected_cats_ids);
+
+ $event->redirect = $this->getModuleFolder($event).'/export';
+
+ $redirect_params = Array( 'm_opener' => 'd',
+ 'index_file' => 'index4.php',
+ $this->Prefix.'.export_event' => 'OnNew',
+ 'pass' => 'all,'.$this->Prefix.'.export');
+
+ $event->setRedirectParams($redirect_params);
+ }
+
+ /**
+ * 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') );
+ }
+
+ list($item_id, $field_values) = each($items_info);
+
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ $object->SetFieldsFromHash($field_values);
+ $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->StoreVar($event->getPrefixSpecial().'_options', serialize($field_values) );
+
+ if( $export_object->verifyOptions($event) )
+ {
+ $this->doExport($event);
+ }
+ else
+ {
+ $event->status = erFAIL;
+ $event->redirect = false;
+ }
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function doExport(&$event)
+ {
+ if ($event->Name == 'OnExportBegin')
+ {
+ $done_percent = 0;
+ }
+ else {
+ $export_options = unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ $done_percent = round($export_options['start_from'] * 100 / $export_options['total_records'], 0);
+ }
+
+ $block_params = Array( 'name' => $this->getModuleFolder($event).'/'.$event->Special.'_progress',
+ 'percent_done' => $done_percent,
+ 'percent_left' => 100 - $done_percent);
+
+ $this->Application->InitParser();
+ $this->Application->setUnitOption($event->Prefix, 'AutoLoad', false);
+ echo $this->Application->ParseBlock($block_params);
+ flush();
+
+ $export_object =& $this->Application->recallObject('CatItemExportHelper');
+
+ $action_method = 'perform'.ucfirst($event->Special);
+ $field_values = $export_object->$action_method($event);
+
+ if ($field_values['start_from'] == $field_values['total_records'])
+ {
+ if ($event->Special == 'import') {
+ $this->Application->StoreVar('PermCache_UpdateRequired', 1);
+ $event->SetRedirectParam('index_file', 'category/category_maint.php');
+ }
+ else {
+ $event->redirect = $this->getModuleFolder($event).'/'.$event->Special.'_finish';
+ }
+ }
+ else {
+ $event->redirect = $this->getModuleFolder($event).'/'.$event->Special.'_progress';
+ $redirect_params = Array($event->getPrefixSpecial().'_event' => 'OnExportProgress', 'pass' => 'm,'.$event->getPrefixSpecial());
+ $event->setRedirectParams($redirect_params);
+ }
+ }
+
+ /**
+ * Next export steps
+ *
+ * @param kEvent $event
+ */
+ function OnExportProgress(&$event)
+ {
+ $this->doExport($event);
+ }
+
+ /**
+ * Sets correct available & export fields
+ *
+ * @param kEvent $event
+ */
+ function prepareExportColumns(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+
+ $available_columns = Array();
+
+ // 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
+ $fields = array_keys($object->Fields);
+ foreach ($fields as $field_name)
+ {
+ if (!$object->SkipField($field_name))
+ {
+ $available_columns[$field_name] = $field_name;
+ }
+ }
+
+ // custom fields
+ $fields = array_keys($object->CustomFields);
+ foreach ($fields as $field_name)
+ {
+ $available_columns['__CUSTOM__'.$field_name] = $field_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);
+
+ if ($event->Special == 'import')
+ {
+ $import_filenames = Array();
+
+ if ($folder_handle = opendir(EXPORT_PATH)) {
+ while (false !== ($file = readdir($folder_handle))) {
+ if ( 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);
+ }
+ }
+
+
+// ImportLocalFilename
+
+ 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;
+ }
+
+ /**
+ * Shows export dialog
+ *
+ * @param kEvent $event
+ */
+ function OnImport(&$event)
+ {
+
+ $event->redirect = $this->getModuleFolder($event).'/import';
+
+ $redirect_params = Array( 'm_opener' => 'd',
+ 'index_file' => 'index4.php',
+ $this->Prefix.'.import_event' => 'OnNew',
+ 'pass' => 'all,'.$this->Prefix.'.import');
+
+ $event->setRedirectParams($redirect_params);
+ }
+
+ /**
+ * Prepares item for import/export operations
+ *
+ * @param kEvent $event
+ */
+ function OnNew(&$event)
+ {
+ parent::OnNew($event);
+
+ if ($event->Special != 'import' && $event->Special != 'export') return ;
+ $this->setRequiredFields($event);
+ }
+
+ /**
+ * set required fields based on import or export params
+ *
+ * @param kEvent $event
+ */
+ function setRequiredFields(&$event)
+ {
+ $required_fields['common'] = Array('FieldsSeparatedBy', 'FieldsEnclosedBy', 'LineEndings', 'CategoryFormat');
+
+ $required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns');
+ $required_fields['import'] = Array('FieldTitles', 'ImportSource', 'CheckDuplicatesMethod'); // ImportFilename, ImportLocalFilename
+
+ $object =& $event->getObject();
+ 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);
+ }
+ }
+
+ /**
+ * Saves selected category as new import category
+ *
+ * @param kEvent $event
+ */
+ function OnSelectItems(&$event)
+ {
+ $items_info = $this->Application->GetVar('c');
+
+ if ($items_info)
+ {
+ $selected_categories = array_keys($items_info);
+ $cat_id = array_shift($selected_categories);
+
+ $sql = 'SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ResourceId = '.$cat_id;
+ $cat_id = $this->Conn->GetOne($sql);
+ }
+ else {
+ $cat_id = 0;
+ }
+
+ $this->Application->StoreVar('ImportCategory', $cat_id);
+ $this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 1); // not to loose import/export values on form refresh
+
+ $this->Application->SetVar($event->getPrefixSpecial().'_id', 0);
+ $this->Application->SetVar($event->getPrefixSpecial().'_event', 'OnExportBegin');
+
+ $passed = $this->Application->GetVar('passed');
+ $this->Application->SetVar('passed', $passed.','.$event->getPrefixSpecial());
+ $event->setEventParam('pass_events', true);
+
+ $this->finalizePopup($event, null, $this->getModuleFolder($event).'/'.$event->Special);
+
+ }
+
+ /**
+ * Saves Import/Export settings to session
+ *
+ * @param kEvent $event
+ */
+ function OnSaveSettings(&$event)
+ {
+ $event->redirect = false;
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if ($items_info) {
+ $this->Application->StoreVar($event->getPrefixSpecial().'_ItemsInfo', serialize($items_info));
+ }
+ }
+
+/* === RELATED TO IMPORT/EXPORT: END === */
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/cat_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.16
\ No newline at end of property
+1.17
\ No newline at end of property
Index: trunk/core/units/general/my_application.php
===================================================================
--- trunk/core/units/general/my_application.php (revision 3542)
+++ trunk/core/units/general/my_application.php (revision 3543)
@@ -1,52 +1,53 @@
<?php
class MyApplication extends kApplication {
function RegisterDefaultClasses()
{
parent::RegisterDefaultClasses();
$this->registerClass('Inp1Parser',MODULES_PATH.'/kernel/units/general/inp1_parser.php','Inp1Parser');
$this->registerClass('InpSession',MODULES_PATH.'/kernel/units/general/inp_ses_storage.php','Session');
$this->registerClass('InpSessionStorage',MODULES_PATH.'/kernel/units/general/inp_ses_storage.php','SessionStorage');
$this->registerClass('kCatDBItem',MODULES_PATH.'/kernel/units/general/cat_dbitem.php');
+ $this->registerClass('kCatDBItemExportHelper',MODULES_PATH.'/kernel/units/general/cat_dbitem_export.php', 'CatItemExportHelper');
$this->registerClass('kCatDBList',MODULES_PATH.'/kernel/units/general/cat_dblist.php');
$this->registerClass('kCatDBEventHandler',MODULES_PATH.'/kernel/units/general/cat_event_handler.php');
$this->registerClass('kCatDBTagProcessor',MODULES_PATH.'/kernel/units/general/cat_tag_processor.php');
$this->registerClass('InpDBEventHandler', MODULES_PATH.'/kernel/units/general/inp_db_event_handler.php', 'kDBEventHandler');
$this->registerClass('InpTempTablesHandler',MODULES_PATH.'/kernel/units/general/inp_temp_handler.php','kTempTablesHandler');
$this->registerClass('InpCustomFieldsHelper',MODULES_PATH.'/kernel/units/general/custom_fields.php','InpCustomFieldsHelper');
$this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper');
$this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper');
}
function getUserGroups($user_id)
{
switch($user_id)
{
case -1:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
break;
case -2:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
$user_groups .= ','.$this->ConfigValue('User_GuestGroup');
break;
default:
$sql = 'SELECT GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = '.$user_id;
$res = $this->DB->GetCol($sql);
$user_groups = Array( $this->ConfigValue('User_LoggedInGroup') );
if(is_array($res))
{
$user_groups = array_merge($user_groups, $res);
}
$user_groups = implode(',', $user_groups);
}
return $user_groups;
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/my_application.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.20
\ No newline at end of property
+1.21
\ No newline at end of property
Index: trunk/core/module_help/visits_list.txt
===================================================================
--- trunk/core/module_help/visits_list.txt (revision 3542)
+++ trunk/core/module_help/visits_list.txt (revision 3543)
@@ -1,24 +1,24 @@
-<span style="font-weight: bold;">Visits (In-portal Platform)<br/>
-<br/>
-</span>This section displays the log of all visits to your website. The visit is recorded when a user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
-The grid on this page displays the following columns:<br/>
-<ul>
- <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
- <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
- <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
- <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
-</ul>
-<br/>
-<span style="font-weight: bold;">Visits (with In-commerce installed)<br/>
-<br/>
-</span>This section displays the log of all visits to your website. The visit is recorded when user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
-The grid on this page displays the following columns:<br/>
-<ul>
- <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
- <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
- <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
- <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
- <li>Affiliate User &ndash; the username of affiliate who has referred the visitor</li>
- <li>Order Total &ndash; the total amount of the orders made during this visit</li>
- <li>Affiliate Commission &ndash; amount of affiliate commission received for the orders made during the visit</li>
+<span style="font-weight: bold;">Visits (In-portal Platform)<br/>
+<br/>
+</span>This section displays the log of all visits to your website. The visit is recorded when a user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
+The grid on this page displays the following columns:<br/>
+<ul>
+ <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
+ <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
+ <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
+ <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
+</ul>
+<br/>
+<span style="font-weight: bold;">Visits (with In-commerce installed)<br/>
+<br/>
+</span>This section displays the log of all visits to your website. The visit is recorded when user comes to your site. If the user logs in during his or her visit, the username will be updated in the visit record. If the user&rsquo;s session expires during the visit, a new visit record will be created when he or she comes back to the site. <br/>
+The grid on this page displays the following columns:<br/>
+<ul>
+ <li>Visit Date &ndash; Date and Time of the visit&rsquo;s start</li>
+ <li>IP Address &ndash; the IP address of the visitor, as identified by the web server</li>
+ <li>Referrer &ndash; the URL the visitor came from, as reported by visitor&rsquo;s browser </li>
+ <li>Username &ndash; the username of the visitor if he or she logs in during the visit</li>
+ <li>Affiliate User &ndash; the username of affiliate who has referred the visitor</li>
+ <li>Order Total &ndash; the total amount of the orders made during this visit</li>
+ <li>Affiliate Commission &ndash; amount of affiliate commission received for the orders made during the visit</li>
</ul>
\ No newline at end of file
Property changes on: trunk/core/module_help/visits_list.txt
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property

Event Timeline