Блог Чуденкова Алексея

Веб-разработка и интернет-реклама без воды.

GetSimple CMS: функция сортировки страниц

Можно использовать для названий, даты создания или же прикрутить плагин Custom Page Field и добавить поле сортировка для точного упорядочивания

<?php function sort_slug($slugs, $order = SORT_ASC) {
  $sortable_array = array();
  foreach($slugs as $slug) {
    $sortable_array[$slug] = returnPageField($slug, 'SORTED_FIELD');
  }
  switch ($order) {
    case SORT_ASC:
      asort($sortable_array, SORT_NUMERIC);
      break;
    case SORT_DESC:
      arsort($sortable_array, SORT_NUMERIC);
      break;
  }
  return array_keys($sortable_array);
} ?>

Вывод:

<?php array = sort_slug(array) ?>

PHP: склонение числительных

/*
 * $num число, от которого будет зависеть форма слова
 * $form_1 первая форма слова, например Яблоко
 * $form_2 вторая форма слова - Яблока
 * $form_3 третья форма множественного числа слова - Яблоков
 */
function true_wordform($num, $form_1, $form_2, $form_3){
	$num = abs($num) % 100; // берем число по модулю и сбрасываем сотни (делим на 100, а остаток присваиваем переменной $num)
	$num_x = $num % 10; // сбрасываем десятки и записываем в новую переменную
	if ($num > 10 && $num < 20) // если число принадлежит отрезку [11;19]
		return $form_3;
	if ($num_x > 1 && $num_x < 5) // иначе если число оканчивается на 2,3,4
		return $form_3;
	if ($num_x == 1) // иначе если оканчивается на 1
		return $form_1;
	return $form_3;
}

Вывод:

$count = 5; 
echo $count . ' ' . wordForm($count, 'яблоко', 'яблока', 'яблок');
 Нет комментариев    43   4 мес   php

GetSimple CMS: вывод полей для дочерних страниц

Задача: вывести список дочерних страниц, с обращением к полям этих страниц.
Решение:

<?php
  $page = get_page_slug(false);
  $children = getChildren($page);
  echo '<div';
  foreach($children as $child) {
    $url = find_url($child, $page);
    $url_clean = $child;
    $img = returnPageField($url_clean, 'h1_img');
    echo '
    	<div>
                    <div>
                        <a href="'.$url.'"></a>
                        <img src="'.$img.'">
                        <div>
                            <div>
                                <h3>'.returnPageField($child, 'title').'</h3>
                            </div>
                        </div>
                    </div>
                </div>
    ';
  }
  echo '</div>';
?>

Чтобы вывести значение любого поля для дочерней страницы в цикле, назначаем поля, которые требуется вывести, например у вас стоит плагин CustomFields и вы добавили через него произвольное поле image. Для вывод значения добавим переменную image:

$image = retutnPageField($url_clean, 'image');

А чтобы вывести в цикле:

<img src="'.$image.'">

SimplaCMS: вывод закупочной цены

Потребовалось сделать вывод закупочной цены в админке. Итак, сначала добавим поля в шаблон в админке.

  1. Откроем /simpla/design/html/product.tpl и добавим колонки Закупка и Прибыль для вариантов товаров:
<li class="variant_move"></li>
<li class="variant_name">Название варианта</li>	
<li class="variant_sku">Артикул</li>
<li class="variant_fprice">Закупка, {$currency->sign}</li>	
<li class="variant_price">Цена, {$currency->sign}</li>	
<li class="variant_discount">Старая, {$currency->sign}</li>	
<li class="variant_amount">Кол-во</li>
<li></li>
<li>Прибыль</li>
  1. Далее добавим поля для указания данных в цикл $product_variants:
<li class="variant_move"><div class="move_zone"></div></li>
<li class="variant_name">      <input name="variants[id][]"            type="hidden" value="{$variant->id|escape}" /><input name="variants[name][]" type="" value="{$variant->name|escape}" /> <a class="del_variant" href=""><img src="design/images/cross-circle-frame.png" alt="" /></a></li>
<li class="variant_sku">       <input name="variants[sku][]"           type="text"   value="{$variant->sku|escape}" /></li>
<li class="variant_fprice">     <input name="variants[fprice][]"         type="text"   value="{$variant->fprice|escape}" /></li>
<li class="variant_price">     <input name="variants[price][]"         type="text"   value="{$variant->price|escape}" /></li>
<li class="variant_discount">  <input name="variants[compare_price][]" type="text"   value="{$variant->compare_price|escape}" /></li>
<li class="variant_amount">    <input name="variants[stock][]"         type="text"   value="{if $variant->infinity || $variant->stock == ''}∞{else}{$variant->stock|escape}{/if}" />{$settings->units}</li>
<li>{if $variant->fprice} +{math equation = $variant->price - $variant->fprice} {$currency->sign}{/if}</li>
  1. Теперь добавим отображение закупки в список товаров, для этого откроем файл /simpla/design/html/products.tpl и добавим в цикл $product_variants:
