Factory->includeClassFile('kDBEventHandler'); class kCatDBEventHandler extends InpDBEventHandler { /** * Allows to override standart permission mapping * */ function mapPermissions() { parent::mapPermissions(); $permissions = Array( 'OnExport' => Array('self' => 'view|advanced:export'), 'OnExportBegin' => Array('self' => 'view|advanced:export'), 'OnSaveSettings' => Array('self' => 'add|edit|advanced:import'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Checks permissions of user * * @param kEvent $event */ function CheckPermission(&$event) { if (!$this->Application->IsAdmin()) { if ($event->Name == 'OnSetSortingDirect') { // allow sorting on front event without view permission return true; } } if ($event->Name == 'OnExport') { // save category_id before doing export $this->Application->LinkVar('m_cat_id'); } if ($event->Name == 'OnNew' && preg_match('/(.*)\/import$/', $this->Application->GetVar('t'), $rets)) { // redirect to item import template, where permission (import) category will be chosen) $root_category = $this->Application->findModule('Path', $rets[1].'/', 'RootCat'); $this->Application->StoreVar('m_cat_id', $root_category); } return parent::CheckPermission($event); } 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; } $ids_arr = explode(',', $ids); if ($this->Application->RecallVar($event->getPrefixSpecial().'_clipboard_mode') == 'copy') { $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); if ($ids_arr) { $temp->CloneItems($event->Prefix, $event->Special, $ids_arr); } } else { // mode == cut $object =& $this->Application->recallObject($event->getPrefixSpecial().'.item', $event->Prefix, Array('skip_autoload' => true)); 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) { $resource_id = $this->Application->GetVar('translator_resource_id'); if ($resource_id) { $t_prefixes = explode(',', $this->Application->GetVar('translator_prefixes')); $cdata =& $this->Application->recallObject($t_prefixes[1], null, Array('skip_autoload' => true)); $cdata->Load($resource_id, 'ResourceId'); if (!$cdata->isLoaded()) { $cdata->SetDBField('ResourceId', $resource_id); $cdata->Create(); } $this->Application->SetVar($cdata->getPrefixSpecial().'_id', $cdata->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 (really needed here, because of tweaky redirect) $last_template = $this->Application->RecallVar('last_template'); preg_match('/index4\.php\|'.$this->Application->GetSID().'-(.*):/U', $last_template, $rets); $this->Application->StoreVar('return_template', $this->Application->GetVar('t')); } } /** * 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_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings'); // new items $object->addCalculatedField('IsNew', ' IF(%1$s.NewItem = 2, IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '. $this->Application->ConfigValue($property_map['NewDays']). '*3600*24), 1, 0), %1$s.NewItem )'); // hot items $sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = "'.$property_map['HotLimit'].'"'; $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.'.$property_map['ClickField'].' >= '.$hot_limit.', 1, 0), %1$s.HotItem )'); // popular items $object->addCalculatedField('IsPop', ' IF(%1$s.PopItem = 2, IF(%1$s.CachedVotesQty >= '. $this->Application->ConfigValue($property_map['MinPopVotes']). ' AND %1$s.CachedRating >= '. $this->Application->ConfigValue($property_map['MinPopRating']). ', 1, 0), %1$s.PopItem)'); } function CalculateHotLimit(&$event) { $property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings'); $click_field = $property_map['ClickField']; $last_hot = $this->Application->ConfigValue($property_map['MaxHotNumber']) - 1; $sql = 'SELECT '.$click_field.' FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').' ORDER BY '.$click_field.' 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 ("'.$property_map['HotLimit'].'", "'.$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); } } /** * Make record to search log * * @param string $keywords * @param int $search_type 0 - simple search, 1 - advanced search */ function saveToSearchLog($keywords, $search_type = 0) { $sql = 'UPDATE '.TABLE_PREFIX.'SearchLog SET Indices = Indices + 1 WHERE Keyword = '.$this->Conn->qstr($keywords).' AND SearchType = '.$search_type; // 0 - simple search, 1 - advanced search $this->Conn->Query($sql); if ($this->Conn->getAffectedRows() == 0) { $fields_hash = Array('Keyword' => $keywords, 'Indices' => 1, 'SearchType' => $search_type); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SearchLog'); } } /** * 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 = unhtmlentities( trim($this->Application->GetVar('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); if (!$this->Application->GetVar('INPORTAL_ON')) { // don't save search log, because in-portal already saved it $this->saveToSearchLog($keywords, 0); // 0 - simple search, 1 - advanced search } $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; $alias_counter = 0; $custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields'); if ($custom_fields) { $custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName'); $join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$product_table.'.ResourceId = custom_data.ResourceId'; } // what field in search config becomes what field in sql (key - new field, value - old field (from searchconfig table)) $search_config_map = Array(); 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 (getArrayValue($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 = $this->Application->RecallVar('UserGroups'); $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); // format: table.field_name $foreign_table = TABLE_PREFIX.$exploded[0]; $alias_counter++; $alias = 't'.$alias_counter; $field_list[$key] = $alias.'.'.$exploded[1]; $search_config_map[ $field_list[$key] ] = $field; $join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']); $join_clause = str_replace('{LocalTable}', $product_table, $join_clause); $join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.' ON '.$join_clause; } } else { // processing fields from local table if ($search_config[$field]['CustomFieldId']) { $local_table = 'custom_data'; $field_list[$key] = 'l'.$lang.'_cust_'.array_search($field_list[$key], $custom_fields); } $field_list[$key] = $local_table.'.'.$field_list[$key]; $search_config_map[ $field_list[$key] ] = $field; } } // keyword string processing $search_helper =& $this->Application->recallObject('SearchHelper'); $where_clause = $search_helper->buildWhereClause($keywords, $field_list); $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')).')'; } } // making relevance clause $positive_words = $search_helper->getPositiveKeywords($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[ $search_config_map[$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_Keyword_products') / 100; $rel_pop = $this->Application->ConfigValue('SearchRel_Pop_products') / 100; $rel_rating = $this->Application->ConfigValue('SearchRel_Rating_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'); $search_keywords = $this->Application->GetVar('value'); // will not be changed $keywords = $this->Application->GetVar('value'); // will be changed down there $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; $custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields'); if ($custom_fields) { $custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName'); $join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$product_table.'.ResourceId = custom_data.ResourceId'; } $search_log = ''; $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 (getArrayValue($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 = $this->Application->RecallVar('UserGroups'); $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 if ($record['CustomFieldId']) { $local_table = 'custom_data'; $field_name = 'l'.$lang.'_cust_'.array_search($field_name, $custom_fields); } $field_name = $local_table.'.'.$field_name; } $condition = ''; switch($record['FieldType']) { case 'text': $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; } } // create search log record $search_log_data = Array('search_config' => $record, 'verb' => getArrayValue($verbs, $field), 'value' => ($record['FieldType'] == 'range') ? $search_keywords[$field.'_from'].'|'.$search_keywords[$field.'_to'] : $search_keywords[$field]); $search_log[] = $this->Application->Phrase('la_Field').' "'.$this->getHuman('Field', $search_log_data).'" '.$this->getHuman('Verb', $search_log_data).' '.$this->Application->Phrase('la_Value').' '.$this->getHuman('Value', $search_log_data).' '.$this->Application->Phrase($glues[$field] == 1 ? 'lu_And' : 'lu_Or'); } } $search_log = implode('
', $search_log); $search_log = preg_replace('/(.*) '.preg_quote($this->Application->Phrase('lu_and'), '/').'|'.preg_quote($this->Application->Phrase('lu_or'), '/').'$/is', '\\1', $search_log); $this->saveToSearchLog($search_log, 1); // advanced search $this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords)); // making relevance clause if($relevance_parts) { $rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_products') / 100; $rel_pop = $this->Application->ConfigValue('SearchRel_Pop_products') / 100; $rel_rating = $this->Application->ConfigValue('SearchRel_Rating_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); } function getHuman($type, $search_data) { $type = ucfirst(strtolower($type)); extract($search_data); switch ($type) { case 'Field': return $this->Application->Phrase($search_config['DisplayName']); break; case 'Verb': return $verb ? $this->Application->Phrase('lu_advsearch_'.$verb) : ''; break; case 'Value': switch ($search_config['FieldType']) { case 'date': $values = Array(0 => 'lu_comm_Any', 'today' => 'lu_comm_Today', 'yesterday' => 'lu_comm_Yesterday', 'last_week' => 'lu_comm_LastWeek', 'last_month' => 'lu_comm_LastMonth', 'last_3_months' => 'lu_comm_Last3Months', 'last_6_months' => 'lu_comm_Last6Months', 'last_year' => 'lu_comm_LastYear'); $ret = $this->Application->Phrase($values[$value]); break; case 'range': $value = explode('|', $value); return $this->Application->Phrase('lu_comm_From').' "'.$value[0].'" '.$this->Application->Phrase('lu_comm_To').' "'.$value[1].'"'; break; case 'boolean': $values = Array(1 => 'lu_comm_Yes', 0 => 'lu_comm_No', -1 => 'lu_comm_Both'); $ret = $this->Application->Phrase($values[$value]); break; case 'text': $ret = $value; break; } return '"'.$ret.'"'; break; } } /** * 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); } 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') ); $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); } list($item_id, $field_values) = each($items_info); $object =& $event->getObject( Array('skip_autoload' => true) ); $object->SetFieldsFromHash($field_values); $field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!! $object->setID($item_id); $this->setRequiredFields($event); $export_object =& $this->Application->recallObject('CatItemExportHelper'); // save export/import options if ($event->Special == 'export') { $export_ids = $this->Application->RecallVar($event->Prefix.'_export_ids'); $export_cats_ids = $this->Application->RecallVar($event->Prefix.'_export_cats_ids'); // used for multistep export $field_values['export_ids'] = $export_ids ? explode(',', $export_ids) : false; $field_values['export_cats_ids'] = $export_cats_ids ? explode(',', $export_cats_ids) : Array( $this->Application->GetVar('m_cat_id') ); } $field_values['ExportColumns'] = $field_values['ExportColumns'] ? explode('|', substr($field_values['ExportColumns'], 1, -1) ) : Array(); $field_values['start_from'] = 0; $export_object->saveOptions($event, $field_values); if( $export_object->verifyOptions($event) ) { $event->redirect = $this->getModuleFolder($event).'/'.$event->Special.'_progress'; } else { // make uploaded file local & change source selection $filename = getArrayValue($field_values, 'ImportFilename'); if ($filename) { $this->updateImportFiles($event); $object->SetDBField('ImportSource', 2); $field_values['ImportSource'] = 2; $object->SetDBField('ImportLocalFilename', $filename); $field_values['ImportLocalFilename'] = $filename; $export_object->saveOptions($event, $field_values); } $event->status = erFAIL; $event->redirect = false; } } /** * Enter description here... * * @param kEvent $event */ function OnExportCancel(&$event) { $this->OnGoBack($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 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 foreach ($object->customFields as $custom_id => $custom_name) { $available_columns['__CUSTOM__'.$custom_name] = $custom_name; } // columns already in use $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if ($items_info) { list($item_id, $field_values) = each($items_info); $export_keys = $field_values['ExportColumns']; $export_keys = $export_keys ? explode('|', substr($export_keys, 1, -1) ) : Array(); } else { $export_keys = Array(); } $export_columns = Array(); foreach ($export_keys as $field_key) { $field_name = $this->getExportField($field_key); $export_columns[$field_key] = $field_name; unset($available_columns[$field_key]); } $options = $object->GetFieldOptions('ExportColumns'); $options['options'] = $export_columns; $object->SetFieldOptions('ExportColumns', $options); $options = $object->GetFieldOptions('AvailableColumns'); $options['options'] = $available_columns; $object->SetFieldOptions('AvailableColumns', $options); $this->updateImportFiles($event); } /** * Updates uploaded files list * * @param kEvent $event */ function updateImportFiles(&$event) { if ($event->Special != 'import') { return false; } $object =& $event->getObject(); $import_filenames = Array(); if ($folder_handle = opendir(EXPORT_PATH)) { while (false !== ($file = readdir($folder_handle))) { if (is_dir(EXPORT_PATH.'/'.$file) || substr($file, 0, 1) == '.' || strtolower($file) == 'cvs' || strtolower($file) == 'dummy' || filesize(EXPORT_PATH.'/'.$file) == 0) continue; $file_size = formatSize( filesize(EXPORT_PATH.'/'.$file) ); $import_filenames[$file] = $file.' ('.$file_size.')'; } closedir($folder_handle); } $options = $object->GetFieldOptions('ImportLocalFilename'); $options['options'] = $import_filenames; $object->SetFieldOptions('ImportLocalFilename', $options); } /** * Returns 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) { $dst_field = $this->Application->RecallVar('dst_field'); $items_info = $this->Application->GetVar('c'); if ($items_info) { $category_id = array_shift( array_keys($items_info) ); $sql = 'SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ResourceId = '.$category_id; $category_id = $this->Conn->GetOne($sql); } else { $category_id = 0; } if ($dst_field == 'ImportCategory') { $this->Application->StoreVar('ImportCategory', $category_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); } if ($dst_field == 'ItemCategory') { $object =& $event->getObject(); // category item object (e.g. link, product, etc.) $ci_prefix = $object->Prefix.'-ci'; $ci_object =& $this->Application->recallObject($ci_prefix, null, Array('skip_autoload' => true)); $ci_object->Load($category_id); if (!$ci_object->isLoaded()) { $fields_hash = Array('CategoryId' => $category_id, 'ItemResourceId' => $object->GetDBField('ResourceId')); $ci_object->SetDBFieldsFromHash($fields_hash); $ci_object->Create(true); } } $this->finalizePopup($event); } /** * 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) { list($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 !!! $field_values['ImportSource'] = 2; $field_values['ImportLocalFilename'] = $object->GetDBField('ImportFilename'); $items_info[$id] = $field_values; $this->Application->StoreVar($event->getPrefixSpecial().'_ItemsInfo', serialize($items_info)); } } /* === RELATED TO IMPORT/EXPORT: END === */ } ?>