Created
February 26, 2010 22:58
-
-
Save codesnik/316283 to your computer and use it in GitHub Desktop.
WTF ZOMG controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CatalogueController < ApplicationController | |
@@rows_on_page = 50 | |
@@companies_on_page = 20 | |
def firms | |
# Возвращаем "304 Not Modified" если страница не устарела | |
if industry.cached_level >= 2 || industry.leaf? | |
if params[:format] != 'xls' | |
# если выводится список компаний (причем не в ExCel) | |
self.http_headers_section = :with_rows | |
return if send_not_modified | |
end | |
else | |
# если не выводится список компаний | |
self.http_headers_section = :without_rows | |
end | |
# мы показываем фирмы в каталоге, начиная со второго уровня, | |
# либо если рубрика и так является нодой, | |
# либо если мы ищем поиском что-то | |
#load_regions | |
return not_found if industry.nil? | |
@search_section = "firms" # установка глобальной переменной для формы поиска | |
# TODO отрефакторить magic number 20 | |
@number = params[:page] ? 20 * (params[:page].to_i - 1) : 0 | |
# поиск у нас происходит добавлением параметра "q", поэтому мы вынесем поиск | |
# в отдельное место | |
return searchfirms if !params[:q].nil? && params[:q] != "" | |
page_title_section = industry.level == 0 ? '' : '_rubric' | |
set_title_key("title#{page_title_section}") | |
set_header_key("header#{page_title_section}") | |
set_description_key("description#{page_title_section}") | |
set_title_variables(title_header_descr_values) | |
# подрубрики | |
@subrubrics = industry.direct_children | |
companies_count = Industry.do_count_companies(current_region, @subrubrics) #Получаем кол-во компаний в текущем регионе для каждой их подрубрик | |
@subrubrics.each {|r| r.set_company_count(current_region, companies_count[r.id] ||= 0)} | |
# удалить из полученного результата все рубрики, у которых нет компаний и которые не являются симлинком | |
@subrubrics = @subrubrics.delete_if { |o| o.company_count(current_region) == 0 && o.link_to == nil } | |
if industry.cached_level >= 2 || industry.leaf? | |
# экспорт в эксель | |
if params[:format] == 'xls' | |
@companies = Company.search('', | |
# TODO отрефакторить magic number 1000 | |
:per_page => 1000, # TODO: пока ограничимся этим максимумом | |
:with => firms_query_conditions, | |
:order => :title_ord, | |
:sort_mode => :asc) | |
exporter = ExportExcel::Companies.new(@companies, {:host => request.host}) | |
send_data exporter.export, :filename => 'pulscen-companies.xls', :content_type => "application/xls" | |
return | |
else | |
@companies = load_companies_by_ids(Company.search_for_ids('', | |
:page => params[:page], | |
# TODO отрефакторить magic number 20 | |
:per_page => @@companies_on_page, | |
:with => firms_query_conditions, | |
:order => :title_ord, :sort_mode => :asc)) | |
@letters = Company.list_letters('', firms_query_conditions) | |
end | |
else | |
# если мы не показываем компании, то показываем список последних компаний | |
@last_companies = Company.search('', | |
:page => 1, | |
# TODO отрефакторить magic number 90 и 60 | |
:per_page => industry.root? ? 90 : 60, | |
:with => firms_query_conditions, | |
:order => :created_at, | |
:sort_mode => :desc) | |
end | |
end | |
def search_redirect | |
# если нам передали флаг "искать в рубрике" и "путь до рубрики", то надо | |
# сделать туда редирект | |
if !params[:rubric].nil? | |
options = {:q => params[:q]} | |
route = current_region.default? ? :firms_path : :region_firms_path | |
options[:region] = current_region.name_lat unless current_region.default? | |
options[:path] = params[:rubric] if params[:search_in_rubric] && params[:rubric] != "/" | |
return redirect_to send(route, options) | |
end | |
return not_found | |
end | |
def searchfirms | |
page_title_section = '_search' | |
set_title_key("title#{page_title_section}") | |
set_header_key("header#{page_title_section}") | |
set_description_key("description#{page_title_section}") | |
set_title_variables(title_header_descr_values) | |
se = Search::SearchQuery.new(params[:q], true) | |
@search_query = se.prepared | |
if params[:format] == 'xls' | |
@companies = Company.search @search_query, | |
# TODO отрефакторить magic number 1000 | |
:per_page => 1000, | |
:with => firms_query_conditions | |
exporter = ExportExcel::Companies.new(@companies, {:host => request.host}) | |
send_data exporter.export, :filename => 'pulscen-companies.xls', :content_type => "application/xls" | |
return | |
else | |
@companies = load_companies_by_ids(Company.search_for_ids(@search_query, | |
:page => params[:page], | |
# TODO отрефакторить magic number 20 | |
:per_page => @@companies_on_page, | |
:with => firms_query_conditions)) | |
set_title_variables(title_header_descr_values.merge({:COUNT => @companies.total_entries})) | |
end | |
# когда мы хотим вывести рубрики, то убираем фильтр по первой букве | |
cond = firms_query_conditions | |
cond.delete(:first_letter_ord) | |
@subrubrics = Company.list_industries @search_query, cond | |
@letters = Company.list_letters @search_query, firms_query_conditions | |
# чтобы правильно отобразилось общее найденное число | |
industry.set_company_count(current_region, @companies.total_entries) | |
render 'firms' | |
end | |
def sprosfirms | |
# Возвращаем "304 Not Modified" если страница не устарела | |
self.http_headers_section = :with_rows | |
return if send_not_modified | |
if check_search | |
return | |
end | |
return try_rubric_with_old_url if rubric.nil? | |
@count_demand = {:is_demand => true} | |
advanced_search_mod | |
load_rubrics(@count_demand) | |
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id" | |
set_title_variables(title_header_descr_values) | |
@predl_count = ThinkingSphinx.search_count( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }), | |
:classes => [Product, PriceListRow], | |
:match_mode => :extended | |
) | |
@firms_count = ThinkingSphinx.search_count( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }), | |
:classes => [Product, PriceListRow], | |
:group => :company_id, | |
:match_mode => :extended | |
) | |
@predl_count = 0 if @predl_count.nil? | |
@firms_count = 0 if @firms_count.nil? | |
@firms = nil | |
if show_rows? | |
sph_res = ThinkingSphinx.search( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id}), | |
:classes => [Product, PriceListRow], | |
:page => params[:page], | |
:per_page => @@rows_on_page, | |
:match_mode => :extended, | |
:group_by => "company_id", | |
:group_function => :attr, | |
:group_clause => "@count DESC" | |
) | |
sph_data = sph_res.results[:matches] | |
companies_ids = sph_data.collect { |e| e[:attributes]["@groupby"] } | |
if companies_ids.length == 0 | |
return | |
end | |
@firms = Array.new | |
def @firms.sph_res=(r) | |
@sph_res = r | |
end | |
@firms.sph_res = sph_res | |
def @firms.total_pages | |
@sph_res.total_pages | |
end | |
def @firms.current_page | |
@sph_res.current_page | |
end | |
def @firms.next_page | |
@sph_res.next_page | |
end | |
def @firms.previous_page | |
@sph_res.previous_page | |
end | |
# load predl count for companies | |
spros_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => true}) | |
# stats | |
stats = CompanyStatisticTotalByMonth.previous_month.find(:all, :conditions => {:company_id => companies_ids}, :select => 'company_id, sum(pages) as sum_pages, sum(visits) as sum_visits', :group => 'company_id') | |
stats_hash = {} | |
stats.each do |s| | |
stats_hash[s.company_id] = {:pages => s.sum_pages.to_i, :visits => s.sum_visits.to_i} | |
end | |
# load from db | |
companies = Company.find(companies_ids, :include => [:company_logo, {:main_address => :city}]) | |
companies_hash = {} | |
companies.each do |c| | |
c.spros_count = spros_count[c.id] || 0 | |
companies_hash[c.id] = c | |
end | |
sph_data.each { |e| | |
@firms.push({ | |
:firm => companies_hash[e[:attributes]["@groupby"]], | |
:count => e[:attributes]["@count"], | |
:stats => stats_hash[e[:attributes]["@groupby"]] ? stats_hash[e[:attributes]["@groupby"]] : {} | |
}) | |
} | |
end | |
end | |
def predlfirms | |
# Возвращаем "304 Not Modified" если страница не устарела | |
self.http_headers_section = :with_rows | |
return if send_not_modified | |
if check_search | |
return | |
end | |
return try_rubric_with_old_url if rubric.nil? | |
set_title_variables(title_header_descr_values) | |
@count_demand = {:is_demand => false} | |
advanced_search_mod | |
load_rubrics(@count_demand) | |
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id" | |
@predl_count = ThinkingSphinx.search_count( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }), | |
:classes => [Product, PriceListRow], | |
:match_mode => :extended | |
) | |
@firms_count = ThinkingSphinx.search_count( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }), | |
:classes => [Product, PriceListRow], | |
:group => :company_id, | |
:match_mode => :extended | |
) | |
@predl_count = 0 if @predl_count.nil? | |
@firms_count = 0 if @firms_count.nil? | |
@firms = nil | |
if show_rows? | |
sph_res = ThinkingSphinx.search_for_ids( | |
@search_query, | |
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id}), | |
:classes => [Product, PriceListRow], | |
:page => params[:page], | |
:per_page => @@rows_on_page, | |
:match_mode => :extended, | |
:group_by => "company_id", | |
:group_function => :attr, | |
:group_clause => "packet DESC, @count DESC" | |
) | |
sph_data = sph_res.results[:matches] | |
companies_ids = sph_data.collect { |e| e[:attributes]["@groupby"] } | |
if companies_ids.length == 0 | |
return | |
end | |
@firms = Array.new | |
def @firms.sph_res=(r) | |
@sph_res = r | |
end | |
@firms.sph_res = sph_res | |
def @firms.total_pages | |
@sph_res.total_pages | |
end | |
def @firms.current_page | |
@sph_res.current_page | |
end | |
def @firms.next_page | |
@sph_res.next_page | |
end | |
def @firms.previous_page | |
@sph_res.previous_page | |
end | |
# load predl count for companies | |
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false}) | |
# stats | |
stats = CompanyStatisticTotalByMonth.previous_month.find(:all, :conditions => {:company_id => companies_ids}, :select => 'company_id, sum(pages) as sum_pages, sum(visits) as sum_visits', :group => 'company_id') | |
stats_hash = {} | |
stats.each do |s| | |
stats_hash[s.company_id] = {:pages => s.sum_pages.to_i, :visits => s.sum_visits.to_i} | |
end | |
# prod count | |
prod = Product.fast_facet('', :company_id, :with => {:company_id => companies_ids}) | |
# load from db | |
companies = Company.find(companies_ids, | |
:select => 'id, name, packet, has_email', | |
:include => [:representative, :company_logo, {:main_address => :city}]) | |
companies_hash = {} | |
companies.each do |c| | |
c.predl_count = predl_count[c.id] || 0 | |
c.index_products_count = prod[c.id] || 0 | |
companies_hash[c.id] = c | |
end | |
sph_data.each { |e| | |
@firms.push({ | |
:firm => companies_hash[e[:attributes]["@groupby"]], | |
:count => e[:attributes]["@count"], | |
:stats => stats_hash[e[:attributes]["@groupby"]] ? stats_hash[e[:attributes]["@groupby"]] : {} | |
}) | |
} | |
end | |
end | |
# caches_action :spros, | |
# :expires_in => Conf.general['cache_expire'].minutes, | |
# :layout => false, | |
# :cache_path => Proc.new{|controller| controller.params.merge({:region => controller.current_region.name_lat})} | |
def spros | |
return try_rubric_with_old_url if rubric.nil? | |
# Возвращаем "304 Not Modified" если страница не устарела | |
if show_rows? | |
self.http_headers_section = :with_rows | |
return if send_not_modified | |
else | |
self.http_headers_section = :without_rows | |
end | |
if check_search | |
return | |
end | |
# page title | |
# page title | |
if @search_query != "" | |
page_title_section = '_search' | |
else | |
page_title_section = rubric.level == 0 ? '' : '_rubric' | |
end | |
set_title_key("title#{page_title_section}") | |
set_header_key("header#{page_title_section}") | |
set_description_key("description#{page_title_section}") | |
set_title_variables(title_header_descr_values) | |
@cache_key = self.params.merge({:region => current_region.name_lat}) | |
@cache_key.merge!({:region_by_ip => current_region_by_ip.name_lat}) if current_region_by_ip | |
@cache_expires_in = (show_rows? ? Conf.cache['catalogue']['spros']['with_rows'] : Conf.cache['catalogue']['spros']['without_rows']).minutes | |
return if fragment_exist?(@cache_key) | |
#load_regions | |
#порядок важе - переменную изменять после загрузки регионов | |
@count_demand = {:is_demand => true} | |
advanced_search_mod | |
load_rubrics(@count_demand) | |
within = "rubric_l#{rubric.cached_level}_id" | |
with = @count_demand.merge({:regions => [current_region.id], within => rubric.id }.merge(@count_demand)) | |
if params[:format] == 'xls' | |
exporter = ExportExcel::Goods.new @search_query, | |
with, | |
{ | |
:request_uri => url_for(:overwrite_params => {:format => nil}, :only_path => false), | |
:user_query => params[:q], | |
:host => request.host | |
} | |
send_data exporter.export, :filename => 'pulscen-spros.xls', :content_type => "application/xls" | |
return | |
end | |
@spros_count = PriceListRow.search_count( | |
@search_query, | |
:with => with, | |
:match_mode => :extended | |
) | |
@firms_count = PriceListRow.search_count( | |
@search_query, | |
:with => with, | |
:group => :company_id, | |
:match_mode => :extended | |
) | |
@spros_count = 0 if @spros_count.nil? | |
@firms_count = 0 if @firms_count.nil? | |
@rows = nil | |
if show_rows? | |
@rows = PriceListRow.search( | |
@search_query, | |
:with => with, | |
:page => params[:page], | |
:per_page => @@rows_on_page, | |
:match_mode => :extended, | |
:sort_mode => :extended, | |
:order => "@relevance DESC, date_order DESC, sort_level ASC, title ASC" | |
#:order => "@relevance DESC, position ASC" | |
) | |
@rows = load_linked_objects_for_rows!(@rows) | |
end | |
end | |
# caches_action_with_content_for :predl, | |
# :expires_in => Conf.general['cache_expire'].minutes, | |
# :layout => false, | |
# :cache_path => Proc.new{|controller| controller.params.merge({:region => controller.current_region.name_lat})} | |
def predl | |
return try_rubric_with_old_url if rubric.nil? | |
# Возвращаем "304 Not Modified" если страница не устарела | |
if show_rows? | |
self.http_headers_section = :with_rows | |
return if send_not_modified | |
else | |
self.http_headers_section = :without_rows | |
end | |
if check_search | |
return | |
end | |
# page title | |
page_title_key = '' | |
if @search_query != "" | |
page_title_section = '_search' | |
else | |
page_title_section = rubric.level == 0 ? '' : '_rubric' | |
if rubric.level > 0 && !rubric.synonym | |
page_title_key = '_rubric_no_synonym' | |
end | |
end | |
if current_region.name_lat == 'ru' | |
if page_title_key != '' | |
page_title_key += '_no_region' | |
else | |
page_title_section += '_no_region' | |
end | |
end | |
set_title_key(page_title_key != "" ? "title#{page_title_key}" : "title#{page_title_section}") | |
set_header_key("header#{page_title_section}") | |
set_description_key("description#{page_title_section}") | |
set_title_variables(title_header_descr_values) | |
@cache_key = self.params.merge({:region => current_region.name_lat}) | |
@cache_key.merge!(:region_by_ip => current_region_by_ip.name_lat) if current_region_by_ip | |
@cache_expires_in = (show_rows? ? Conf.cache['catalogue']['predl']['with_rows'] : Conf.cache['catalogue']['predl']['without_rows']).minutes | |
return if fragment_exist?(@cache_key) | |
#load_regions | |
@count_demand = {:is_demand => false} | |
advanced_search_mod | |
load_rubrics(@count_demand) | |
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id" | |
with = @count_demand.merge({:regions => [current_region.id], within => rubric.id }) | |
if params[:format] == 'xls' | |
exporter = ExportExcel::Goods.new @search_query, | |
with, | |
{ | |
:request_uri => url_for(:overwrite_params => {:format => nil}, :only_path => false), | |
:user_query => params[:q], | |
:host => request.host | |
} | |
send_data exporter.export, :filename => 'pulscen-predl.xls', :content_type => "application/xls" | |
return | |
end | |
@firms_count = ThinkingSphinx.search_count( | |
@search_query, | |
:with => with, | |
:classes => [Product, PriceListRow], | |
:group => :company_id, | |
:match_mode => :extended | |
) | |
@firms_count = 0 if @firms_count.nil? | |
@products_total = @lots_total = 0 | |
@rows = nil | |
if show_rows? | |
product_fields = ['id', 'name', 'announce', 'company_id', | |
'is_exact_price', 'price', | |
'price_max', "actualized_at"] | |
current_page = params[:page].to_i || 1 | |
current_page = 1 if current_page < 1 | |
@products = Product.search( | |
@search_query, | |
:with => with, | |
:page => current_page, | |
:per_page => @@rows_on_page, | |
:match_mode => :extended, | |
#:sort_mode => :extended, | |
:group_by => 'company_id', | |
:group_function => :attr, | |
#:order => "@relevance DESC, packet DESC, date_order DESC, title ASC" | |
:group_clause => "@relevance DESC, packet DESC, date_order DESC, title ASC", | |
:select => product_fields.join(', ') | |
) | |
@products_total = @products.results[:total_found] || 0 | |
if @products.count < @@rows_on_page | |
offset = ((current_page - 1) * @@rows_on_page) - @products_total | |
offset = 0 if offset < 0 | |
limit = @@rows_on_page - @products.count | |
offset = (5000 - limit) if (offset + limit) > 5000 | |
lots_fields = ['id', 'title', 'company_id', 'price', 'price_max', 'is_exact'] | |
@lots = PriceListRow.search( | |
@search_query, | |
:with => with, | |
:offset => offset, | |
:limit => limit, | |
:match_mode => :extended, | |
:sort_mode => :extended, | |
:order => "is_row ASC, @relevance DESC, date_order DESC, sort_level ASC, title ASC", | |
:select => lots_fields.join(', ') | |
#:order => "@relevance DESC, position ASC" | |
) | |
@lots_total = @lots.results[:total_found] || 0 | |
else | |
@lots = [] | |
@lots_total = PriceListRow.search_count( | |
@search_query, | |
:with => with, | |
:match_mode => :extended | |
) || 0 | |
end | |
@predl_count = @products_total.to_i + @lots_total.to_i | |
@rows = @products.to_a + @lots.to_a | |
@rows = load_linked_objects_for_rows!(@rows.compact) | |
self.class.total_pages = ([@predl_count, 5000].min.to_f / @@rows_on_page.to_f).ceil | |
self.class.current_page = current_page | |
def @rows.total_pages | |
CatalogueController.total_pages | |
end | |
def @rows.current_page | |
CatalogueController.current_page | |
end | |
def @rows.next_page | |
current_page < total_pages ? current_page + 1 : nil | |
end | |
def @rows.previous_page | |
current_page > 1 ? current_page - 1 : nil | |
end | |
else # if !show_rows? | |
@predl_count = Product.search_count( | |
@search_query, | |
:with => with, | |
:match_mode => :extended, | |
:group_by => 'company_id', | |
:group_function => :attr | |
) + PriceListRow.search_count( | |
@search_query, | |
:with => with, | |
:match_mode => :extended | |
) | |
end | |
#PriceListRow.paginate_all_by_rubric_id @rubric.id, :page => page, :per_page => 50 if rubric.rubric_level >= 3#PriceListRow.by_rubric(rubric).search(:page => page, :per_page => 100) if rubric.rubric_level >= 3 | |
#ThinkingSphinx.search_count(:with => {:regions => [2]}, :classes => [Product, PriceListRow], :index_weights => {Product => 10, PriceListRow => 1}) | |
end | |
cattr_accessor :total_pages | |
cattr_accessor :current_page | |
caches_page :lastgoods, :lastgoods_frontend | |
def lastgoods_frontend | |
set_title_variables(title_header_descr_values) | |
@rows = lastgoods_items(@@rows_on_page, params[:page] || 1) | |
end | |
helper_method :lastgoods_items | |
def lastgoods_items(limit, page, rubric_filter = nil) | |
min_packet = 2 | |
unless rubric_filter.nil? | |
field = "rubric_l#{rubric_filter.level}_id" | |
# cond = ["companies.packet >= ? AND companies.state = ? AND products.state = ? AND products.rubric_l4_id > ? AND products.#{field} = ?", min_packet, 'accepted', 'accepted', 0, rubric_filter.id] | |
sph_cond = {:packet => min_packet..5, field.to_sym => rubric_filter.id} | |
else | |
# cond = ['companies.packet >= ? AND companies.state = ? AND products.state = ? AND products.rubric_l4_id > ?', min_packet, 'accepted', 'accepted', 0] | |
sph_cond = {:packet => min_packet..5} | |
end | |
# Product.paginate( | |
# :page => page, | |
# :per_page => limit, | |
# :order => 'products.created_at DESC', | |
# :include => {:company => {:main_address => :city}}, | |
# :conditions => cond | |
# ) | |
Product.search('', | |
:with => sph_cond, | |
:sort_mode => :extended, | |
:order => 'sphinx_internal_id DESC', | |
:include => {:company => {:main_address => :city}}, | |
:page => page, | |
:per_page => limit | |
) | |
end | |
def lastgoods | |
total = 100 | |
portions = 1 | |
if params[:portion] && (portion = (begin Integer params[:portion] rescue nil end)) | |
offset = total * (portion / portions) | |
limit = total / portions | |
else | |
offset = 0 | |
limit = total | |
end | |
render :json => { | |
:without_photo => _lastgoods({:limit => limit, :offset => offset, :with_photo => false}), | |
:with_photo => _lastgoods({:limit => limit, :offset => offset, :with_photo => true}) | |
} | |
end | |
def _lastgoods(options = {}) | |
limit = options[:limit] || 100 | |
offset = options[:offset] || 0 | |
images_cond = options[:with_photo] ? 'images.id IS NULL' : 'images.position = 1' | |
products = Product.all( | |
:offset => offset, | |
:limit => limit, | |
:include => [:images, {:company => :main_address}], | |
:conditions => ["NOT (companies.id IS NULL) AND (companies.state != 'deleted') AND companies.packet >= 2 AND " + images_cond], | |
:order => 'products.created_at DESC' | |
) | |
# Ассоциации напрямую неиспользуются ддя того чтобы не плодить по 200 запросов | |
cities = {} | |
Address.all(:conditions => {:id => products.map{|p| p.company.main_address.id}.uniq}, :include => :city).map{|a| cities[a.id.to_i] = a.city.name.to_s} | |
products.map do |p| | |
{ | |
:title => p.name, | |
:href => company_product_url(p.company, p), | |
:firm_title => p.company.name, | |
:firm_href => company_url(p.company), | |
#:firm_city => p.company.main_address.city.name, | |
:firm_city => cities[p.company.main_address.id.to_i], # Ассоциации напрямую неиспользуются ддя того чтобы не плодить по 200 запросов | |
:image => p.images.first ? p.images.first.img.url : false, | |
:firm_raiting => @template.raiting_star(p.company) | |
} | |
end | |
end | |
# def lastgoods | |
# # json | |
# response.headers['Content-type'] = "text/plain; charset=utf-8" | |
# limit = (params[:limit] if params[:limit].to_i > 0 && params[:limit].to_i < 10) || 1 | |
# offset = (params[:offset] if params[:offset].to_i > 0 && params[:offset].to_i < 200) || 0 | |
# | |
# images_cond = params[:nophotos] ? 'images.id IS NULL' : 'images.position = 1' | |
# | |
# products = Product.find( | |
# :all, | |
# :limit => limit, | |
# :offset => offset, | |
# :include => [:images], | |
# :joins => [:company, :rubric], | |
# :conditions => ["companies.state != 'deleted' /*AND companies.packet >= 2*/ AND "+images_cond], | |
# :order => 'products.created_at DESC' | |
# ) | |
# | |
# # prepare data | |
# data = Array.new | |
# products.each { |p| | |
# data.push({ | |
# :title => p.name, | |
# :href => company_product_url(p.company, p), | |
# :firm_title => p.company.name, | |
# :firm_href => company_url(p.company), | |
# :firm_city => p.company.main_address.city.name, | |
# :image => p.images.first ? p.images.first.img.url : '/images/firms/pic90x90.gif' | |
# }) | |
# } | |
# | |
# render :text => data.to_json | |
# end | |
protected | |
def show_rows? | |
# TODO число 2 подозрительное какое-то. надо или комент к методу или вынести в конфиг | |
rubric.level > 2 || params[:search] || rubric.next_level_normativka | |
end | |
def check_search | |
@search_query = '' | |
if params[:search] && !params[:q].nil? && params[:q] != "" | |
if !params[:rubric].nil? | |
r = Rubric.find(params[:rubric]) | |
route = current_region.default? ? "search#{params[:action]}_path".to_sym : "region_search#{params[:action]}_path".to_sym | |
options = {:q => params[:q]} | |
options[:region] = current_region.name_lat unless current_region.default? | |
if params[:search_in_rubric] && !r.nil? && !r.root? | |
options[:path] = r.path | |
# redirect_to url_for(:controller => "catalogue", | |
# :action => params[:action], | |
# :q => params[:q], | |
# :path => r.path, | |
# :region => current_region.default? ? nil : current_region.name_lat, | |
# :search => true | |
# ) | |
# return true | |
# else | |
# redirect_to url_for(:controller => "catalogue", | |
# :action => params[:action], | |
# :q => params[:q], | |
# :region => current_region.default? ? nil : current_region.name_lat, | |
# :search => true | |
# ) | |
# return true | |
end | |
return redirect_to send(route, options) | |
end | |
if params[:adv] != "1" | |
se = Search::SearchQuery.new(params[:q]) | |
else | |
# в расширенном поиске можно передать раздел, и если этот раздел не равен текущему, | |
# то надо перенаправить на нужный | |
if params[:is_demand] == "1" && params[:action] == "predl" | |
redirect_to url_for(:overwrite_params => {:action => "spros"}) | |
return true | |
end | |
if params[:is_demand] != "1" && params[:action] == "spros" | |
redirect_to url_for(:overwrite_params => {:action => "predl"}) | |
return true | |
end | |
if !params[:q].instance_of? HashWithIndifferentAccess | |
q = {:all => params[:q], :any => "", :without => ""} | |
else | |
q = {:all => params[:q][:all], :any => params[:q][:any], :without => params[:q][:without]} | |
end | |
se = Search::SearchQueryAdvanced.new(q[:any], q[:all], q[:without]) | |
end | |
@search_query = se.prepared | |
end | |
return false | |
end | |
def advanced_search_mod | |
if params[:search] && params[:adv] == "1" | |
if params[:price].instance_of? HashWithIndifferentAccess | |
# макс/мин цена - разные условия | |
# TODO мин и макс вынести в конфиг | |
min = 0.0 | |
max = 2000000000.0 | |
if params[:price][:min].to_f > 0 | |
min = params[:price][:min].to_f | |
end | |
if params[:price][:max].to_f > 0 | |
max = params[:price][:max].to_f | |
end | |
if min > max | |
min, max = max, min | |
end | |
@count_demand[:price_uni] = min..max | |
end | |
end | |
end | |
def load_rubrics( with_args ) | |
if 0==rubric.level | |
# если поиск по всем предложениям, то надо | |
# проверить рубрики, начиная с 2 уровня | |
# и если на каком-то уровне выяснится, что получилась только одна рубрика, | |
# то надо сделать редирект туда | |
if params[:search] | |
facets = [:rubric_l2_id, :rubric_l3_id, :rubric_l4_id] | |
sph_data = ThinkingSphinx.facets( | |
@search_query, | |
:with => with_args, | |
:facets => facets, | |
:classes => [Product, PriceListRow], | |
:match_mode => :extended | |
) | |
redirect_rubric = nil | |
facets.each { |facet| | |
data = sph_data[facet] | |
# delete NULL data | |
data.delete(0) | |
if data.length == 1 | |
redirect_rubric = Rubric.find(data.to_a.first[0]) | |
end | |
} | |
if !redirect_rubric.nil? | |
redirect_to url_for(:overwrite_params => {:path => redirect_rubric.path}) | |
return | |
end | |
end | |
if @search_query != '' | |
@rubrics = load_level3_rubrics_for_search( with_args ) | |
else | |
@rubrics = load_root_rubrics( with_args ) | |
end | |
end | |
if rubric.level > 0 | |
unless @search_query.blank? | |
@rubrics = load_descendant_rubrics_for_search( with_args ) | |
else | |
@rubrics = load_descendant_rubrics( with_args ) | |
end | |
end | |
end | |
def load_descendant_rubrics( with_args ) | |
stat_field = 'predl_stat' | |
stat_field = 'spros_stat' if params[:action] == "spros" | |
stat_field = 'providers_stat_predl' if params[:action] == "predlfirms" | |
stat_field = 'providers_stat_spros' if params[:action] == "sprosfirms" | |
rubrics = Rubric.find_by_sql(['SELECT *, NULL AS prefix_normativka FROM get_catalogue_rubricator(?, ?, ?)', rubric.id, current_region.id, stat_field]) | |
rubrics_result = [] | |
rubrics.each do |r| | |
if r.cached_level == rubric.cached_level + 1 | |
r.descendants_rubrics = [] # создаем задел под рубрики 3-го уровня | |
r.rows_count_in_current_region = r.current_region_stats | |
r.rows_count_in_total = current_region.default? ? nil : r.default_region_stats | |
rubrics_result << r | |
else | |
if rubrics_result.last.id == r.parent_id && !rubrics_result.last.descendants_rubrics.nil? | |
rubrics_result[rubrics_result.length - 1].descendants_rubrics << r | |
end | |
end | |
end | |
return rubrics_result | |
end | |
def load_descendant_rubrics_for_search( with_args ) | |
# очевидно, что если рубрика и так последняя, то ничего загружать не надо | |
# рубрика также будет являться последней, ежели её slug будет числом | |
if rubric.leaf? || rubric.is_normativka? || (rubric.slug =~ /\d+/) != nil | |
return [] | |
end | |
# загружаем рубрики дочерние | |
rubrics_cnt = rubric.children_with_count_in(current_region.id, @search_query, with_args) | |
unless current_region.default? | |
rubrics_cnt_total = rubric.children_with_count_in(Region::DEFAULT_REGION, @search_query, with_args) | |
else | |
rubrics_cnt_total = {} | |
end | |
#debugger | |
rubric_fields = ['id', 'parent_id', 'title', 'joined_path', 'is_normativka', 'prefix_normativka', | |
'next_level_normativka', 'lft', 'rgt', 'cached_level'] | |
rubrics = Rubric.find(:all, :select => rubric_fields.join(', '), :conditions => {:id => rubrics_cnt.keys}) | |
# sort by (search = count, listing = lft) | |
rubrics = rubrics.sort { |a,b| | |
(@search_query.is_a?(String) && @search_query != "") || rubric.next_level_normativka? ? | |
rubrics_cnt[b.id] <=> rubrics_cnt[a.id] : | |
a.lft <=> b.lft | |
} | |
result = [] | |
all_children_ids = [] # все IDы рубрик нижнего уровня (мы их загрузим потом и все сразу) | |
rubrics.each_index do |i| | |
r = rubrics[i] | |
next if r.id == rubric.id | |
rubrics[i].descendants_rubrics = [] | |
children_hash = {} | |
# подгрузить детяк | |
unless r.leaf? || r.cached_level == 5 || rubric.next_level_normativka? | |
children_cnt = r.children_with_count_in(current_region.id, @search_query, with_args) | |
children_cnt.delete(r.id) | |
children_cnt.delete(rubric.id) | |
#load-load-load | |
unless children_cnt.nil? | |
# надо отсортировать рубрики по количеству в них найденного | |
children_cnt_ar = children_cnt.sort {|a,b| b[1] <=> a[1]}[0..7] | |
children_cnt = {} | |
children_cnt_ar.each do |a| | |
children_cnt[a[0]] = a[1] | |
end | |
#children = Rubric.find(children_cnt.keys) | |
all_children_ids << children_cnt.keys | |
rubrics[i].descendants_rubrics = children_cnt.keys | |
end | |
end | |
rubrics[i].rows_count_in_current_region = rubrics_cnt[r.id] | |
rubrics[i].rows_count_in_total = rubrics_cnt_total[r.id] | |
#result.push(rubrics[i]) | |
end | |
if all_children_ids.length > 0 | |
children_rubrics_hash = {} | |
Rubric.find(:all, :conditions => {:id => all_children_ids.flatten.uniq}).each do |r| children_rubrics_hash[r.id] = r end | |
rubrics.each_index do |i| | |
if !rubrics[i].descendants_rubrics.nil? && rubrics[i].descendants_rubrics.length > 0 | |
children = [] | |
rubrics[i].descendants_rubrics.each do |id| | |
children << children_rubrics_hash[id] unless children_rubrics_hash[id].nil? | |
end | |
rubrics[i].descendants_rubrics = children | |
end | |
result << rubrics[i] | |
end | |
else | |
result = rubrics | |
end | |
result | |
end | |
def load_level3_rubrics_for_search( with_args ) | |
level3_cnt = Rubric.rubrics_l3_with_count_in(current_region.id, @search_query, with_args) | |
unless current_region.default? | |
level3_cnt_total = Rubric.rubrics_l3_with_count_in(Region::DEFAULT_REGION, @search_query, with_args.merge(:rubric_l3_id => level3_cnt.keys)) | |
else | |
level3_cnt_total = {} | |
end | |
#load | |
rubrics = Rubric.find(:all, :conditions => {:id => level3_cnt.keys}) | |
rubrics.each do |r| | |
r.rows_count_in_current_region = level3_cnt[r.id] # кол-во | |
r.rows_count_in_total = level3_cnt_total[r.id] | |
end | |
rubrics.sort { |a, b| b.rows_count_in_current_region <=> a.rows_count_in_current_region } | |
end | |
def load_root_rubrics( with_args ) | |
stat_field = 'predl_stat' | |
stat_field = 'spros_stat' if params[:action] == "spros" | |
stat_field = 'providers_stat_predl' if params[:action] == "predlfirms" | |
stat_field = 'providers_stat_spros' if params[:action] == "sprosfirms" | |
max_level = params[:action] == "spros" || params[:action] == "sprosfirms" ? 2 : 3 | |
rubrics = Rubric.find_by_sql(['SELECT * FROM get_catalogue_root_rubricator(?, ?, ?)', current_region.id, max_level, stat_field]) | |
rubrics_lvl1 = {} | |
rubrics_lvl2 = [] | |
rubrics.each do |r| | |
if r.cached_level == 1 | |
rubrics_lvl1[r.id] = r | |
elsif r.cached_level == 2 | |
unless rubrics_lvl1[r.parent_id].nil? | |
r.parent_rubric = rubrics_lvl1[r.parent_id] # запоминаем родительскую рубрику | |
r.descendants_rubrics = [] # создаем задел под рубрики 3-го уровня | |
r.rows_count_in_current_region = r.current_region_stats | |
r.rows_count_in_total = current_region.default? ? nil : r.default_region_stats | |
rubrics_lvl2 << r | |
end | |
else | |
if rubrics_lvl2.last.id == r.parent_id && !rubrics_lvl2.last.descendants_rubrics.nil? | |
rubrics_lvl2[rubrics_lvl2.length - 1].descendants_rubrics << r | |
end | |
end | |
end | |
return rubrics_lvl2 | |
end | |
def rubric | |
@rubric ||= (params[:path].nil? || params[:path].length == 0 ? Rubric.root : Rubric.with_path(params[:path]).first) | |
end | |
def try_rubric_with_old_url | |
self.http_headers_section = :without_rows | |
rubric = Rubric.with_old_path(params[:path]).first | |
if !rubric.nil? | |
return redirect_to( url_for({:overwrite_params => {:path => rubric.path}}) , :status => 301) | |
else | |
return not_found | |
end | |
end | |
def page | |
@page ||= params[:page] || 1 | |
end | |
def industry | |
@industry ||= Industry.with_path(params[:path]).first(:conditions => {:link_to => nil}) | |
end | |
def firms_query_conditions | |
conditions = { | |
:industries => industry.id, | |
:show_portal => 1 | |
} | |
conditions[:regions] = current_region.id if !current_region.default? | |
if !params[:letter].nil? && params[:letter].instance_of?(String) | |
if params[:letter] == '0-9' | |
conditions[:first_letter_ord] = ('0'.ord..'9'.ord).to_a | |
elsif params[:letter].mb_chars.length == 1 | |
params[:letter] = params[:letter].mb_chars.downcase | |
params[:letter] = 'е' if params[:letter] == 'ё' | |
conditions[:first_letter_ord] = params[:letter].mb_chars.ord | |
end | |
end | |
return conditions | |
end | |
def title | |
key = @page_title_key ? @page_title_key : 'title' | |
{:key => "#{@page_title_section}.#{key}", | |
:values => title_header_descr_values | |
} | |
end | |
def header | |
{:key => "#{@page_title_section}.h1", | |
:values => title_header_descr_values} | |
end | |
def description | |
{:key => "#{@page_title_section}.description", | |
:values => title_header_descr_values} | |
end | |
def title_header_descr_values | |
{:REGION => current_region.name, | |
:REGION_GENITIVE => current_region.name_genitive, | |
:RUBRIC => params[:action] == "firms" ? industry.title : (rubric.is_normativka? ? "#{rubric.prefix_normativka} #{rubric.title}" : rubric.title), | |
:SYNONYM => !rubric.nil? && !rubric.root? ? rubric.synonym : '', | |
:QUERY => params[:q] | |
} | |
end | |
def load_linked_objects_for_rows!(rows) | |
# 1. companies | |
companies_ids = rows.map(&:company_id) | |
# load predl count for companies | |
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false}) | |
# load including first address, representative users and cities | |
companies_fields = ['id', 'name', 'packet', 'has_email'] | |
companies = Company.find(companies_ids, :select => companies_fields.join(', '), :include => [:representative, {:main_address => {:city => :city_type}}]) | |
companies_hash = {} | |
companies.each do |c| | |
c.predl_count = predl_count[c.id] || 0 | |
companies_hash[c.id] = c | |
end | |
# first addresses in region | |
unless current_region.default? | |
first_addresses = CompanyRegionCommercial.find( | |
:all, | |
:conditions => {:company_id => companies_ids, :region_id => current_region.id}, | |
:include => {:address => {:city => :city_type}} | |
) | |
first_addresses.each do |a| | |
next if companies_hash[a.company_id].nil? | |
companies_hash[a.company_id].computed_first_address = a.address | |
end | |
end | |
products_ids = [] | |
rows.each_index do |i| | |
rows[i].company = companies_hash[rows[i].company_id] | |
products_ids << rows[i].id if rows[i].is_a?(Product) | |
end | |
# load images for products | |
if products_ids.length > 0 | |
images = Image.find(:all, | |
:select => 'id, subject_type, subject_id, img_file_name', | |
:conditions => {:subject_type => 'Product', :subject_id => products_ids}, | |
:order => "position DESC") | |
images_hash = {} | |
images.each do |img| | |
images_hash[img.subject_id.to_i] = img | |
end | |
rows.each_index do |i| | |
if rows[i].is_a?(Product) && images_hash[rows[i].id.to_i] | |
rows[i].first_image = images_hash[rows[i].id.to_i] | |
end | |
end | |
end | |
rows | |
end | |
def load_companies_by_ids(companies_ids) | |
unless companies_ids.blank? | |
companies = Company.find(companies_ids, :include => [:company_logo]) | |
# load predl count for companies | |
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false}) | |
companies_hash = {} | |
if companies.is_a?(Company) | |
companies.predl_count = predl_count[companies.id] | |
companies_hash[companies.id] = companies | |
else | |
companies.each do |c| | |
c.predl_count = predl_count[c.id] | |
companies_hash[c.id] = c | |
end | |
end | |
res = [] | |
companies_ids.each do |id| | |
res << companies_hash[id] | |
end | |
else | |
res = [] | |
end | |
def res.sph_result=(r) | |
@sph = r | |
end | |
def res.total_pages | |
@sph.total_pages | |
end | |
def res.current_page | |
@sph.current_page | |
end | |
def res.next_page | |
@sph.next_page | |
end | |
def res.previous_page | |
@sph.previous_page | |
end | |
def res.total_entries | |
@sph.total_entries | |
end | |
res.sph_result = companies_ids | |
res | |
end | |
def http_headers_opts | |
now = Time.now | |
opts = {:config_scope => self.http_headers_section.to_s} | |
if self.http_headers_section == :with_rows | |
# Last-Modified - каждый час | |
opts[:headers] = {'Last-Modified' => Time.local(now.year, now.month, now.day, now.hour, 0, 1)} | |
end | |
if self.http_headers_section == :without_rows | |
# Last-Modified - 00:00:01 текущего дня | |
opts[:headers] = {'Last-Modified' => Time.local(now.year, now.month, now.day, 0, 0, 1)} | |
end | |
opts | |
end | |
helper_method :rubric | |
helper_method :page | |
helper_method :industry | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment