Open Graph

#Вариант 1

Обязательно добавить в head префиксы для валидности
<head prefix=
    "og: http://ogp.me/ns#
     fb: http://ogp.me/ns/fb#  
     product: http://ogp.me/ns/product#">
Сам код OpenGraph
<?php
$bOpenGraph = FALSE;
// Open Graph
if (is_object(Core_Page::instance()->object))
{
    $bInformationItem = Core_Page::instance()->object instanceof Informationsystem_Controller_Show;
    $bShopItem = Core_Page::instance()->object instanceof Shop_Controller_Show;
   
    if ($bInformationItem || $bShopItem)
    {
        echo'<meta property="og:site_name" content="inikSite.ru">';    // ЗАМЕНИТЬ НА URL СВОЕГО САЙТА
        if (Core_Page::instance()->object->item)
        {
   $bOpenGraph = TRUE;
         
            $aOpenGraph = array();            
            $oEntity = $bInformationItem
                ? Core_Entity::factory('Informationsystem_Item', Core_Page::instance()->object->item)
                : Core_Entity::factory('Shop_Item', Core_Page::instance()->object->item);
            
            $type = $bInformationItem
                ? 'article'
                : 'product';
            
            $aOpenGraph['og:type'] = $type;
            $aOpenGraph['og:title'] =  $oEntity->name;
            $aOpenGraph['og:description'] = strip_tags(Core_Str::cutSentences($oEntity->description));


            $oSite = Core_Entity::factory('Site', CURRENT_SITE);
            $oSite_Alias = $oSite->getCurrentAlias();
        
            if ($oSite_Alias)
            {
                $sSiteURL = $oSite_Alias->name;
                
                $protocol = Core_Page::instance()->structure->https
                    ? 'https://'
                    : 'http://';
            
                $aOpenGraph['og:url'] = $protocol . $sSiteURL
                    . Core_Page::instance()->structure->getPath()
                    . $oEntity->getPath();
            
                if ($oEntity->image_large != '')
                {
                    $aOpenGraph['og:image'] = $protocol . $sSiteURL . $oEntity->getLargeFileHref();
                              $aOpenGraph['og:image:width'] = $oEntity->image_large_width;
                              $aOpenGraph['og:image:height'] = $oEntity->image_large_height;
                }
               
               if ($bShopItem)
               {
                  $aOpenGraph['product:price:amount'] = $oEntity->price;
                  $aOpenGraph['product:price:currency'] = $oEntity->shop_currency->code;
               }
                     
            }
            
            foreach ($aOpenGraph as $sProperty => $sContent)
            {
         ?><meta property="<?php echo htmlspecialchars($sProperty)?>" content="<?php echo htmlspecialchars($sContent)?>" /><?php
      
         echo PHP_EOL;
            }
      }
      elseif (Core_Page::instance()->object->group)
      {
         $bOpenGraph = TRUE;


            $aOpenGraph = array();
            
            $oEntity = $bInformationItem
                ? Core_Entity::factory('Informationsystem_Group', Core_Page::instance()->object->group)
                : Core_Entity::factory('Shop_Group', Core_Page::instance()->object->group);
            
            $type = $bInformationItem
                ? 'article'
                : 'website';
            
            $aOpenGraph['og:type'] = $type;
            $aOpenGraph['og:title'] = $oEntity->name;
            $aOpenGraph['og:description'] = $oEntity->seo_description;


            $oSite = Core_Entity::factory('Site', CURRENT_SITE);
            $oSite_Alias = $oSite->getCurrentAlias();
        
            if ($oSite_Alias)
            {
                $sSiteURL = $oSite_Alias->name;
                
                $protocol = Core_Page::instance()->structure->https
                    ? 'https://'
                    : 'http://';
            
                $aOpenGraph['og:url'] = $protocol . $sSiteURL
                    . Core_Page::instance()->structure->getPath()
                    . $oEntity->getPath();
            
                if ($oEntity->image_large != '')
                {
                    $aOpenGraph['og:image'] = $protocol . $sSiteURL . $oEntity->getLargeFileHref();
                }else{
                    $aOpenGraph['og:image'] = 'https://inikSite.ru/images/logo.jpg';   // ЗАМЕНИТЬ НА ПУТЬ К ЛОГОТИПУ СВОЕГО САЙТА
                }
            }
            
            foreach ($aOpenGraph as $sProperty => $sContent)
            {
         ?><meta property="<?php echo htmlspecialchars($sProperty)?>" content="<?php echo htmlspecialchars($sContent)?>" /><?php
      
         echo PHP_EOL;
         }
      }
   }
}
   
