Kami
-
Публикаций
559 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные Kami
-
-
5 часов назад, phukortsin сказал:
Все это можно делать по аналогии. Но код не совсем простой и довольно объемный, требуется аккуратность...
Ну не прям объемный, но да, внимательно надо отнестись к запросам при копировании связанных.
-
15 часов назад, megauser сказал:
Есть связанные товары в товаре, А кто делал для обычной страницы товары?
На форуме что то не нашел ничего похожего.
Чтоб не разжевывать скинул полные файлы, ищи в коде комменты
/*related_page_products*/ /*/related_page_products*/
Запрос в базу
CREATE TABLE `s_related_page_products` ( `page_id` int(11) NOT NULL, `related_id` int(11) NOT NULL, `position` int(11) NOT NULL, PRIMARY KEY (`page_id`,`related_id`), KEY `position` (`position`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
api/Pages.php
<?php /** * Simpla CMS * * @copyright 2011 Denis Pikusov * @link http://simplacms.ru * @author Denis Pikusov * */ require_once('Simpla.php'); class Pages extends Simpla { /* * * Функция возвращает страницу по ее id или url (в зависимости от типа) * @param $id id или url страницы * */ public function get_page($id) { if(gettype($id) == 'string') $where = $this->db->placehold(' WHERE url=? ', $id); else $where = $this->db->placehold(' WHERE id=? ', intval($id)); $query = "SELECT id, url, header, name, meta_title, meta_description, meta_keywords, body, menu_id, position, visible FROM __pages $where LIMIT 1"; $this->db->query($query); return $this->db->result(); } /* * * Функция возвращает массив страниц, удовлетворяющих фильтру * @param $filter * */ public function get_pages($filter = array()) { $menu_filter = ''; $visible_filter = ''; $pages = array(); if(isset($filter['menu_id'])) $menu_filter = $this->db->placehold('AND menu_id in (?@)', (array)$filter['menu_id']); if(isset($filter['visible'])) $visible_filter = $this->db->placehold('AND visible = ?', intval($filter['visible'])); $query = "SELECT id, url, header, name, meta_title, meta_description, meta_keywords, body, menu_id, position, visible FROM __pages WHERE 1 $menu_filter $visible_filter ORDER BY position"; $this->db->query($query); foreach($this->db->results() as $page) $pages[$page->id] = $page; return $pages; } /* * * Создание страницы * */ public function add_page($page) { $query = $this->db->placehold('INSERT INTO __pages SET ?%', $page); if(!$this->db->query($query)) return false; $id = $this->db->insert_id(); $this->db->query("UPDATE __pages SET position=id WHERE id=?", $id); return $id; } /* * * Обновить страницу * */ public function update_page($id, $page) { $query = $this->db->placehold('UPDATE __pages SET ?% WHERE id in (?@)', $page, (array)$id); if(!$this->db->query($query)) return false; return $id; } /* * * Удалить страницу * */ public function delete_page($id) { if(!empty($id)) { /*related_page_products*/ $this->db->query('DELETE FROM __related_page_products WHERE page_id=?', intval($id)); /*/related_page_products*/ $query = $this->db->placehold("DELETE FROM __pages WHERE id=? LIMIT 1", intval($id)); if($this->db->query($query)) return true; } return false; } /*related_page_products*/ function get_related_products($page_id = array()) { if(empty($page_id)) return array(); $page_id_filter = $this->db->placehold('AND page_id in(?@)', (array)$page_id); $query = $this->db->placehold("SELECT page_id, related_id, position FROM __related_page_products WHERE 1 $page_id_filter ORDER BY position "); $this->db->query($query); return $this->db->results(); } // Функция возвращает связанные товары public function add_related_product($page_id, $related_id, $position=0) { $query = $this->db->placehold("INSERT IGNORE INTO __related_page_products SET page_id=?, related_id=?, position=?", $page_id, $related_id, $position); $this->db->query($query); return $related_id; } // Удаление связанного товара public function delete_related_product($page_id, $related_id) { $query = $this->db->placehold("DELETE FROM __related_page_products WHERE page_id=? AND related_id=? LIMIT 1", intval($page_id), intval($related_id)); $this->db->query($query); } /*/related_page_products*/ /* * * Функция возвращает массив меню * */ public function get_menus() { $menus = array(); $query = "SELECT * FROM __menu ORDER BY position"; $this->db->query($query); foreach($this->db->results() as $menu) $menus[$menu->id] = $menu; return $menus; } /* * * Функция возвращает меню по id * @param $id * */ public function get_menu($menu_id) { $query = $this->db->placehold("SELECT * FROM __menu WHERE id=? LIMIT 1", intval($menu_id)); $this->db->query($query); return $this->db->result(); } }
simpla/PageAdmin.php
<?PHP require_once('api/Simpla.php'); class PageAdmin extends Simpla { public function fetch() { $page = new stdClass; /*related_page_products*/ $related_products = array(); /*/related_page_products*/ if($this->request->method('POST')) { $page->id = $this->request->post('id', 'integer'); $page->name = $this->request->post('name'); $page->header = $this->request->post('header'); $page->url = trim($this->request->post('url')); $page->meta_title = $this->request->post('meta_title'); $page->meta_keywords = $this->request->post('meta_keywords'); $page->meta_description = $this->request->post('meta_description'); $page->body = $this->request->post('body'); $page->menu_id = $this->request->post('menu_id', 'integer'); $page->visible = $this->request->post('visible', 'boolean'); ## Не допустить одинаковые URL разделов. if(($p = $this->pages->get_page($page->url)) && $p->id!=$page->id) { $this->design->assign('message_error', 'url_exists'); } else { if(empty($page->id)) { $page->id = $this->pages->add_page($page); $page = $this->pages->get_page($page->id); $this->design->assign('message_success', 'added'); } else { $this->pages->update_page($page->id, $page); $page = $this->pages->get_page($page->id); $this->design->assign('message_success', 'updated'); } /*related_page_products*/ if(is_array($this->request->post('related_products'))) { foreach($this->request->post('related_products') as $p) { $rp[$p] = new stdClass; $rp[$p]->page_id = $page->id; $rp[$p]->related_id = $p; } $related_products = $rp; } $query = $this->db->placehold('DELETE FROM __related_page_products WHERE page_id=?', $page->id); $this->db->query($query); if(is_array($related_products)) { $pos = 0; foreach($related_products as $i=>$related_product) $this->pages->add_related_product($page->id, $related_product->related_id, $pos++); } /*/related_page_products*/ } } else { $id = $this->request->get('id', 'integer'); /*related_page_products*/ $related_products = (!$id ? array() : $this->pages->get_related_products(array('page_id'=>$id))); /*/related_page_products*/ if(!empty($id)) $page = $this->pages->get_page(intval($id)); else { $page->menu_id = $this->request->get('menu_id'); $page->visible = 1; } } /*related_page_products*/ if(!empty($related_products)) { foreach($related_products as &$r_p) $r_products[$r_p->related_id] = &$r_p; $temp_products = $this->products->get_products(array('id'=>array_keys($r_products))); foreach($temp_products as $temp_product) $r_products[$temp_product->id] = $temp_product; $related_products_images = $this->products->get_images(array('product_id'=>array_keys($r_products))); foreach($related_products_images as $image) { $r_products[$image->product_id]->images[] = $image; } } $this->design->assign('related_products', $related_products); /*/related_page_products*/ $this->design->assign('page', $page); $menus = $this->pages->get_menus(); $this->design->assign('menus', $menus); // Текущее меню if(isset($page->menu_id)) $menu_id = $page->menu_id; if(empty($menu_id) || !$menu = $this->pages->get_menu($menu_id)) { $menu = reset($menus); } $this->design->assign('menu', $menu); return $this->design->fetch('page.tpl'); } }
simpla/design/html/page.tpl
{capture name=tabs} {if in_array('pages', $manager->permissions)} {foreach $menus as $m} <li {if $m->id == $menu->id}class="active"{/if}><a href='index.php?module=PagesAdmin&menu_id={$m->id}'>{$m->name}</a></li> {/foreach} {/if} {/capture} {if $page->id} {$meta_title = $page->name scope=parent} {else} {$meta_title = 'Новая страница' scope=parent} {/if} {* Подключаем Tiny MCE *} {include file='tinymce_init.tpl'} {* On document load *} {literal} <script src="design/js/jquery/jquery.js"></script> <script src="design/js/jquery/jquery-ui.min.js"></script> {*related_page_products*} <script src="design/js/autocomplete/jquery.autocomplete-min.js"></script> {*related_page_products*} <script> $(function() { /*related_page_products*/ // Удаление связанного товара $(".related_products a.delete").live('click', function() { $(this).closest("div.row").fadeOut(200, function() { $(this).remove(); }); return false; }); // Добавление связанного товара var new_related_product = $('#new_related_product').clone(true); $('#new_related_product').remove().removeAttr('id'); $("input#related_products").autocomplete({ serviceUrl:'ajax/search_products.php', minChars:0, noCache: false, onSelect: function(suggestion){ $("input#related_products").val('').focus().blur(); new_item = new_related_product.clone().appendTo('.related_products'); new_item.removeAttr('id'); new_item.find('a.related_product_name').html(suggestion.data.name); new_item.find('a.related_product_name').attr('href', 'index.php?module=ProductAdmin&id='+suggestion.data.id); new_item.find('input[name*="related_products"]').val(suggestion.data.id); if(suggestion.data.image) new_item.find('img.product_icon').attr("src", suggestion.data.image); else new_item.find('img.product_icon').remove(); new_item.show(); }, formatResult: function(suggestions, currentValue){ var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g'); var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')'; return (suggestions.data.image?"<img align=absmiddle src='"+suggestions.data.image+"'> ":'') + suggestions.value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>'); } }); // Сортировка связанных товаров $(".sortable").sortable({ items: "div.row", tolerance:"pointer", scrollSensitivity:40, opacity:0.7, handle: '.move_zone' }); /*/related_page_products*/ // Автозаполнение мета-тегов menu_item_name_touched = true; meta_title_touched = true; meta_keywords_touched = true; meta_description_touched = true; url_touched = true; if($('input[name="menu_item_name"]').val() == generate_menu_item_name() || $('input[name="name"]').val() == '') menu_item_name_touched = false; if($('input[name="meta_title"]').val() == generate_meta_title() || $('input[name="meta_title"]').val() == '') meta_title_touched = false; if($('input[name="meta_keywords"]').val() == generate_meta_keywords() || $('input[name="meta_keywords"]').val() == '') meta_keywords_touched = false; if($('textarea[name="meta_description"]').val() == generate_meta_description() || $('textarea[name="meta_description"]').val() == '') meta_description_touched = false; if($('input[name="url"]').val() == generate_url()) url_touched = false; $('input[name="name"]').change(function() { menu_item_name_touched = true; }); $('input[name="meta_title"]').change(function() { meta_title_touched = true; }); $('input[name="meta_keywords"]').change(function() { meta_keywords_touched = true; }); $('textarea[name="meta_description"]').change(function() { meta_description_touched = true; }); $('input[name="url"]').change(function() { url_touched = true; }); $('input[name="header"]').keyup(function() { set_meta(); }); }); function set_meta() { if(!menu_item_name_touched) $('input[name="name"]').val(generate_menu_item_name()); if(!meta_title_touched) $('input[name="meta_title"]').val(generate_meta_title()); if(!meta_keywords_touched) $('input[name="meta_keywords"]').val(generate_meta_keywords()); if(!meta_description_touched) { descr = $('textarea[name="meta_description"]'); descr.val(generate_meta_description()); descr.scrollTop(descr.outerHeight()); } if(!url_touched) $('input[name="url"]').val(generate_url()); } function generate_menu_item_name() { name = $('input[name="header"]').val(); return name; } function generate_meta_title() { name = $('input[name="header"]').val(); return name; } function generate_meta_keywords() { name = $('input[name="header"]').val(); return name; } function generate_meta_description() { if(typeof(tinyMCE.get("body")) =='object') { description = tinyMCE.get("body").getContent().replace(/(<([^>]+)>)/ig," ").replace(/(\ )/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 512); return description; } else return $('textarea[name=body]').val().replace(/(<([^>]+)>)/ig," ").replace(/(\ )/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 512); } function generate_url() { url = $('input[name="header"]').val(); url = url.replace(/[\s]+/gi, '-'); url = translit(url); url = url.replace(/[^0-9a-z_\-]+/gi, '').toLowerCase(); return url; } function translit(str) { var ru=("А-а-Б-б-В-в-Ґ-ґ-Г-г-Д-д-Е-е-Ё-ё-Є-є-Ж-ж-З-з-И-и-І-і-Ї-ї-Й-й-К-к-Л-л-М-м-Н-н-О-о-П-п-Р-р-С-с-Т-т-У-у-Ф-ф-Х-х-Ц-ц-Ч-ч-Ш-ш-Щ-щ-Ъ-ъ-Ы-ы-Ь-ь-Э-э-Ю-ю-Я-я").split("-") var en=("A-a-B-b-V-v-G-g-G-g-D-d-E-e-E-e-E-e-ZH-zh-Z-z-I-i-I-i-I-i-J-j-K-k-L-l-M-m-N-n-O-o-P-p-R-r-S-s-T-t-U-u-F-f-H-h-TS-ts-CH-ch-SH-sh-SCH-sch-'-'-Y-y-'-'-E-e-YU-yu-YA-ya").split("-") var res = ''; for(var i=0, l=str.length; i<l; i++) { var s = str.charAt(i), n = ru.indexOf(s); if(n >= 0) { res += en[n]; } else { res += s; } } return res; } </script> <!--related_page_products--> <style> .autocomplete-suggestions{ background-color: #ffffff; width: 100px; overflow: hidden; border: 1px solid #e0e0e0; padding: 5px; } .autocomplete-suggestions .autocomplete-suggestion{cursor: default;} .autocomplete-suggestions .selected { background:#F0F0F0; } .autocomplete-suggestions div { padding:2px 5px; white-space:nowrap; } .autocomplete-suggestions strong { font-weight:normal; color:#3399FF; } </style> <!--/related_page_products--> {/literal} {if $message_success} <!-- Системное сообщение --> <div class="message message_success"> <span class="text">{if $message_success == 'added'}Страница добавлена{elseif $message_success == 'updated'}Страница обновлена{/if}</span> <a class="link" target="_blank" href="../{$page->url}">Открыть страницу на сайте</a> {if $smarty.get.return} <a class="button" href="{$smarty.get.return}">Вернуться</a> {/if} <span class="share"> <a href="#" onClick='window.open("http://vkontakte.ru/share.php?url={$config->root_url|urlencode}/{$page->url|urlencode}&title={$page->name|urlencode}&description={$page->body|urlencode}&noparse=false","displayWindow","width=700,height=400,left=250,top=170,status=no,toolbar=no,menubar=no");return false;'> <img src="{$config->root_url}/simpla/design/images/vk_icon.png" /></a> <a href="#" onClick='window.open("http://www.facebook.com/sharer.php?u={$config->root_url|urlencode}/{$page->url|urlencode}","displayWindow","width=700,height=400,left=250,top=170,status=no,toolbar=no,menubar=no");return false;'> <img src="{$config->root_url}/simpla/design/images/facebook_icon.png" /></a> <a href="#" onClick='window.open("http://twitter.com/share?text={$page->name|urlencode}&url={$config->root_url|urlencode}/{$page->url|urlencode}&hashtags={$page->meta_keywords|replace:' ':''|urlencode}","displayWindow","width=700,height=400,left=250,top=170,status=no,toolbar=no,menubar=no");return false;'> <img src="{$config->root_url}/simpla/design/images/twitter_icon.png" /></a> </span> </div> <!-- Системное сообщение (The End)--> {/if} {if $message_error} <!-- Системное сообщение --> <div class="message message_error"> <span class="text">{if $message_error == 'url_exists'}Страница с таким адресом уже существует{/if}</span> <a class="button" href="">Вернуться</a> </div> <!-- Системное сообщение (The End)--> {/if} <!-- Основная форма --> <form method=post id=product enctype="multipart/form-data"> <input type=hidden name="session_id" value="{$smarty.session.id}"> <div id="name"> <input class="name" name=header type="text" value="{$page->header|escape}"/> <input name=id type="hidden" value="{$page->id|escape}"/> <div class="checkbox"> <input name=visible value='1' type="checkbox" id="active_checkbox" {if $page->visible}checked{/if}/> <label for="active_checkbox">Активна</label> </div> </div> <!-- Параметры страницы --> <div class="block"> <ul> <li><label class=property>Название пункта в меню</label><input name="name" class="simpla_inp" type="text" value="{$page->name|escape}" /></li> <li><label class=property>Меню</label> <select name="menu_id"> {foreach $menus as $m} <option value='{$m->id}' {if $page->menu_id == $m->id}selected{/if}>{$m->name|escape}</option> {/foreach} </select> </li> </ul> </div> <!-- Параметры страницы (The End)--> <!-- Левая колонка свойств товара --> <div id="column_left"> <!-- Параметры страницы --> <div class="block layer"> <h2>Параметры страницы</h2> <ul> <li><label class=property>Адрес</label><div class="page_url">/</div><input name="url" class="page_url" type="text" value="{$page->url|escape}" /></li> <li><label class=property>Заголовок</label><input name="meta_title" class="simpla_inp" type="text" value="{$page->meta_title|escape}" /></li> <li><label class=property>Ключевые слова</label><input name="meta_keywords" class="simpla_inp" type="text" value="{$page->meta_keywords|escape}" /></li> <li><label class=property>Описание</label><textarea name="meta_description" class="simpla_inp"/>{$page->meta_description|escape}</textarea></li> </ul> </div> <!-- Параметры страницы (The End)--> </div> <!-- Левая колонка свойств товара (The End)--> <!-- Правая колонка свойств товара --> <div id="column_right"> {*related_page_products*} <div class="block layer"> <h2>Связанные товары</h2> <div id=list class="sortable related_products"> {foreach from=$related_products item=related_product} <div class="row"> <div class="move cell"> <div class="move_zone"></div> </div> <div class="image cell"> <input type=hidden name=related_products[] value='{$related_product->id}'> <a href="{url id=$related_product->id}"> <img class=product_icon src='{$related_product->images[0]->filename|resize:35:35}'> </a> </div> <div class="name cell"> <a href="{url id=$related_product->id}">{$related_product->name}</a> </div> <div class="icons cell"> <a href='#' class="delete"></a> </div> <div class="clear"></div> </div> {/foreach} <div id="new_related_product" class="row" style='display:none;'> <div class="move cell"> <div class="move_zone"></div> </div> <div class="image cell"> <input type=hidden name=related_products[] value=''> <img class=product_icon src=''> </div> <div class="name cell"> <a class="related_product_name" href=""></a> </div> <div class="icons cell"> <a href='#' class="delete"></a> </div> <div class="clear"></div> </div> </div> <input type=text name=related id='related_products' class="input_autocomplete" placeholder='Выберите товар чтобы добавить его'> </div> <input class="button_green button_save" type="submit" name="" value="Сохранить" /> {*/related_page_products*} </div> <!-- Правая колонка свойств товара (The End)--> <!-- Описагние товара --> <div class="block layer"> <h2>Текст страницы</h2> <textarea name="body" class="editor_large">{$page->body|escape}</textarea> </div> <!-- Описание товара (The End)--> <input class="button_green button_save" type="submit" name="" value="Сохранить" /> </form> <!-- Основная форма (The End) -->
view/PageView.php
<?PHP /** * Simpla CMS * * @copyright 2011 Denis Pikusov * @link http://simplacms.ru * @author Denis Pikusov * * Этот класс использует шаблон page.tpl * */ require_once('View.php'); class PageView extends View { function fetch() { $url = $this->request->get('page_url', 'string'); $page = $this->pages->get_page($url); // Отображать скрытые страницы только админу if(empty($page) || (!$page->visible && empty($_SESSION['admin']))) return false; $this->design->assign('page', $page); $this->design->assign('meta_title', $page->meta_title); $this->design->assign('meta_keywords', $page->meta_keywords); $this->design->assign('meta_description', $page->meta_description); /*related_page_products*/ // Связанные товары $related_ids = array(); $related_products = array(); foreach($this->pages->get_related_products($page->id) as $p) { $related_ids[] = $p->related_id; $related_products[$p->related_id] = null; } if(!empty($related_ids)) { foreach($this->products->get_products(array('id'=>$related_ids, 'visible'=>1)) as $p) $related_products[$p->id] = $p; $related_products_images = $this->products->get_images(array('product_id'=>array_keys($related_products))); foreach($related_products_images as $related_product_image) if(isset($related_products[$related_product_image->product_id])) $related_products[$related_product_image->product_id]->images[] = $related_product_image; $related_products_variants = $this->variants->get_variants(array('product_id'=>array_keys($related_products), 'in_stock'=>1)); foreach($related_products_variants as $related_product_variant) { if(isset($related_products[$related_product_variant->product_id])) { $related_products[$related_product_variant->product_id]->variants[] = $related_product_variant; } } foreach($related_products as $id=>$r) { if(is_object($r)) { $r->image = &$r->images[0]; $r->variant = &$r->variants[0]; } else { unset($related_products[$id]); } } $this->design->assign('related_products', $related_products); } /*/related_page_products*/ return $this->design->fetch('page.tpl'); } }
В шаблоне сайта
{if $related_products} {foreach $related_products as $related_product} Тут товары {/foreach} {/if}
Ну и в api/Products.php
в функции
delete_product
добавить удаление товара из связанных при его удалении
/*related_page_products*/ $this->db->query("DELETE FROM __related_page_products where related_id=?", $id); /*/related_page_products*/
-
Может кому пригодится, понадобилось сделать фильтр клиента по цене, найти товары у которых цена больше, меньше или равна.
в simpla/design/html/products.tpl
{* По цене *} <form method="get"> <div id="price"> <input type="hidden" name="module" value="ProductsAdmin"> <select name="price_comparison"> <option value="" {if empty($price_comparison)}selected{/if}>Выберите</option> <option value="equal" {if $price_comparison == "equal"}selected{/if}>Равно</option> <option value="less" {if $price_comparison == "less"}selected{/if}>Меньше</option> <option value="greater" {if $price_comparison == "greater"}selected{/if}>Больше</option> </select> <input class="price_input" type="text" name="price" placeholder="Введите цену" value="{$price|escape}" /> <input class="price_button" type="submit" value="Найти"/> </div> </form>
В simpla/design/css/style.css
#price { display: flex; flex-direction: column; gap: 15px; padding: 15px 15px; border: 1px solid #343434; margin-bottom: 30px; }
В ProductsAdmin.php
$price_comparison = $this->request->get('price_comparison'); $price = $this->request->get('price'); if (!empty($price)) { $filter['price'] = $price; $this->design->assign('price', $price); } if (!empty($price_comparison)) { $filter['price_comparison'] = $price_comparison; $this->design->assign('price_comparison', $price_comparison); }
В Api/products.php
в 2 функции get_products и count_products ставим новый фильтр
/*фильтр по цене*/ $price_filter = ''; /*фильтр по цене*/
Далее сам фильтр
/*фильтр по цене*/ if (isset($filter['price_comparison']) && isset($filter['price'])) { $price_comparison = $filter['price_comparison']; $price_value = intval($filter['price']); switch ($price_comparison) { case 'equal': $price_filter = $this->db->placehold('AND (SELECT 1 FROM __variants pv WHERE pv.product_id=p.id AND pv.price = ? LIMIT 1)', $price_value); break; case 'less': $price_filter = $this->db->placehold('AND (SELECT 1 FROM __variants pv WHERE pv.product_id=p.id AND pv.price < ? LIMIT 1)', $price_value); break; case 'greater': $price_filter = $this->db->placehold('AND (SELECT 1 FROM __variants pv WHERE pv.product_id=p.id AND pv.price > ? LIMIT 1)', $price_value); break; } } /*фильтр по цене*/
и в общем $query добавляем
$price_filter
Вдруг кому пригодится.
-
В 17.08.2023 в 21:29, shooroop сказал:
LIMIT
Лимитом я же просто ограничу выборку с базы данных, а мне то нужно всё выгрузить.
-
В 23.08.2023 в 08:14, phukortsin сказал:
Значит, не хватает серверу ресурсов.
Ну вот проблема ресурсов решена, а вот всё равно фид грузится 5 минут ти ложится с ошибкой. То есть даже 5 минут не хватает чтоб выполнить запрос к 20 к товарам со свойствами т.д.
Как вы выходили из ситуации? пилить фид?
-
11 минут назад, phukortsin сказал:
В этом и соль что уже все прописал
location / {
proxy_pass http://127.0.0.1:81;
proxy_redirect http://127.0.0.1:81/ /;
include /etc/nginx/proxy_params;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
proxy_read_timeout 300;
}
И сервер перезагружал, всё равно - 1 минуту выполняет и уходит в 504 ошибку.
-
В 18.08.2023 в 08:50, phukortsin сказал:
Такой проблемы у большинства типовых сайтов НЕТ. При 20 тыс обычно товаров фид формируется легко и быстро. Если у Вас не работает, то это, скорее всего, проблема слабого сервера. Если нет желания/возможности перейти на лучший тарифный план, то работать надо индивидуально. Сначала выяснять причину (основные варианты - не хватает ресурсов MySQL или не хватает оперативной памяти сервера). А потом уже придумывать хитрости, чтобы обойти нехватку ресурсов...
Например, если причина затыка в нехватке ресурсов MySQL, то можно выходить из положения, как намекнул shooroop - делать подряд несколько запросов с ограничением, например, по 4000 записей...
Вообще в логах странная ошибка. 2023/08/22 05:36:52 [error] 145577#145577: *2 upstream timed out (110: Connection timed out) while reading response header from upstream,
Сервер ложится с ошибкой 504 Gateway Time-out
Сам сервер выделенный и с хорошим железом, стоит fast panel
-
Скажите, кто как разбивал yandex.xml на части? товаров 20 тыс и фид уже не загружается, падает сервер.
Кто как выходил из этой проблемы?
-
https://www.bestceramic.ru/catalog/plitka
Ну или вот тут более наглядно.
Получается и товары и коллекции.
Как лучше создать? Поделитесь опытом.
-
https://keram.ru/catalog/plitka/
Есть сайт пример по продаже плитки.
У него есть категории товары так скажем по дефолту.
Но помимо этого есть еще коллекции
https://keram.ru/catalog/plitka/?display=manufactureCollection
в коллекции могут быть плитки разных категорий, как настенная плитка , так и плинтус.
Вопрос, как лучше создать структуру и связать ее с базовой simpla?
Создать отдельную сущность collections по аналогии с категориями?
-
17 часов назад, phukortsin сказал:
Если совсем просто, то добавить к заказу поле по аналогии с комментарием. И пусть туда пишут "в пятницу после обеда". Или даже вообще пусть в комментарии записывают дату - тогда вообще ничего делать не надо...
а в целом был опыт создании бронирования на simpla?
-
1 час назад, phukortsin сказал:
У Вас фактически магазин продает не ТОВАР, а АРЕНДУ. Чтобы выглядело достойно, надо значительно перерабатывать функционал, просто и легко вряд ли получится. Надо, видимо, иметь расписание сеансов, и продавать билеты на сеансы. Вариантов разработки есть много разных. А если все же хотите просто, то записывать дату аренды надо в новое поле, как уже было сказано. Может, к заказу, а может, к покупке...
Согласен, по идее надо прям делать чтоб в одну баню не забронировали 5-6 человек . Но просят просто выбор даты, дальше как обычно ручной труд.
В общем если не совсем колхоз, то я думал хранить выбранные дату и время в сессии а потом уже при заказе записывать в pushares таблицу. Пока только такая идея
-
В 09.06.2023 в 23:36, shooroop сказал:
Какая дата? Дата создания товара, или дата оформления заказ или дата добавления товара в корзину или может у вас дата своя к примеру годности товара....
Своя дата, не хотелось бы городить лишний функционал, по сути есть дата которую выбираем на странице товара, аренда бани по сути и кладем в корзину, создавать варианты с датами конечно не получится, т.к. дата постоянно меняется, вот и думаю куда ее записывать чтоб в корзине товар с датой хранился
-
В 02.06.2023 в 09:26, phukortsin сказал:
Нестандартно запрограммировать все требующееся.
http://simpla-tuning.ru/dobavlenie-v-korzinu-srazu-neskolkih-variantov
У меня не стандартно немного сделано, что есть еще дата и время которые надо добавить к товару.
С вариантами то разобраться можно
if (is_array($simpla->request->get('variants'))) { $variants = $simpla->request->get('variants'); foreach ($variants as $s => $v) { $simpla->cart->add_item($s, $v); } }
А вот как сделать чтоб еще дата куда то записывалась? к товару который берут?
-
Есть немного нестандартный вопрос.
Есть у товара 2 варианта
Как правильней сделать чтоб
Можно было выбрать кол-во для каждого из двух вариантов и при клике в корзину чтоб оба товара сразу ушли в корзину с тем же количеством что выбрали.
-
Отбой, кажется он есть в стандартном репозитории.
-
Никто не делал модуль PSBAnk платежный?
https://www.psbank.ru/-/media/Files/Product-Documents/Business/tech-docum-api.pdf
Куплю.
-
В 04.03.2023 в 11:31, Drake777 сказал:
да, имел в виду авторов самого Okay. Полностью согласен с тем, что владельцы сайтов опасаются такого отношения. И был недавно удивлен, когда обратились с заявкой сделать именно на Okay проект
а что мешает делать проекты на окай? как по мне так Виталий забивает болт на клиентов еще до начала СВО, поэтому что изменилось?
Берем окай, он с открытым кодом, свежие версии на github пушат, так что не вижу проблем поддерживать и пилить для России.
Ну а теряет позиции потому что в Украине сейчас наверное не до интернет торговли.
-
Кто сталкивался с таким интересным подходом добавлять контрагентов?
Кто то до меня придумал у клиента такую фичу,
if(empty($order->user_id)) $order->user_id = $order->id;
В целом костыль норм, но потом если человек регается и user_id совпадает с номером заказа, то происходит каша в контрагентах при выгрузке в Мой склад.
Кто сталкивался и какое решение было оптимальным?
-
16 часов назад, shooroop сказал:
Да, в принципе как то мало с ним возился. Спасибо за инфу!
-
11 часов назад, alexivchenko сказал:
Существуют зарезервированные символы, которые имеют зарезервированные значения, это разделители —
:/?#[]@
— и суб-ограничители —!$&'()*+,;=
Существует также набор символов, называемых незарегистрированными символами — буквенно-цифровыми и
-._~
— которые не подлежат кодированию.Ну по логике
RewriteRule ^\*$ / [R=301,L]
Должно редиректить с https://site.ru/* на https://site.ru
Но по итогу я получаю
-
11 часов назад, Kosjak76 сказал:
По поводу чего?
Придумали проблему - и давай чего-то придумывать)))
Вот, например, и не мешает никому)
Проблема в том что все CMS отдают нормально 404, а Simpla показывает главную.
Как вариант можно было бы сделать редирект на нормальную главную. Но пока все методы выдают циклический редирект.
-
9 часов назад, Kosjak76 сказал:
По поводу чего?
Придумали проблему - и давай чего-то придумывать)))
Вот, например, и не мешает никому)
404.
-
Есть у кого мысли по поводу?
Связанные товары со статической страницей
в Общие вопросы по функционалу и дизайну
Опубликовано
Так как решение я дал бесплатно, то тут либо голову включать человеку, либо тут найти специалиста кто это всё перенесет исправно. В целом дал более чем полное решение)