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; } /** * Return type clauses for list bulding on front * * @param kEvent $event * @return Array */ function getTypeClauses(&$event) { $types = $event->getEventParam('types'); $except_types = $event->getEventParam('except'); $type_clauses = Array(); $type_clauses['pick']['include'] = '%1$s.EditorsPick = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1'; $type_clauses['pick']['except'] = '%1$s.EditorsPick! = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1'; $type_clauses['pick']['having_filter'] = false; $type_clauses['hot']['include'] = '`IsHot` = 1 AND PrimaryCat = 1'; $type_clauses['hot']['except'] = '`IsHot`! = 1 AND PrimaryCat = 1'; $type_clauses['hot']['having_filter'] = true; $type_clauses['pop']['include'] = '`IsPop` = 1 AND PrimaryCat = 1'; $type_clauses['pop']['except'] = '`IsPop`! = 1 AND PrimaryCat = 1'; $type_clauses['pop']['having_filter'] = true; $type_clauses['new']['include'] = '`IsNew` = 1 AND PrimaryCat = 1'; $type_clauses['new']['except'] = '`IsNew`! = 1 AND PrimaryCat = 1'; $type_clauses['new']['having_filter'] = true; $type_clauses['displayed']['include'] = ''; $displayed = $this->Application->GetVar($event->Prefix.'_displayed_ids'); if ($displayed) { $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $type_clauses['displayed']['except'] = '%1$s.'.$id_field.' NOT IN ('.$displayed.')'; } else { $type_clauses['displayed']['except'] = ''; } $type_clauses['displayed']['having_filter'] = false; if (strpos($types, 'search') !== false || strpos($except_types, 'search') !== false) { $event_mapping = Array( 'simple' => 'OnSimpleSearch', 'subsearch' => 'OnSubSearch', 'advanced' => 'OnAdvancedSearch'); if($this->Application->GetVar('INPORTAL_ON') && $this->Application->GetVar('Action') == 'm_simple_subsearch') { $type = 'subsearch'; } else { $type = $this->Application->GetVar('search_type') ? $this->Application->GetVar('search_type') : 'simple'; } if($keywords = $event->getEventParam('keyword_string')) // processing keyword_string param of ListProducts tag { $this->Application->SetVar('keywords', $keywords); $type = 'simple'; } $search_event = $event_mapping[$type]; $this->$search_event($event); $search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search'; $sql = 'SHOW TABLES LIKE "'.$search_table.'"'; if ( $this->Conn->Query($sql) ) { $search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table); } if ($search_res_ids) { $type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1'; $type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1'; } else { $type_clauses['search']['include'] = '0'; $type_clauses['search']['except'] = '1'; } $type_clauses['search']['having_filter'] = false; } if (strpos($types, 'related') !== false || strpos($except_types, 'related') !== false) { $related_to = $event->getEventParam('related_to'); if (!$related_to) { $related_prefix = $event->Prefix; } else { $sql = 'SELECT Prefix FROM '.TABLE_PREFIX.'ItemTypes WHERE ItemName = '.$this->Conn->qstr($related_to); $related_prefix = $this->Conn->GetOne($sql); } $rel_table = $this->Application->getUnitOption('rel', 'TableName'); $item_type = $this->Application->getUnitOption($event->Prefix, 'ItemType'); $p_item =& $this->Application->recallObject($related_prefix.'.current', null, Array('skip_autoload' => true)); $p_item->Load( $this->Application->GetVar($related_prefix.'_id') ); $p_resource_id = $p_item->GetDBField('ResourceId'); $sql = 'SELECT SourceId, TargetId FROM '.$rel_table.' WHERE (Enabled = 1) AND ( (Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') OR (Type = 1 AND ( (SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') OR (TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.') ) ) )'; $related_ids_array = $this->Conn->Query($sql); $related_ids = Array(); foreach ($related_ids_array as $key => $record) { $related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ]; } if (count($related_ids) > 0) { $type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).') AND PrimaryCat = 1'; $type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).') AND PrimaryCat = 1'; } else { $type_clauses['related']['include'] = '0'; $type_clauses['related']['except'] = '1'; } $type_clauses['related']['having_filter'] = false; } return $type_clauses; } /** * Apply filters to list * * @param kEvent $event */ function SetCustomQuery(&$event) { parent::SetCustomQuery($event); $object =& $event->getObject(); // add category filter if needed 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'); } // add permission filter $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'); } $types = $event->getEventParam('types'); $except_types = $event->getEventParam('except'); $type_clauses = $this->getTypeClauses($event); // convert prepared type clauses into list filters $includes_or_filter =& $this->Application->makeClass('kMultipleFilter'); $includes_or_filter->setType(FLT_TYPE_OR); $excepts_and_filter =& $this->Application->makeClass('kMultipleFilter'); $excepts_and_filter->setType(FLT_TYPE_AND); $includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter'); $includes_or_filter_h->setType(FLT_TYPE_OR); $excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter'); $excepts_and_filter_h->setType(FLT_TYPE_AND); $except_types_array = explode(',', $types); if ($types) { $types_array = explode(',', $types); for ($i = 0; $i < sizeof($types_array); $i++) { $type = trim($types_array[$i]); if (isset($type_clauses[$type])) { if ($type_clauses[$type]['having_filter']) { $includes_or_filter_h->removeFilter('filter_'.$type); $includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']); }else { $includes_or_filter->removeFilter('filter_'.$type); $includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']); } } } } if ($except_types) { $except_types_array = explode(',', $except_types); for ($i = 0; $i < sizeof($except_types_array); $i++) { $type = trim($except_types_array[$i]); if (isset($type_clauses[$type])) { if ($type_clauses[$type]['having_filter']) { $excepts_and_filter_h->removeFilter('filter_'.$type); $excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']); }else { $excepts_and_filter->removeFilter('filter_'.$type); $excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']); } } } } /*if ( !$this->Application->IsAdmin() ) { $object->addFilter('expire_filter', '%1$s.Expire IS NULL OR %1$s.Expire > UNIX_TIMESTAMP()'); }*/ /*$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; } */ $object->addFilter('includes_filter', $includes_or_filter); $object->addFilter('excepts_filter', $excepts_and_filter); $object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER); $object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER); } /** * Adds calculates fields for item statuses * * @param kCatDBItem $object * @param kEvent $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); } } /** * Load price from temp table if product mode is temp table * * @param kEvent $event */ function OnAfterItemLoad(&$event) { $special = substr($event->Special, -6); if ($special == 'import' || $special == 'export') { $object =& $event->getObject(); $image_data = $object->getPrimaryImageData(); if ($image_data) { $thumbnail_image = $image_data[$image_data['LocalThumb'] ? 'ThumbPath' : 'ThumbUrl']; if ($image_data['SameImages']) { $full_image = ''; } else { $full_image = $image_data[$image_data['LocalImage'] ? 'LocalPath' : 'Url']; } $object->SetDBField('ThumbnailImage', $thumbnail_image); $object->SetDBField('FullImage', $full_image); $object->SetDBField('ImageAlt', $image_data['AltName']); } } } function OnAfterItemUpdate(&$event) { $this->CalculateHotLimit($event); if ( substr($event->Special, -6) == 'import') { $this->setCustomExportColumns($event); } } /** * sets values for import process * * @param kEvent $event */ function OnAfterItemCreate(&$event) { if ( substr($event->Special, -6) == 'import') { $this->setCustomExportColumns($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')); $keywords_arr = explode(' ', $keywords); if(count($keywords_arr) > 1 && strpos($keywords, '"') === false && strpos($keywords, '+') === false && strpos($keywords, '-') === false) { foreach($keywords_arr as $key => $value) { $keywords_arr[$key] = '+'.$value; } $keywords = implode(' ', $keywords_arr); } 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]; if($search_config[$field]['CustomFieldId']) { $exploded[1] = 'l'.$lang.'_'.$exploded[1]; } $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]; if($record['CustomFieldId']) { $exploded[1] = 'l'.$lang.'_'.$exploded[1]; } $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; } } /*$cur_per_page = $per_page; $per_page = $event->getEventParam('per_page'); if ($per_page == 'list_next') { $cur_page = $page; $object =& $this->Application->recallObject($event->Prefix); $object->SetPerPage(1); $cur_item_index = $object->CurrentIndex; $page = ($cur_page-1) * $cur_per_page + $cur_item_index + 1; $object->SetPerPage(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) { // use old fasion (in-portal) grid $selector_name = $this->Application->getUnitOption($event->Prefix, 'CatalogSelectorName'); if ($selector_name) { $selected_ids = $this->Application->GetVar($selector_name); } else { $this->StoreSelectedIDs($event); $selected_ids = $this->getSelectedIDs($event); if (implode(',', $selected_ids) == '') { // K4 fix when no ids found bad selected ids array is formed $selected_ids = false; } } $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); $field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!! $object->setID($item_id); $this->setRequiredFields($event); $export_object =& $this->Application->recallObject('CatItemExportHelper'); // save export/import options if ($event->Special == 'export') { $export_ids = $this->Application->RecallVar($event->Prefix.'_export_ids'); $export_cats_ids = $this->Application->RecallVar($event->Prefix.'_export_cats_ids'); // used for multistep export $field_values['export_ids'] = $export_ids ? explode(',', $export_ids) : false; $field_values['export_cats_ids'] = $export_cats_ids ? explode(',', $export_cats_ids) : Array( $this->Application->GetVar('m_cat_id') ); } $field_values['ExportColumns'] = $field_values['ExportColumns'] ? explode('|', substr($field_values['ExportColumns'], 1, -1) ) : Array(); $field_values['start_from'] = 0; $this->Application->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(); // ID of category to create $available_columns['__CATEGORY__CategoryId'] = 'CategoryId'; // category field (mixed) $available_columns['__CATEGORY__CategoryPath'] = 'CategoryPath'; if ($event->Special == 'import') { // category field (separated fields) $max_level = $this->Application->ConfigValue('MaxImportCategoryLevels'); $i = 0; while ($i < $max_level) { $available_columns['__CATEGORY__Category'.($i + 1)] = 'Category'.($i + 1); $i++; } } // db fields foreach ($object->Fields as $field_name => $field_options) { if (!$object->SkipField($field_name)) { $available_columns[$field_name] = $field_name.(getArrayValue($field_options, 'required') ? '*' : ''); } } $available_columns = array_merge_recursive2($available_columns, $this->getCustomExportColumns($event)); // 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 (is_dir(EXPORT_PATH.'/'.$file) || substr($file, 0, 1) == '.' || strtolower($file) == 'cvs' || strtolower($file) == 'dummy' || filesize(EXPORT_PATH.'/'.$file) == 0) continue; $file_size = formatSize( filesize(EXPORT_PATH.'/'.$file) ); $import_filenames[$file] = $file.' ('.$file_size.')'; } closedir($folder_handle); } $options = $object->GetFieldOptions('ImportLocalFilename'); $options['options'] = $import_filenames; $object->SetFieldOptions('ImportLocalFilename', $options); } } /** * Returns specific to each item type columns only * * @param kEvent $event * @return Array */ function getCustomExportColumns(&$event) { return Array( '__VIRTUAL__ThumbnailImage' => 'ThumbnailImage', '__VIRTUAL__FullImage' => 'FullImage', '__VIRTUAL__ImageAlt' => 'ImageAlt'); } /** * Sets non standart virtual fields (e.g. to other tables) * * @param kEvent $event */ function setCustomExportColumns(&$event) { $this->restorePrimaryImage($event); } /** * Create/Update primary image record in info found in imported data * * @param kEvent $event */ function restorePrimaryImage(&$event) { $object =& $event->getObject(); $has_image_info = $object->GetDBField('ImageAlt') && ($object->GetDBField('ThumbnailImage') || $object->GetDBField('FullImage')); if (!$has_image_info) { return false; } $image_data = $object->getPrimaryImageData(); $image =& $this->Application->recallObject('img', null, Array('skip_autoload' => true)); if ($image_data) { $image->Load($image_data['ImageId']); } else { $image->Clear(); $image->SetDBField('Name', 'main'); $image->SetDBField('DefaultImg', 1); $image->SetDBField('ResourceId', $object->GetDBField('ResourceId')); } $image->SetDBField('AltName', $object->GetDBField('ImageAlt')); if ($object->GetDBField('ThumbnailImage')) { $thumbnail_field = $this->isURL( $object->GetDBField('ThumbnailImage') ) ? 'ThumbUrl' : 'ThumbPath'; $image->SetDBField($thumbnail_field, $object->GetDBField('ThumbnailImage') ); $image->SetDBField('LocalThumb', $thumbnail_field == 'ThumbPath' ? 1 : 0); } if (!$object->GetDBField('FullImage')) { $image->SetDBField('SameImages', 1); } else { $image->SetDBField('SameImages', 0); $full_field = $this->isURL( $object->GetDBField('FullImage') ) ? 'Url' : 'LocalPath'; $image->SetDBField($full_field, $object->GetDBField('FullImage') ); $image->SetDBField('LocalImage', $full_field == 'LocalPath' ? 1 : 0); } if ($image->isLoaded()) { $image->Update(); } else { $image->Create(); } } function isURL($path) { return preg_match('#(http|https)://(.*)#', $path); } // 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); $this->Application->StoreVar('ImportCategory', 0); } /** * set required fields based on import or export params * * @param kEvent $event */ function setRequiredFields(&$event) { $required_fields['common'] = Array('FieldsSeparatedBy', 'LineEndings', 'CategoryFormat'); $required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns'); $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 === */ function BuildListSpecial($params) { if ($this->Special != '') return $this->Special; if ( isset($params['parent_cat_id']) ) { $parent_cat_id = $params['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'); } } $recursive = isset($params['recursive']); $types = $this->SelectParam($params, 'types'); $except = $this->SelectParam($params, 'except'); if ($types.$except.$recursive == '') { return parent::BuildListSpecial($params); } $special = crc32($parent_cat_id.$types.$except.$recursive.$manufacturer); return $special; } } ?>