module Optimacms module PageServices class PageRouteService def self.find_page_by_url(url, lang='') where_base = 'is_folder = 0 AND enabled = 1 AND ' order = 'url_parts_count DESC, url_vars_count ASC' if url.blank? where = where_base + 'url = \'\'' else #where = where_base + '\'' + url + '\' REGEXP parsed_url' where = where_base + '\'' + url + '\''+ " REGEXP parsed_url" end # result pagedata = PageData.new pagedata.url = url # try 1 rows = Page.where(where).order(order).all pagedata.page = rows[0] if rows.count>0 # try 2 if pagedata.page.nil? && url.blank? where = where_base + "url = '#{lang}'" rows = Page.where(where).order(order).all pagedata.page = rows[0] if row.count>0 end return pagedata if pagedata.page.nil? # controller if pagedata.page.controller_action.present? pagedata.controller, pagedata.action = parse_controller_action(pagedata.page.controller_action) pagedata.url_vars = get_url_vars(pagedata.url, pagedata.page) end pagedata end def self.parse_controller_action(s) m = s.match /^(\w+)#(\w+)$/ if m [m[1], m[2]] else return nil end end def self.parse_url(url) if url.blank? return '^$' end url_parts = url.split '/' a = [] url_parts.each do |part| # Проверяем, нет ли вложенных фигурных скобок return nil if part =~ /\{[^{}]*[{}][^{}]*\}/ # Проверяем, нет ли одиночных фигурных скобок или знака $ без скобки или знака { без $ return nil if part =~ /(\{[^}]*$|^[^{]*\}|[^{]\$|\{[^\$])/ # Экранируем служебные символы # Точку заменяем на символьный класс вместо простого экранирования т.к. это надежнее. # Например, одинарное экранирование пропадает при записи в базу p = part p.sub! '.', '[.]' # Заменяем переменные на шаблон #p.gsub! /\{\$[^}]+\}/, '([^\/]+)' p.gsub! /\{\$[^}]+\}/, '([^/]+)' a << p end return '^'+url_parts.join('\/') end def self.count_url_parts(url) url_parts = url.split '/' n = url_parts.count # Если после последнего / ничего нет, уменьшаем количество частей URL на 1 n-=1 if url_parts.last == '' n end def self.count_url_vars(url) m = url.scan /\{\$[^}]+\}/ m.count end def self.get_url_vars(url, page_row) return [] if page_row.nil? return [] if url.blank? parsed_url = page_row.parsed_url.sub '/', '\/' #if (preg_match('/' . $parsed_url . '/', $url, $values_matches)) { m_params_in_url = url.scan /#{parsed_url}/ return nil if m_params_in_url.empty? values_matches = m_params_in_url[0] # search for variables in URL #if (preg_match_all('/\{\$([^}\/]+)\}/', $page_row['url'], $keys_matches)) keys_matches = page_row.url.scan /\{\$([^}\/]+)\}/ if !keys_matches.empty? keys_matches = keys_matches.map{|r| r[0]} if keys_matches.count == values_matches.count res = {} values_matches.each_with_index do |val, key| res[keys_matches[key]] = val end #url_vars = array_combine($keys_matches, $values_matches); return res else #user_error('Keys and values has different number of elements'); return [] end elsif m_params_in_url.count == 0 # Если переменные не найдены, но и в parsed_url не было переменных - возвращаем пустой массив return [] else # что-то не так return [] end end end end end