public function getAvailableTemplates($layout_name = null, $area_meta = null) { $area_size = Template\Suitable::getSize($area_meta['size']); $layout_defined = !is_null($layout_name); if (is_numeric($layout_name)) { $layout_names = array(fx::data('layout', $layout_name)->get('keyword')); } elseif (is_null($layout_name)) { $layout_names = fx::data('layout')->all()->getValues('keyword'); } elseif (is_string($layout_name)) { $layout_names = array($layout_name); } elseif (is_array($layout_name)) { $layout_names = $layout_name; } // get acceptable controller $controller_variants = $this->getControllerVariants(); foreach ($controller_variants as $controller_variant) { fx::template()->import($controller_variant); } // this will be used to restrict allowed templates by config 'ignore' directive $theme_template = null; $layout_classes = array(); foreach ($layout_names as $layout_name) { $layout_classes[] = fx::template()->import('theme.' . $layout_name); } if (count($layout_names) === 1) { $theme_template = fx::template('theme.' . end($layout_names)); } $imported_classes = fx::template()->getImportedClasses(); $template_variants = array(); foreach ($imported_classes as $class) { if (!$class) { continue; } // ignore templates from layouts not listed in arg if (preg_match("~^fx_template_theme~", $class) && !in_array($class, $layout_classes)) { continue; } $template_variants = array_merge($template_variants, call_user_func(array($class, 'getTemplateVariants'))); } // now - filtered $result = array(); $replace = array(); foreach ($template_variants as $k => $tplv) { if (isset($tplv['is_abstract'])) { continue; } if (!isset($tplv['of']) || !is_array($tplv['of'])) { continue; } foreach ($tplv['of'] as $tpl_of => $tpl_of_priority) { $of_parts = explode(":", $tpl_of); if (count($of_parts) != 2) { continue; } list($tpl_of_controller, $tpl_of_action) = $of_parts; $tpl_of_action = fx::util()->underscoreToCamel($tpl_of_action, false); if (!in_array($tpl_of_controller, $controller_variants)) { continue; } // the first controller variant is the most precious if (strpos($this->action, $tpl_of_action) !== 0) { continue; } // if template action exactly matches current controller action $tplv['action_match_rate'] = $this->action == $tpl_of_action ? 1 : 0; if (isset($tplv['suit']) && $area_meta) { $tplv_areas = explode(",", preg_replace("~\\s+~", '', $tplv['suit'])); if (in_array('local', $tplv_areas)) { $tplv_areas[] = $tplv['area']; } if (!in_array($area_meta['id'], $tplv_areas)) { continue; } } // if current layout is defined, we should rate layout templates greater than standard ones $tplv['layout_match_rate'] = $layout_defined && preg_match("~^theme\\.~", $tplv['full_id']) ? 1 : 0; if ($area_size && isset($tplv['size'])) { $size = Template\Suitable::getSize($tplv['size']); $size_rate = Template\Suitable::checkSizes($size, $area_size); if (!$size_rate) { continue; } $tplv['size_rate'] = $size_rate; } if ($theme_template && !$theme_template->isTemplateAllowed($tplv['full_id'])) { continue; } if (!isset($tplv['of_priority']) || $tplv['of_priority'] < $tpl_of_priority) { $tplv['of_priority'] = $tpl_of_priority; } $result[$tplv['full_id']] = $tplv; if ($tplv['is_preset_of'] && $tplv['replace_original']) { $replace[] = $tplv['is_preset_of']; } } } foreach ($replace as $rep_id) { unset($result[$rep_id]); } usort($result, function ($a, $b) { $action_diff = $b['action_match_rate'] - $a['action_match_rate']; if ($action_diff != 0) { return $action_diff; } $prior_diff = $b['of_priority'] - $a['of_priority']; if ($prior_diff !== 0) { return $prior_diff; } $layout_diff = $b['layout_match_rate'] - $a['layout_match_rate']; if ($layout_diff != 0) { return $layout_diff; } return 0; }); fx::cdebug($result); return $result; }