if (!$bOpenGraph && Core_Page::instance()->structure)
{
   $aOpenGraph = array();
   
   $oEntity = Core_Page::instance()->structure;
   
   $type = 'website';
   
   $aOpenGraph['og:type'] = $type;
   $aOpenGraph['og:title'] = $oEntity->Site->name;
   $aOpenGraph['og:description'] = strip_tags(Core_Str::cutSentences($oEntity->seo_description));


   $oSite = Core_Entity::factory('Site', CURRENT_SITE);
   $oSite_Alias = $oSite->getCurrentAlias();


   if ($oSite_Alias)
   {
      $sSiteURL = $oSite_Alias->name;
      
      $protocol = Core_Page::instance()->structure->https
         ? 'https://'
         : 'http://';
   
      $aOpenGraph['og:url'] = $protocol . $sSiteURL
         . $oEntity->getPath();
   
     $aOpenGraph['og:image'] = 'https://inikSite.ru/images/logo.jpg';   // ЗАМЕНИТЬ НА ПУТЬ К ЛОГОТИПУ СВОЕГО САЙТА
               
   }
   
   foreach ($aOpenGraph as $sProperty => $sContent)
   {
      ?><meta property="<?php echo htmlspecialchars($sProperty)?>" content="<?php echo htmlspecialchars($sContent)?>" /><?php


      echo PHP_EOL;
   }
}
?>

#Вариант 2

<?php
    // Open Graph
    if (is_object(Core_Page::instance()->object))
    {
        $bInformationItem = Core_Page::instance()->object instanceof Informationsystem_Controller_Show;
        $bShopItem = Core_Page::instance()->object instanceof Shop_Controller_Show;
        if ($bInformationItem || $bShopItem)
        {
            if (Core_Page::instance()->object->item)
            {
                $aOpenGraph = array();
                
                $oEntity = $bInformationItem
                    ? Core_Entity::factory('Informationsystem_Item', Core_Page::instance()->object->item)
                    : Core_Entity::factory('Shop_Item', Core_Page::instance()->object->item);
                
                $type = $bInformationItem
                    ? 'article'
                    : 'website';
                
                $aOpenGraph['og:type'] = $type;
                $aOpenGraph['og:title'] = $oEntity->name;
                $aOpenGraph['og:description'] = strip_tags(Core_Str::cutSentences($oEntity->description));
                                

                if ($oEntity->image_large != '')
                {
                    $oSite = Core_Entity::factory('Site', CURRENT_SITE);
                    $oSite_Alias = $oSite->getCurrentAlias();
                
                    if ($oSite_Alias)
                    {
                        $sSiteURL = $oSite_Alias->name;
                        
                        $protocol = Core_Page::instance()->structure->https
                            ? 'https://'
                            : 'http://';
                            
                        $aOpenGraph['og:image'] = $protocol . $sSiteURL . $oEntity->getLargeFileHref();
                    }
                }
                
                foreach ($aOpenGraph as $sProperty => $sContent)
                {
                    ?><meta property="<?php echo htmlspecialchars($sProperty)?>" content="<?php echo htmlspecialchars($sContent)?>" /><?php
                    echo PHP_EOL;
                }
            }
        }
    }
?>

ROBOTS.TXT для HOSTCMS

Простой файл robots.txt