<li {if !$variant@first}class="variant" style="display:none;"{/if}>
	<i title="{$variant->name|escape}">{$variant->name|escape|truncate:30:'…':true:true}</i>
	<input class="fprice" type="text" name="fprice[{$variant->id}]" value="{$variant->fprice}" />
	<input class="price {if $variant->compare_price>0}compare_price{/if}" type="text" name="price[{$variant->id}]" value="{$variant->price}" {if $variant->compare_price>0}title="Старая цена &mdash; {$variant->compare_price} {$currency->sign}"{/if} />{$currency->sign}  
	<input class="stock" type="text" name="stock[{$variant->id}]" value="{if $variant->infinity}∞{else}{$variant->stock}{/if}" />{$settings->units}
</li>
  1. Отображение сделали, теперь нужно поработать над функционалом. Откроем файл /api/Variants.php и обновим в двух местах SQL-запрос для функции get_variants:
$query = $this->db->placehold("SELECT v.id, v.product_id , v.price, v.fprice, NULLIF(v.compare_price, 0) as compare_price, v.sku, IFNULL(v.stock, ?) as stock, (v.stock IS NULL) as infinity, v.name, v.attachment, v.position
  1. Теперь откроем файл /simpla/ProductsAdmin.php и добавим возможность управления закупочной ценой на списке товаров:
// Обработка действий 	
if($this->request->method('post'))
{
// Сохранение цен и наличия
$prices = $this->request->post('price');
$fprices = $this->request->post('fprice');
$stocks = $this->request->post('stock'); 
		    foreach($fprices as $id=>$fprice)
{
	$this->variants->update_variant($id, array('fprice'=>$fprice));
}
foreach($prices as $id=>$price)
{
	$stock = $stocks[$id];
	if($stock == '∞' || $stock == '')
	$stock = null;
	$this->variants->update_variant($id, array('price'=>$price, 'stock'=>$stock));
}

PHP: Разделить число на разряды

Не люблю, когда нет разделителей разрядов в длинных числах, поэтому пришлось для себя отрыть функцию number_format.

<? number_format($string, 0, '', ' '); ?>
 Нет комментариев    37   5 мес   php

SimplaCMS: подключаем dadata для клёвых подсказок

Есть клёвый сервис, который позволяет в вашей корзине вызывать подсказки.
Подсказки могут быть разными — фамилии, имена, отчества, адреса, почты, огрн, инн и ещё большая куча других подсказок. Для простых интернет-магазинов очень нужны ФИО, электропочты и адреса. Это реально упрощает процесс оформления заказа и в какой-то степени увеличивает конверсию.

Как подключить

  1. Регистрируемся на сайте dadata.ru, получаем API ключик.
  2. Открываем файл /design/ваша_тема/html/cart.tpl и добавляем в него:
{literal}
<link href="https://cdn.jsdelivr.net/npm/suggestions-jquery@19.4.2/dist/css/suggestions.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/suggestions-jquery@19.4.2/dist/js/jquery.suggestions.min.js"></script>
 <script type="text/javascript">
     $(".cart input[name='name']").suggestions({
         serviceUrl: "https://dadata.ru/api/v2",
         token: "a8fe6329cfa81666be66deb370d2c364ccfddeaa",
         type: "NAME",
         params: {
             parts: ["SURNAME", "NAME", "PATRONYMIC"]
         }
     });
     $(".cart input[name='address']").suggestions({
         serviceUrl: "https://dadata.ru/api/v2",
         token: "a8fe6329cfa81666be66deb370d2c364ccfddeaa",
         type: "ADDRESS"
     });
     $(".cart input[name='email']").suggestions({
        serviceUrl: "https://dadata.ru/api/v2",
        token: "a8fe6329cfa81666be66deb370d2c364ccfddeaa",
        type: "EMAIL",
        /* Вызывается, когда пользователь выбирает одну из подсказок */
        onSelect: function(suggestion) {
            console.log(suggestion);
        }
    });
 </script>
 {/literal}
  1. Чтобы скрипт заработал, нужно указать свой API-ключик во всех token-параметрах.
  2. Обратите внимание, что у меня используется нестандартный класс для формы корзины. Чтобы узнать какой класс формы корзины используется у вас, найдите в cart.tpl html-тег
    и посмотрите какой класс ему принадлежит. Далее просто замените cart на свой класс в этих полях:
$(".cart input[name='name']").suggestions({
...
$(".cart input[name='address']").suggestions({
...
$(".cart input[name='email']").suggestions({
...
}

Результат работы

SimplaCMS: обновляем TinyMCE до 4 версии

Кривой TinyMCE 3 версии в 2019 году уже невозможно использовать. Он регулярно вставляет всякие спаны и непечатаемые пробелы, поэтому нужно было обновить его версию.

  1. Открываем /simpla/design/js/ и создаём папку tinymce
  2. Скачаем сам TinyMCE и положим содержимое папки js в папку tinymce. Краткая структура файлов и папок в папке tinymce должна быть такой:
-langs
-plugins
-skins
-themes
--jquery.tinymce.min.js
--tinymce.min.js
  1. Открываем файл /simpla/design/html/tinymce_init.tpl и меняем полностью его содержимое на:
<script language="javascript" type="text/javascript" src="design/js/tinymce/tinymce.min.js"></script>
<script language="javascript">
tinymce.init({
    selector: "textarea.editor_large,textarea.editor_small",
    language : "ru",
    plugins: [
        "advlist autosave autolink lists link image charmap print preview hr anchor pagebreak",
        "searchreplace wordcount charactercount charmap visualblocks visualchars code fullscreen",
        "insertdatetime media nonbreaking save table contextmenu directionality",
        "emoticons template paste textcolor colorpicker textpattern  "
   ],
   toolbar1: "undo redo | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link unlink anchor | image media charmap blockquote | forecolor backcolor | removeformat print preview code emoticons ",
menubar: '',
   verify_html: false, 
   image_advtab: true,
        setup : function(ed) {
        if(typeof set_meta == 'function')
        {
            ed.on('keyUp', function() {
                set_meta();
            });
            ed.on('change', function() {
                set_meta();
            });
        }
    }
    {literal}}{/literal});
    function myCustomGetContent( id ) {
        if( typeof tinymce != "undefined" ) {
            var editor = tinymce.get( id );
            if( editor && editor instanceof tinymce.Editor ) {
                return editor.getContent{literal}({format : 'text'}{/literal}).substr(0, 512);
            } else {
                return  jQuery('textarea[name='+id+']').val().replace(/(<([^>]+)>)/ig," ").replace(/(\&nbsp;)/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 255);
            }
        }
        return '';
    }
</script>
  1. Далее необходимо поправить автогенерацию meta description в админке. Для этого нужно полностью заменить функцию generate_meta_description() в файлах:
    • /simpla/design/html/product.tpl
    • /simpla/design/html/post.tpl
// Обновлённая функция, которую нужно вставить в файлы
function generate_meta_description()
{
	if( typeof tinymce != "undefined" )
	{
		return myCustomGetContent( "annotation" );
	}
	else
		return $('textarea[name=annotation]').val().replace(/(<([^>]+)>)/ig," ").replace(/(\&nbsp;)/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 255);
}

В файле /simpla/design/html/category.tpl полностью обновляем функцию:

function generate_meta_description()
{
	if( typeof tinymce != "undefined" )
	{
		return myCustomGetContent( "description" );
	}
	else
		return $('textarea[name=description]').val().replace(/(<([^>]+)>)/ig," ").replace(/(\&nbsp;)/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 255);
}

В файле /simpla/design/html/page.tpl полностью обновляем функцию:

function generate_meta_description()
{
	if( typeof tinymce != "undefined" )
	{
		return myCustomGetContent( "body" );
	}
	else
		return $('textarea[name=body]').val().replace(/(<([^>]+)>)/ig," ").replace(/(\&nbsp;)/ig," ").replace(/^\s+|\s+$/g, '').substr(0, 255);
}

Результат работы

SimplaCMS: соседние товары, вывод бренда

Откроем файл /view/ProductView.php, отыщем строчку

//Соседние товары

И заменим содержимое блока на:

$next = $this->products->get_next_product($product->id);
		$next_brand = $this->brands->get_brand(intval($next->brand_id));
		$i = $this->products->get_images(array('product_id'=>$next->id));
		$next->image = reset($i);
		$next->brand = $next_brand;

		$prev = $this->products->get_prev_product($product->id);
		$prev_brand = $this->brands->get_brand(intval($prev->brand_id));
		$i = $this->products->get_images(array('product_id'=>$prev->id));
		$prev->image = reset($i);
		$prev->brand = $prev_brand;

Теперь, чтобы вывести бренд соседнего товара:

{$prev_product->brand->name} или {$next_product->brand->name}

Битрикс: красивый вывод массива $arResult

В целом решение подойдет для любой переменной, но именно этот массив содержит большое количество информации, которое сложно прочитать без форматирования.

<? if ($USER->IsAdmin()) {
 echo "<pre>Template arResult: "; print_r($arResult); echo "</pre>";
}  ?>
 21   5 мес   битрикс
Ранее Ctrl + ↓