public function up() { $dir = fx::path('@floxim/update/migration'); // get migrations $migration_files = glob($dir . '/*.php'); if (!$migration_files) { return; } $migration_names = array(); foreach ($migration_files as $migration_file) { $info = pathinfo($migration_file); $paths = explode('_', $info['filename']); $paths = array_slice($paths, 0, 2); $migration_names[join('_', $paths)] = $info['filename']; } asort($migration_names); // get completed migration $migrations_completed = fx::data('patch_migration')->all(); if ($migrations_completed_name = $migrations_completed->getValues('name')) { $migration_names = array_diff_key($migration_names, array_combine($migrations_completed_name, array_fill(0, count($migrations_completed_name), 1))); } // run migrations $count = 0; foreach ($migration_names as $name_full) { $file = $dir . DIRECTORY_SEPARATOR . $name_full . '.php'; if (file_exists($file)) { require_once $file; $migration = new $name_full(); $migration->execUp(); $count++; } } // todo: need fix echo 'Count run new migrations: ' . $count; }
public function execDown() { $name = $this->getName(); // check not exec run if (!($migration = fx::data('patch_migration')->where('name', $name)->one())) { return; } // exec $this->down(); // remove mark $migration->delete(); }
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; }); return $result; }
/** * Добавляет коллбэк на обновление ID * * @param $itemType * @param $itemIdNew * @param $linkType * @param $linkIdOld * @param $linkField */ protected function addCallbackIdUpdate($itemType, &$itemIdNew, $linkType, $linkIdOld, $linkField) { $_this = $this; $this->callbackIdUpdateStack[] = function () use($_this, $itemType, &$itemIdNew, $linkType, $linkIdOld, $linkField) { $itemNew = fx::data($itemType, $itemIdNew); if ($itemNew and false !== ($idNew = $_this->getIdNewForType($linkIdOld, $linkType))) { $itemNew[$linkField] = $idNew; if ($itemType == 'infoblock_visual') { $itemNew->setNeedRecountFiles(false); } $itemNew->save(); } }; }
protected function processingLinkedField($linkedField, $value, $itemId, &$linkedContent, &$linkedSystemItems) { if ($linkedField['type'] == \Floxim\Floxim\Component\Field\Entity::FIELD_LINK) { /** * Линкуемое значение */ if (!$value) { return; } if (!is_array($value)) { $value = array($value); } /** * Обработка связи "один к одному" */ if ($linkedField['target_type'] == 'component') { /** * Добавляем линкуемый компонент в число экспортируемых * todo: скорее всего это можно пропустить, т.к. при экспорте дерева контента все-равно получается компонент */ $this->componentsForExport[] = $linkedField['target_id']; /** * Пропускаем те элементы, которые уже есть в списке * todo: Проверить пропуск этого условия */ /** * if (isset($usedTypes[$linkedField['target_id']]) and in_array($value, * $usedTypes[$linkedField['target_id']]) * ) { * return; * } */ /** * Формируем новый список ID элементов контента * Для каждого такого элемента необходимо будет получить полное дочернее дерево * Еще проблема в том, что тип из настроек поля может не совпадать с фактическим конечным типом элемента */ $linkedContent = array_merge($linkedContent, $value); } elseif ($linkedField['target_type'] == 'system') { if (!isset($linkedSystemItems[$linkedField['target_id']])) { $linkedSystemItems[$linkedField['target_id']] = array(); } $linkedSystemItems[$linkedField['target_id']] = array_merge($linkedSystemItems[$linkedField['target_id']], $value); } } elseif ($linkedField['type'] == \Floxim\Floxim\Component\Field\Entity::FIELD_MULTILINK) { /** * Обработка связи "один ко многим" */ if ($linkedField['type-many'] == 'has-many') { /** * Варианта два: * 1 - переданы конкретные значения в $value (используется в условиях инфоблоков) * 2 - передан id обрабатываемого элемента $itemId (используется для получения связей конкретного элемента) */ if ($itemId) { /** * Получаем список элементов контента */ $finder = fx::data($linkedField['linking_component']); $contents = $finder->where($linkedField['linking_field'], $itemId)->all()->getValues('id'); $linkedContent = array_merge($linkedContent, $contents); } else { if (!$value) { return; } if (!is_array($value)) { $value = array($value); } $linkedContent = array_merge($linkedContent, $value); } } elseif ($linkedField['type-many'] == 'many-many') { /** * Обработка связи "много ко многим" */ $finder = fx::data($linkedField['linking_component']); $linkers = $finder->where($linkedField['linking_field'], $itemId)->all()->getValues($linkedField['mm_field']); $linkedContent = array_merge($linkedContent, $linkers); /** * Добавляем линкуемый компонент в число экспортируемых * todo: скорее всего это можно пропустить, т.к. при экспорте дерева контента все-равно получается компонент */ $this->componentsForExport[] = $linkedContent['mm_component']; } } }
/** template entity interface */ public function getFinder() { return fx::data($this->getType()); }
public static function alang($string = null, $dict = null) { static $lang = null; if (!$lang) { $lang = fx::data('lang_string'); $lang->setLang(); } if ($string === null) { return $lang; } if (!($res = $lang->getString($string, $dict))) { try { $lang->addString($string, $dict); } catch (\Exception $e) { fx::log('exc', $e); } $res = $string; } if (func_num_args() > 2) { $replacements = array_slice(func_get_args(), 2); array_unshift($replacements, $res); $res = call_user_func_array('sprintf', $replacements); } return $res; }
/** * */ public function dumpSiteData($site_id = null, $target_file = null) { if (is_null($site_id)) { $site_id = fx::env('site_id'); } if (is_null($target_file)) { $dir = '@files/export/site_' . $site_id; fx::files()->mkdir($dir); $target_file = fx::path()->abs($dir . '/data.sql'); } // export the site fx::db()->dump(array('tables' => array('site'), 'where' => 'id = ' . $site_id, 'schema' => false, 'file' => $target_file)); // export infoblocks fx::db()->dump(array('tables' => array('infoblock'), 'where' => 'site_id = ' . $site_id, 'schema' => false, 'file' => $target_file, 'add' => true)); // export URL aliases fx::db()->dump(array('tables' => array('url_alias'), 'where' => 'site_id = ' . $site_id, 'schema' => false, 'file' => $target_file, 'add' => true)); // export infoblock_visual $infoblock_ids = fx::data('infoblock')->where('site_id', $site_id)->all()->getValues('id'); fx::db()->dump(array('tables' => array('infoblock_visual'), 'where' => 'infoblock_id IN (' . join(", ", $infoblock_ids) . ')', 'schema' => false, 'file' => $target_file, 'add' => true)); // export main content table fx::db()->dump(array('tables' => array('floxim_main_content'), 'where' => 'site_id = ' . $site_id, 'schema' => false, 'file' => $target_file, 'add' => true)); // get existing content items $items = fx::db()->getResults('select id, type from {{floxim_main_content}} where site_id = ' . $site_id); $tables = $this->getContentDumpTables(fx::collection($items)); foreach ($tables as $t => $item_ids) { if ($t === 'floxim_main_content') { continue; } // export content table fx::db()->dump(array('tables' => array($t), 'where' => 'id IN (' . join(',', $item_ids) . ')', 'schema' => false, 'file' => $target_file, 'add' => true)); } }
protected function up() { \fx::data('floxim.main.page')->all()->apply(function ($c) { $c->set('url', preg_replace("~^/~", '', $c['url']))->save(); }); }
public function addRelated($rel_name, $entities, $rel_finder = null) { $relations = $this->relations(); if (!isset($relations[$rel_name])) { return; } $rel = $relations[$rel_name]; if (!isset($rel[3])) { $rel[3] = null; } list($rel_type, $rel_datatype, $rel_field, $rel_target_field) = $rel; if (!$rel_finder) { $rel_finder = $this->getDefaultRelationFinder($rel); } // e.g. $rel = array(fx_data::HAS_MANY, 'field', 'component_id'); switch ($rel_type) { case self::BELONGS_TO: if (!$rel_target_field) { $rel_target_field = 'id'; } $rel_item_ids = array(); foreach ($entities as $entity) { $rel_id = $entity[$rel_field]; if ($rel_id) { $rel_item_ids[] = $rel_id; } } if (count($rel_item_ids) > 0) { $rel_items = $rel_finder->where($rel_target_field, $rel_item_ids)->all(); $entities->attach($rel_items, $rel_field, $rel_name, $rel_target_field); } break; case self::HAS_MANY: $rel_items = $rel_finder->where($rel_field, $entities->getValues('id'))->all(); $entities->attachMany($rel_items, $rel_field, $rel_name); break; case self::HAS_ONE: break; case self::MANY_MANY: $end_rel = $rel[3]; // removed to related entities // only with a non-empty field in which relate $end_rel_data = $rel_finder->relations(); $end_rel_field = $end_rel_data[$end_rel][2]; // $rel[4] is the data type for many-many $end_finder = null; if (isset($rel[4])) { $end_rel_datatype = $rel[4]; $end_finder = fx::data($end_rel_datatype); } $rel_finder->with($end_rel, $end_finder)->where($rel_field, $entities->getValues('id')); if ($end_rel_field) { $rel_finder->where($end_rel_field, 0, '!='); } $rel_items = $rel_finder->all()->find($end_rel, null, '!='); $entities->attachMany($rel_items, $rel_field, $rel_name, 'id', $end_rel, $end_rel_field); break; } }
public function getLayout() { if (!isset($this->current['layout'])) { if ($preview_id = self::getLayoutPreview()) { $this->current['layout'] = $preview_id; return $preview_id; } $page_id = $this->getPageId(); if ($page_id) { $page = fx::data('page', $page_id); if ($page['layout_id']) { $this->current['layout'] = $page['layout_id']; } } if (!isset($this->current['layout'])) { $this->current['layout'] = $this->getSite()->get('layout_id'); } if (!isset($this->current['layout'])) { $this->current['layout'] = fx::data('layout')->one()->get('id'); } } return $this->current['layout']; }
/** * Store params by keys in DB * * @param $keys */ public function store($keys) { if (!is_array($keys)) { $keys = array($keys); } foreach ($keys as $key) { if (!($option = fx::data('option')->where('keyword', $key)->one())) { $option = fx::data('option')->create(array('keyword' => $key)); } $option['value'] = $this->get($key); $option->save(); } }
/** * Generate code for update field * * @param $params * * @return string */ protected function createAfterForFieldUpdate($params) { $field = $params['field']; $modified = $field->getModified(); $data = array(); foreach ($modified as $key) { $data[$key] = $field[$key]; } $keyword = in_array('keyword', $modified) ? $field->getOld('keyword') : $field['keyword']; $code = '$data=' . var_export($data, true) . ";\n"; $component = fx::data("component", $field['component_id']); $code .= ' $component=fx::data("component")->where("keyword", "' . $component['keyword'] . '")->one(); $field=fx::data("field")->where("keyword","' . $keyword . '")->where("component_id",$component["id"])->one(); if ($field) { foreach($data as $k=>$v) { $field[$k]=$v; } $field->save(); } '; return $code; }