User-agent: *
Disallow: /admin
Disallow: /search
Disallow: /templates
Disallow: /captcha.php
Disallow: /403
Disallow: /404
Disallow: /*filter=*
Disallow: /*cart/*
Disallow: /*search/*
Disallow: /*sorting=*
Disallow: /*?comments=*
Disallow: /*?producer_id=*
Disallow: /*?on_page=*
Disallow: /showbanner/
Allow: /hostcmsfiles/css/*
Allow: /hostcmsfiles/js/*

User-agent: Yandex
Crawl-delay: 50

Host: site.ru
Sitemap: http://site.ru/sitemap.xml

Расширенный вариант

User-agent: Yandex
Disallow: /admin
Disallow: /search
Disallow: /templates
Disallow: /showbanner
Disallow: /captcha.php
Disallow: /403
Disallow: /404
Disallow: /users/
Disallow: /*tag
Disallow: /*page
Disallow: */page/
Disallow: /compare_items/
Disallow: /*?
Disallow: /*filter=*
Disallow: /*cart/*
Disallow: /*sorting=*
Disallow: /*?comments=*
Disallow: /*?producer_id=*
Disallow: /*?on_page=*
Disallow: /*?text=*
Disallow: *.pdf
Disallow: *.xls
Disallow: *.doc
Disallow: *.ppt
Disallow: *.txt
Allow: /hostcmsfiles/css/*
Allow: /hostcmsfiles/js/*
Allow: /hostcmsfiles/jquery/*
Allow: */upload/*.jpg
Allow: */upload/*.jpeg
Allow: */upload/*.png
Allow: */upload/*.gif
Clean-param: sort
Clean-param: utm_source&utm_medium&utm_term&utm_content&utm_campaign&yclid&gclid&_openstat&from /
Clean-param: openstat

User-agent: Googlebot
Disallow: /admin
Disallow: /search
Disallow: /templates
Disallow: /showbanner
Disallow: /captcha.php
Disallow: /403
Disallow: /404
Disallow: /users/
Disallow: /*tag
Disallow: /*page
Disallow: */page/
Disallow: /compare_items/
Disallow: /*?
Disallow: /*filter=*
Disallow: /*cart/*
Disallow: /*sorting=*
Disallow: /*?comments=*
Disallow: /*?producer_id=*
Disallow: /*?on_page=*
Disallow: /*?text=*
Disallow: *.pdf
Disallow: *.xls
Disallow: *.doc
Disallow: *.ppt
Disallow: *.txt
Disallow: *utm
Disallow: *clid=
Disallow: *openstat
Disallow: *from
Allow: /hostcmsfiles/css/*
Allow: /hostcmsfiles/js/*
Allow: /hostcmsfiles/jquery/*
Allow: */upload/*.jpg
Allow: */upload/*.jpeg
Allow: */upload/*.png
Allow: */upload/*.gif

User-agent: *
Disallow: /admin
Disallow: /search
Disallow: /templates
Disallow: /showbanner
Disallow: /captcha.php
Disallow: /403
Disallow: /404
Disallow: /users/
Disallow: /*tag
Disallow: /*page
Disallow: */page/
Disallow: /catalogs/
Disallow: /compare_items/
Disallow: /*?
Disallow: /*filter=*
Disallow: /*cart/*
Disallow: /*sorting=*
Disallow: /*?comments=*
Disallow: /*?producer_id=*
Disallow: /*?on_page=*
Disallow: /*?text=*
Disallow: *.pdf
Disallow: *.xls
Disallow: *.doc
Disallow: *.ppt
Disallow: *.txt
Disallow: *utm
Disallow: *clid=
Disallow: *openstat
Disallow: *from
Allow: /hostcmsfiles/css/*
Allow: /hostcmsfiles/js/*
Allow: /hostcmsfiles/jquery/*
Allow: */upload/*.jpg
Allow: */upload/*.jpeg
Allow: */upload/*.png
Allow: */upload/*.gif

Host: https://www.site.ru
Sitemap: https://www.site.ru/sitemap.xml

Где управлять разрешенными для загрузки типами файлов?

Открываем фал  \modules\core\config\config.php

Находим строчку:
'availableExtension' => array ('JPG', 'JPEG', 'GIF', 'PNG', 'PDF', 'ZIP', 'DOC'),

и меняем на эту: 

'availableExtension' => array ('JPG', 'JPEG', 'GIF', 'PNG', 'PDF', 'ZIP', 'TXT', 'CSV', 'DOC', 'DOCX', 'RTF', 'PDF', 'PPT', 'PPTX', 'XLS', 'XLSX')
php

Делаем магазин каталог на Главной странице сайта

Создаем константу INDEX_PAGE_IS_DEFAULT = true
  • Идем в структуру сайта, открываем редактирование узла "Главная", переключаем тип с документа на ТДС, выбираем ТДС Интернет-магазин, указываем id магазина и нужные xsl-шаблоны.
  • Идем в раздел "Интернет-магазины", заходим в редактор нужного магазина и меняем в списке узел структуры, к которому он привязан. 

Для показа групп товаров при переносе групп и товаров в админке сайта

Для показа групп товаров при переносе групп и товаров в админке сайта, в файле \modules\core\config\config.php укажите параметр
'switchSelectToAutocomplete' => 100,
вместо 100 укажите значительно большее число, при этом значении выбор папок будет заменяться на автокомплит
php

Доступ по защищенному протоколу HTTPS. SSL сертификаты

Система управления поддерживает возможность работы в клиентском разделе и центре администрирования по защищенному протоколу HTTPS.
Для домена необходимо приобрести SSL-сертификат или создать самоподписанный сертификат, далее обратиться в поддержку хостинга или к администратору сервера для установки сертификата.

Установка внешних ссылок без протокола

Если в макете вы используете внешние ссылки с протоколом http://, например
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.js">
замените на независимые от протокола:
<script type="text/javascript" src="//code.jquery.com/jquery-1.7.js">

Использование HTTPS при работе с клиентским разделом

Установите SSL сертификат на сервере, далее в структуре сайта для всех разделов выберите опцию "Доступ через HTTPS". Ускорить установку всем разделам этой опции можно через SQL-запрос (123 замените на идентификатор сайта):
UPDATE `structures` SET `https` = 1 WHERE `site_id` = 2;

Указание HTTPS в Яндекс.Вебмастер

После перевода сайта с http на https в Яндекс.Вебмастер для сайта в разделе Настройка индексирования — Переезд сайта для сайта установить «Добавить HTTPS».

Указание директивы Host с https:// в robots.txt

В robots.txt для директивы Host укажите адрес с https://, например,
Host: https://www.myhost.ru

Доступ в центр администрирования с использованием HTTPS

После установки SSL сертификата и проверки доступа к центру администрирования через https создайте константу 
USE_ONLY_HTTPS_AUTHORIZATION
и присвойте ей значение true, после этого доступ по протоколу HTTP в центр администрирования будет невозможен.

КОНСТАНТЫ

Отключаем Вебвизор в коде Метрики

1. В Система -> Константы создаём Константу WEBVISOR
2. В код Метрики вставляем строчку
webvisor:<?php if (defined('WEBVISOR')) {echo 'true';}else{ echo 'false';};?>,
При неактивной Константе Webvisor в коде Метрики Вебвизор отключается.

Загрузка бета обновлений

 INSTALL_BETA_UPDATE (true)  -  для загрузки бэта обновлений делаем константу активной и прописываем TRUE

Отключаем чат в админпанели, чтобы уменьшить нагрузку

Открыввем файл /modules/core/config
'chat' => FALSE,
php

Меняем путь к базе данных database.php

Открываем файл /modules/core/config/database.php и заменяем параметры

<?php
 return array (
      'default' => array (
           'driver' => 'mysql',
           'host' => 'securitysf.mysql',
           'username' => 'securitysf_mysql',
           'password' => 'auotczlo',
           'database' => 'securitysf_hs'
      )
 );
php

Настройка memcahe

в секции memcahe указываются данные доступа к серверу:
modules/core/config/cache.php
PHP
'memcache' => array(
'name' => 'Memcache',
'driver' => 'Cache_Memcache',
'server' => '127.0.0.1',
'port' => 11211,
'checksum' => FALSE,
'caches' => $aTypicalCaches,
),
а в 'defaultCache' указываете 'memcache'
PHP
<?php
return array (
'skin' => 'bootstrap',
'dateFormat' => 'd.m.Y',
'dateTimeFormat' => 'd.m.Y H:i:s',
//'reverseDateTimeFormat' => '',
'datePickerFormat' => 'DD.MM.YYYY',
'dateTimePickerFormat' => 'DD.MM.YYYY HH:mm:ss',
'timezone' => 'Europe/Moscow',
'translate' => TRUE,
'chat' => FALSE,
'switchSelectToAutocomplete' => 100,
'autocompleteItems' => 10,
'backendSessionLifetime' => 14400,
'availableExtension' => array ('JPG', 'JPEG', 'GIF', 'PNG', 'WEBP', 'PDF', 'ZIP', 'DOC', 'DOCX', 'XLS', 'XLSX'),
'defaultCache' => 'file',
'session' => array(
'driver' => 'database',
'class' => 'Core_Session_Database'
),...

Конфигурационный файл

Конфигурационный файл размещается в modules/core/config/cache.php и содержит переменную $aTypicalCaches с массивом имен кэшей и их конфигурациями, например:

PHP

$aTypicalCaches = array(
'default' => array('expire' => 3600, 'size' => 262144, 'tags' => FALSE),
'Core_ORM' => array('expire' => 3600, 'size' => 262144, 'tags' => FALSE),
'Core_ORM_ColumnCache' => array('expire' => 3600, 'size' => 262144, 'tags' => FALSE),
'Core_ORM_RelationCache' => array('expire' => 3600, 'size' => 262144, 'tags' => FALSE),
'informationsystem_rss' => array('expire' => 14400, 'size' => 262144),
'informationsystem_show' => array('expire' => 14400, 'size' => 262144, 'compress' => TRUE),
'informationsystem_tags' => array('expire' => 14400, 'size' => 262144, 'compress' => TRUE),
'shop_show' => array('expire' => 14400, 'size' => 262144, 'compress' => TRUE),
'shop_tags' => array('expire' => 14400, 'size' => 262144, 'compress' => TRUE),
'search' => array('expire' => 14400, 'size' => 262144, 'tags' => FALSE),
'structure_breadcrumbs' => array('expire' => 14400, 'size' => 262144),
'structure_show' => array('expire' => 14400, 'size' => 262144, 'compress' => TRUE),
'counter_allSession' => array('expire' => 1800, 'size' => 1024, 'tags' => FALSE),
);
Индексом элемента массива является имя кэша, значением - массив опций, где:
  • expire — время жизни закэшированного элемента, указывается в секундах;
  • size — максимальный размер кэшируемого элемента, указывается в байтах;
  • tags — использовать теггирование кэша, по умолчанию TRUE;
  • compress — сжимать значение перед сохранением в кэш, по умолчанию FALSE.
Далее конфигурационный файл возвращает массив со списком доступных хранилищ кэша, например:
PHP
return array (
'memory' => array(
'name' => 'Memory',
'driver' => 'Core_Cache_Memory',
'caches' => array(
'default' => array()
),
),
'file' => array(
'name' => 'File',
'driver' => 'Cache_File',
'checksum' => FALSE,
'caches' => $aTypicalCaches,
),
'eaccelerator' => array(
'name' => 'eAccelerator',
'driver' => 'Cache_Eaccelerator',
'checksum' => TRUE,
'caches' => $aTypicalCaches,
),
'apc' => array(
'name' => 'APC',
'driver' => 'Cache_APC',
'checksum' => TRUE,
'caches' => $aTypicalCaches,
),
'memcache' => array(
'name' => 'Memcache',
'driver' => 'Cache_Memcache',
'server' => '127.0.0.1',
'port' => 11211,
'checksum' => FALSE,
'caches' => $aTypicalCaches,
),
'xcache' => array(
'name' => 'XCache',
'driver' => 'Cache_XCache',
'checksum' => TRUE,
'caches' => $aTypicalCaches,
),
'static' => array(
'name' => 'Static',
'driver' => 'Cache_Static',
'caches' => array(
'default' => array('expire' => 3600, 'size' => NULL),
),
),);
где индексом является уникальное название кэша, а значением массив опций, например:
  • name — текстовое название вида кэширования;
  • driver — имя драйвера, осуществляющего работу с кэшем. Файлы дополнительных драйверов располагаются в директории modules/cache/;
  • checksum — сохранять контрольную сумму кэшируемого объекта и проверять ее при извлечении элемента из кэша, позволяет исключить извлечение поврежденных данных;
  • caches — массив доступных кэшей, чаще всего подставляется переменная $aTypicalCaches.

Конфигурационный файл

Конфигурационный файл размещается в modules/core/config/config.php и содержит следующие настройки:
  • skin — шаблон центра администрирования, по умолчанию 'bootstrap';
  • dateFormat — формат даты, по умолчанию 'd.m.Y';
  • dateTimeFormat — формат даты-времени, по умолчанию 'd.m.Y H:i:s';
  • timezone — временная зона, по умолчанию 'Europe/Moscow';
  • translate — использовать в пути элемента перевод, по умолчанию TRUE. В случае указания FALSE используется транслитерация;
  • chat — использовать чат между пользователями в центре администрирования, по умолчанию TRUE;
  • switchSelectToAutocomplete — количество элементов, при которых большие списки переключать на автоподстановку, по умолчанию 100. Используется, например, при выборе группы для товаров и информационных элементов;
  • autocompleteItems — количество элементов, предлагаемых в автоподстановке, по умолчанию 10;
  • availableExtension — массив расширений файлов, разрешенных для загрузки в атрибуты элементов центра администрирования. При указании дополнительных элементов не забывайте указывать их в верхнем регистре;
  • defaultCache — вид кэширования по умолчанию;
  • fileIcons — массив соответствий расширений файлов и иконок.

PHP . config.php

<?php
return array (
'skin' => 'bootstrap',
'dateFormat' => 'd.m.Y',
'dateTimeFormat' => 'd.m.Y H:i:s',
//'reverseDateTimeFormat' => '',
'datePickerFormat' => 'DD.MM.YYYY',
'dateTimePickerFormat' => 'DD.MM.YYYY HH:mm:ss',
'timezone' => 'Europe/Moscow',
'translate' => TRUE,
'chat' => FALSE,
'switchSelectToAutocomplete' => 100,
'autocompleteItems' => 10,
'backendSessionLifetime' => 14400,
'availableExtension' => array ('JPG', 'JPEG', 'GIF', 'PNG', 'PDF', 'ZIP', 'DOC'),
'defaultCache' => 'file',
'adminMenu' => array(
0 => array(
'image' => '/admin/images/structure.gif'
),
1 => array(
'image' => '/admin/images/service.gif'
),
2 => array(
'image' => '/admin/images/users.gif'
),
3 => array(
'image' => '/admin/images/system.gif'
)
),
'fileIcons' => array(
'sql' => 'sql.gif',
'txt' => 'txt.gif',
'htaccess' => 'config.gif',
'css' => 'css.gif',
'php' => 'php.gif',
'php3' => 'php.gif',
'jpg' => 'jpg.gif',
'jpeg' => 'jpg.gif',
'gif' => 'gif.gif',
'bmp' => 'bmp.gif',
'png' => 'png.gif',
'ico' => 'image.gif', //
'htm' => 'html.gif',
'html' => 'html.gif',
'xml' => 'xml.gif', //
'xsl' => 'xsl.gif',
'zip' => 'zip.gif',
'gz' => 'zip.gif',
'7z' => 'zip.gif',
'rar' => 'rar.gif',
'pdf' => 'pdf.gif',
'doc' => 'doc.gif',
'docx' => 'doc.gif',
'cdr' => 'vector.gif',
'ai' => 'vector.gif',
'eps' => 'vector.gif',
'rb' => 'rb.gif',
'ppt' => 'ppt.gif',
'pptx' => 'ppt.gif',
'pptm' => 'ppt.gif',
'mdb' => 'mdb.gif',
'h' => 'h.gif',
'fh1' => 'fh1.gif',
'fh2' => 'fh2.gif',
'fh3' => 'fh3.gif',
'fh4' => 'fh4.gif',
'fh5' => 'fh5.gif',
'fh6' => 'fh6.gif',
'fh7' => 'fh7.gif',
'fh8' => 'fh8.gif',
'fh9' => 'fh9.gif',
'fla' => 'flash.gif',
'swf' => 'flash.gif',
'xls' => 'xls.gif',
'cpp' => 'cpp.gif',
'chm' => 'chm.gif'
));

Настройка почты, отправка через SMTP, настройка DKIM

Конфигурационный файл размещается в modules/core/config/mail.php. Стандартно используется опция default, для которой задан драйвер sendmail:

   'default' => array (
       'driver' => 'sendmail',
    ),

вместо sendmail укажите драйвер smtp.

Далее настройте секцию с параметрами драйвера smtp:

'smtp' => array (
       'driver' => 'smtp',
       'username' => 'address@domain.com', // Логин
       'password' => 'password', // Пароль
       'host' => 'ssl://smtp.server.com', // для SSL используйте 'ssl://smtp.server.com', для TLS 'smtp.server.com'
       'port' => 465, // порт 25, для SSL порт 465, для TLS порт 587
       'timeout' => 10,
       'log' => FALSE,
       'options' => array(
            'ssl' => array(
                'verify_peer' => FALSE,
                'verify_peer_name' => FALSE,
                'allow_self_signed' => TRUE
            )
        )
    )
В качестве пароля чаще всего указывается пароль приложений, созданный в интерфейсе почтовой службы, а не пароль от самого ящика!

Мы можем подключиться к портам 465 (SMTP over SSL) или 587 (STARTTLS), если необходим TLS, то установите опцию tls в TRUE и порт в 587:

'smtp' => array (
       'driver' => 'smtp',
       ...
       'port' => 587,
       'tls' => TRUE,
       'timeout' => 10,
       ...
    )

Если адрес электронной почты отличается от username, то используйте дополнительную опцию from с указанием адреса электронной почты:

 'smtp' => array (
       'driver' => 'smtp',
       'username' => 'username', // Логин
       'password' => 'password', // Пароль
       'from' => 'address@domain.com', // Адрес эл. почты
       'host' => 'smtp.server.com', // для SSL используйте ssl://smtp.server.com
       'port' => '25', // Порт, для SSL укажите порт 465
        'options' => array(
            'ssl' => array(
                'verify_peer' => FALSE,
                'verify_peer_name' => FALSE,
                'allow_self_signed' => TRUE
            )
        )
    )

Для отладки включите опцию 'log' в значение TRUE, не забудьте отключить опцию после завершения отладки, так как данные имеют большой размер в логах.

Указание отдельных опций для сайтов

Возможно отдельное задание опций отправки почты для выбранных сайтов, при этом для неуказанных отдельно сайтов будут использоваться общие параметры.

'smtp' => array (
        'driver' => 'smtp',
        // Общие настройки для всех сайтов
        'username' => 'address@domain.com', // Адрес электронной почты
        'port' => '25', // Порт, для SSL укажите порт 465
        'host' => 'smtp.server.com', // для SSL используйте ssl://smtp.server.com
        'password' => 'password', // Пароль
        // Индивидуальные настройки для сайта с ID 17
        17 => array(
            'username' => 'address2@domain2.com', // Адрес электронной почты
            'port' => '25', // Порт, для SSL укажите порт 465
            'host' => 'smtp.server.com', // для SSL используйте ssl://smtp.server.com
            'password' => 'password', // Пароль
        )
    )

Отдельное указание доступно с версии 6.5.9. Секция 'options' добавлена в версии 6.6.8. Поддержка TLS и указание timeout добавлены в версии 6.8.4.

DKIM

Для того, чтобы письма, отправляемые из системы управления, проходили проверку DKIM, необходимо соединиться с сервером по SSH и создать открытый и закрытый ключ. * доступно с версии 7.0.6

Генерация открытого и закрытого ключа

Создаем закрытый ключ, указав вместо domain.com имя домена:

openssl genrsa -out domain.com.privatekey.pem 1024

где «domain.com.privatekey.pem» — файл приватного ключа, «1024» — длина ключа.

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

Создаем открытый ключ, указав вместо domain.com имя вашего домена:

openssl rsa -in domain.com.private.pem -out domain.com.public.pem -pubout

где «domain.com.public.pem» — файл публичного ключа

Содержимое файла открытого ключа domain.com.public.pem после генерирования ключа будет следующим:

-----BEGIN PUBLIC KEY-----
ваш открытый ключ
-----END PUBLIC KEY-----

Указание открытого ключа в NS-записи домена

Через панель регистратора домена, в настройках домена создайте TXT-запись для поддомена mail._domainkey со следующим содержимым:

v=DKIM1; k=rsa; p=ваш-открытый-ключ

Ключ должен быть указан в одну строку, без BEGIN и END.

Указание ключа в настройках системы управления

В настройках драйвера или в настройках конкретного сайта укажите использование DKIM и путь к ключу, пример указания для сайта с кодом 2:

return array (
	'default' => array (
		'driver' => 'sendmail',
	),
	'sendmail' => array (
		'driver' => 'sendmail',
		2 => array(
			'dkim' => array(
				'private_key' => '/home/user4567/domain.com.private.pem',
				'selector' => 'mail',
			)
		),
	);

Кроме приведенных опций, для DKIM могут быть заданы следующие:

array(
	'hash' => 'sha256', // sha256|sha1
	'passphrase' => '',
	'selector' => 'mail',
	'domain' => NULL,
	'identity' => NULL,
	'body_canonicalization' => 'relaxed',
)

Особенности настройки почтовых серверов

Яндекс.Почта

Для подключения к почтовому ящику Яндекс из стороннего приложения не подходит обычный пароль, который используется для входа в учетную запись на Яндексе, создайте специальный пароль приложения.

Также может понадобиться разрешить доступ к почтовому ящику с помощью почтовых клиентов, для этого в почте выберите шестерёнку, затем Все настройки  Почтовые программы.

В качестве SMTP-сервера укажите ssl://smtp.yandex.ru, порт 465, не указывать TLS.

Mail.ru

Для подключения к почтовому ящику Mail.ru из стороннего приложения не подходит обычный пароль, который используется для входа в учетную запись, создайте специальный пароль приложения. Перейдите в настройки Mail ID → «Безопасность» → «Пароли для внешних приложений», нажмите Добавить, введите название приложения, чтобы не забыть, для какой программы пароль, скопируйте сгенерированный пароль приложения.

Настройки TinyMCE

Конфигурация визуального редактора

Конфигурация визуального редактора размещена в файле modules/core/config/wysiwyg.php и содержит параметры его инициализации.

Указание стиля для body редактора

В случае, если контент на вашем сайте отображается внутри блока с определенным стилем, например внутри <div class="myclass">здесь текст</div>, то укажите редактору этот стиль в опции body_class:

    'body_class' => '"myclass"',

Скрытие части кнопок

Для скрытия части кнопок интерфейса используйте опцию toolbar_mode в значении "sliding", чтобы показать все опции сразу укажите "wrap"

    'toolbar_mode' => '"sliding"',

Вставка блочных элементов внутри строчных

Стандартно вставка блочных элементов, например, <div> внутрь <a>, не допускается. Для разрешения такой вставки необходимо внести следующие изменения в конфигурацию визуального редактора:

//'forced_root_block' => '"p"',
'forced_root_block'=> 'false',
'valid_children' => '"+body[style],+a[div|h1|h2|h3|h4|h5|h6|p|#text]"' ,

Вставка тега <p> для первого абзаца

Начиная писать текст в визуальном редакторе, он стандартно оборачивается в тег первого абзаца <p>, чтобы исключить такое поведение внесите следующие изменения в конфигурацию визуального редактора:

//'forced_root_block' => '"p"',
'forced_root_block'=>'false',
'force_p_newlines' => 'false' ,

Добавление плагинов TinyMCE

В файле \modules\core\config\wysiwyg.php строка:
'plugins' => '"safari,pagebreak,style,layer,table,save,advhr,advimage,advlink, emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,inlinepopups"',

Вставка тега <meta> в тексте документа

Стандартно визуальный редактор вырезает теги <meta> из документа. Для изменения данного поведения нужно внести изменения в конфигурацию визуального редактора:

'extended_valid_elements'=>'"meta[*],i[*],noindex[*]"',
'valid_children' => '"+body[style|meta],+a[div|h1|h2|h3|h4|h5|h6|p|#text]"' ,

Если хотите добавлять <meta> в определенных тегах, то расширьте правило. Например, добавление в <footer>:

'valid_children' => '"+body[style|meta],+footer[meta],+a[div|h1|h2|h3|h4|h5|h6|p|#text]"',

Вставка данных из Word

С версии редактора TinyMCE 6 плагин paste стал частью ядра TinyMCE. Разработчики предлагают PowerPaste плагин с ежемесячной оплатой.

С версии 7.0.7 в поставку редактора включен плагин paste, которые осуществляет улучшенную вставку данных из Word (как в TinyMCE 5.x версии), активировать его в можете в списке плагинов.

Отслеживание продаж в Я.Метрике

Владельцы интернет-магазинов могут получать в Яндекс.Метрике детальную информацию о заказах, совершенных на сайте магазина.

Подключение Ecommerce

Перейдите в Метрику. Выберите счетчик, к которому нужно подключить электронную коммерцию. В настройках счетчика включите опцию Электронная коммерция. В код счетчика добавится контейнер для сбора данных dataLayer.

Подключение Ecommerce

Убедитесь, что код счетчика на сайте содержит строку:

ecommerce:"dataLayer"

Установите код счетчика на страницах вашего сайта.

Представление и передача данных в Ecommerce

Чтобы передать данные в виде Ecommerce-объектов сервису Яндекс.Метрики, необходимо поместить их в специальный JavaScript-массив методом push. Такой массив будем называть контейнером данных.

  1. В разделе Настройки перейдите на вкладку Цели.
  2. Нажмите кнопку Добавить цель.
  3. Укажите тип условия JavaScript-событие, которое позволяет указать событие на сайте, которое является индикатором эффективности работы сайта.
  4. Установите Идентификатор цели в ORDER, сохраните номер цели.
  5. Нажмите кнопку Добавить цель. Созданная цель отображается в списке целей.
     
  6. Нажмите кнопку "Сохранить".
  7. В конец файла bootstrap.php добавьте наблюдателя к событию создания заказа Shop_Payment_System_Handler.onAfterProcessOrder и внесите следующий код обработчика события. Не забудьте заменить идентификатор цели (goal_id) в коде обработчика:

PHP

  1. // Цели Яндекс.Метрики при оформлении заказа
    class HostCms_Yandex_Metrika
    {
        static public function onAfterProcessOrder($oShop_Payment_System_Handler)
        {
            $oShop_Order = $oShop_Payment_System_Handler->getShopOrder();
    
            // ЗАМЕНИТЕ ЗНАЧЕНИЕ goal_id НА ИДЕНТИФИКАТОР ВАШЕЙ ЦЕЛИ ORDER
            // Код метрики должен быть выше блока оформления заказа
            ?>
            <script type="text/javascript">
            // $(window).load(function(){
                try {
                    window.dataLayer = window.dataLayer || [];
                    
                    dataLayer.push({
                        "ecommerce": {
                            "currencyCode": "<?php echo htmlspecialchars($oShop_Order->Shop_Currency->code)?>",
                            "purchase": {
                                "actionField": {
                                    "id" : "<?php echo htmlspecialchars($oShop_Order->invoice)?>",
                                    "goal_id" : "999999999"
                                },
                                "products": [
                                <?php
                                    $aShop_Order_Items = $oShop_Order->Shop_Order_Items->findAll(FALSE);
                                    $len = count($aShop_Order_Items);
                                    foreach ($aShop_Order_Items as $key => $oShop_Order_Item)
                                    {
                                        ?>{
                                            name: "<?php echo htmlspecialchars($oShop_Order_Item->name)?>",
                                            price: <?php echo htmlspecialchars($oShop_Order_Item->getPrice())?>,
                                            quantity: <?php echo htmlspecialchars($oShop_Order_Item->quantity)?>
                                        }<?php
    
                                        if ($key < $len - 1)
                                        {
                                            echo "," . PHP_EOL;
                                        }
                                    }
                                ?>
                                ]
                            }
                        }
                    });
                } catch(e) { }
            //});
            </script>
            <?php
        }
    }
    Core_Event::attach('Shop_Payment_System_Handler.onAfterProcessOrder', array('HostCms_Yandex_Metrika', 'onAfterProcessOrder'));
    // /Цели Яндекс.Метрики
    
    
  2. Проверьте оформление заказа, информация о достижении цели должна появиться в конверсиях.

Сессии

Сессии позволяют сохранять пользовательские данные между запросами. Хранение сессий в HostCMS осуществляется в базе данных (по умолчанию) или в Redis (с версии HostCMS 6.8.3, используя php-redis версии 2.6.12+).

Доступ к данным сессии

К данным сессии доступ получается через суперглобальный массив $_SESSION.
$value = $_SESSION['foo'];
Если вы не уверены в наличии требуемого значения в сессии, то используйте Core_Array::getSession(), при отсутствии значения метод вернет NULL
$value = Core_Array::getSession('foo');
То же действие, только с возвратом значения по умолчанию 'default' в случае, если индекса foo в сессии нет
$value = Core_Array::getSession('foo', 'default');

Открытие и закрытие сессии

// Открыть сессиюCore_Session::start();

// Записать в сессию
$_SESSION['foo'] = 'bar';

// Закрыть сессиюCore_Session::close();
Открывать сессию необходимо каждый раз перед там, как записать данные в $_SESSION, дополнительно проверять наличие открытой сессии перед вызовом Core_Session::start() не требуется, проверка содержится внутри метода start().
Проверить, запущена ли сессия:
$bStarted = Core_Session::isStarted();
Проверить, запущена ли сессия и активна:
$bAcive = Core_Session::isAcive();
Получить имя сессии:
$session_name = Core_Session::getName();
Запустить сессию только в случае, если она была ранее запущена в предыдущих сеансах:
if (Core_Session::hasSessionId()){
Core_Session::start();
print_r($_SESSION);}

Времени жизни сессии

При старте сессии, время жизни устанавливается равным времени, указанном в session.gc_maxlifetime, изменить время жизни сессии можно до или уже после запуска сессии методом Core_Session::setMaxLifeTime($maxlifetime, $overwrite = FALSE)
// Время жизни сессии в секундах (1 сутки с момента последней активности)Core_Session::setMaxLifeTime(86400);
Время жизни сессии будет установлено в том случае, если оно больше ранее заданного. Чтобы перезаписать время жизни сессии в любом случае, вторым параметром передайте TRUE.

Конфигурационный файл

Указание способа хранения сессий и опций осуществляется в основном конфигурационном файле modules/core/config/config.php в опции session.
При хранении сессии в базе данных задаются 2 параметра:
  • driver — название драйвера;
  • class — имя класса драйвера (необязательный параметр).
'session' => array(
'driver' => 'database',
'class' => 'Core_Session_Database'
),
Для хранения в Redis требуется больше параметров:
  • driver — название драйвера;
  • class — имя класса драйвера (необязательный параметр);
  • server — адрес сервера, по умолчанию 127.0.0.1;
  • port — порт, по умолчанию 6379;
  • auth —авторизационный пароль, если сервер не требует пароль, то не устанавливайте опцию или укажите NULL;
'session' => array(
'driver' => 'phpredis',
'class' => 'Core_Session_Phpredis',
'server' => '127.0.0.1',
'port' => 6379,
'auth' => 'авторизационный пароль'
),

Увеличить время хранения избранных товаров

Товары в Избранном стали очень мало времени храниться, иногда через 1-2 часа исчезают.
Что делать?
Увеличить время жизни сессии в настройках ТДС магазина.

PHP

Core_Session::setMaxLifeTime(86400 * 30);
// Избранное
if (Core_Array::getRequest('favorite'))
{
$shop_item_id = intval(Core_Array::getRequest('favorite'));
if (Core_Entity::factory('Shop_Item', $shop_item_id)->shop_id == $oShop->id)
{
Core_Session::start();
if (isset($_SESSION['hostcmsFavorite'][$oShop->id]) && in_array($shop_item_id, $_SESSION['hostcmsFavorite'][$oShop->id]))
{
unset($_SESSION['hostcmsFavorite'][$oShop->id][
array_search($shop_item_id, $_SESSION['hostcmsFavorite'][$oShop->id])
]);
}
else
{
$_SESSION['hostcmsFavorite'][$oShop->id][] = $shop_item_id;
}
}