$ npm install uglifycss -g |
whereis uglifycss |
<?
/*
* Класс по минификации CSS-файлов. Использует NodeJS плагин uglifycss
*/
class CCssMinify
{
const DIRS_FOR_CSS_MINIFY = [
'/local/admin/css/',
'/local/components/',
'/local/templates/main/components/',
'/local/templates/main/theme/build/styles/'
];
const FILES_FOR_CSS_MINIFY = [
'/local/templates/main/styles.css',
'/local/templates/main/template_styles.css'
];
private static $bNeedCacheRefresh = false;
/**
* Агент по минификации стилей
*
* @return string
*/
public static function minifyAgent(): string
{
try {
self::minify();
} catch (Exception $obException) {
CEventLog::Add(array(
"SEVERITY" => "ERROR",
"AUDIT_TYPE_ID" => "MINIFY_CSS",
"MODULE_ID" => "main",
"ITEM_ID" => "",
"DESCRIPTION" => $obException->getMessage()
));
}
return __METHOD__.'();';
}
/**
* Минификация стилей, находящихся внутри директорий, обозначенных в константе \dh\CCssMinify::DIRS_FOR_CSS_MINIFY,
* и в файлах в константе \dh\Seo\CCssMinify::FILES_FOR_CSS_MINIFY
*/
public static function minify()
{
foreach (self::DIRS_FOR_CSS_MINIFY as $sDir) {
$arFilePaths = self::findCssFilesInDir($sDir);
if (!empty($arFilePaths)) {
foreach ($arFilePaths as $sFilePath) {
self::execUglifycss($sFilePath);
}
}
}
foreach (self::FILES_FOR_CSS_MINIFY as $sFilePath) {
self::execUglifycss($sFilePath, true);
}
if (self::$bNeedCacheRefresh && BXClearCache(true, "/css/")) {
CEventLog::Add(array(
"SEVERITY" => "INFO",
"AUDIT_TYPE_ID" => "MINIFY_CSS",
"MODULE_ID" => "main",
"ITEM_ID" => "",
"DESCRIPTION" => "Clear cache"
));
}
}
/**
* Получим путь до UglifyCss
* @return string
*/
private static function getUglifyCssPath(): string
{
return '/usr/local/bin/uglifycss';
}
/**
* Поиск Не минифицированных css файлов в Директории (и её поддиректориях)
*
* @param $sDirPath
* @return array
*/
public static function findCssFilesInDir($sDirPath): array
{
$arFilePaths = [];
$obDirectory = new RecursiveDirectoryIterator($_SERVER["DOCUMENT_ROOT"].$sDirPath);
$obIterator = new RecursiveIteratorIterator($obDirectory);
foreach ($obIterator as $obInfo) {
$file_formal = substr($obInfo->getfileName(), strrpos($obInfo->getfileName(), ".") + 1);
$name_search = array("css"); // Список форматов
foreach ($name_search as $key_name) {
if (
$file_formal == $key_name &&
!stristr($obInfo->getfileName(), '.min.css')
) {
$arFilePaths[] = $obInfo->getPathname();
}
}
}
return $arFilePaths;
}
/**
* Выполнить минификацию
*
* @param $sFilePath
* @param bool $bAddDocumentRoot
*/
private static function execUglifycss($sFilePath, bool $bAddDocumentRoot = false)
{
if ($bAddDocumentRoot) {
$sFilePath = $_SERVER["DOCUMENT_ROOT"].$sFilePath;
}
$sMinFilePath = str_replace('.css', '.min.css', $sFilePath);
if (
!file_exists($sMinFilePath) ||
(
file_exists($sMinFilePath) &&
filectime($sFilePath) > filectime($sMinFilePath)
)
) {
/*
* https://www.npmjs.com/package/uglifycss
--output f puts the result in f file
*/
shell_exec(self::getUglifyCssPath().' '.$sFilePath.' --output '.$sMinFilePath);
self::$bNeedCacheRefresh = true;
}
}
} |
npm install uglify-js -g |
whereis uglifyjs |
<?
/*
* Класс по минификации JS-файлов. Использует NodeJS плагин uglifyjs
*/
class CJsMinify
{
const DIRS_FOR_JS_MINIFY = [
'/local/admin/js/',
'/local/templates/main/js/',
'/local/components/',
'/local/templates/main/components/'
];
/**
* Агент по минификации скриптов
*
* @return string
*/
public static function minifyAgent()
{
try {
self::minify();
} catch (Exception $obException) {
CEventLog::Add(array(
"SEVERITY" => "ERROR",
"AUDIT_TYPE_ID" => "MINIFY_JS",
"MODULE_ID" => "main",
"ITEM_ID" => "",
"DESCRIPTION" => $obException->getMessage()
));
}
return __METHOD__.'();';
}
/**
* Минификация скриптов, находящихся внутри директорий, обозначенных в константе \dh\CJsMinify::DIRS_FOR_JS_MINIFY
*/
public static function minify()
{
$bNeedCacheRefresh = false;
foreach (self::DIRS_FOR_JS_MINIFY as $sDir) {
$arFilePaths = self::findJsFilesInDir($sDir);
if (!empty($arFilePaths)) {
foreach ($arFilePaths as $sFilePath) {
$sMinFilePath = str_replace('.js', '.min.js', $sFilePath);
if (
!file_exists($sMinFilePath) ||
(
file_exists($sMinFilePath) &&
filectime($sFilePath) > filectime($sMinFilePath)
)
) {
/*
* https://www.npmjs.com/package/uglify-js
-c, --compress [options] Enable compressor/specify compressor options
-m, --mangle [options] Mangle names/specify mangler options
-o, --output <file> Output file path (default STDOUT)
*/
shell_exec(self::getUglifyJsPath().' '.$sFilePath.' -c -m -o '.$sMinFilePath);
$bNeedCacheRefresh = true;
}
}
}
}
if ($bNeedCacheRefresh && BXClearCache(true, "/js/")) {
CEventLog::Add(array(
"SEVERITY" => "INFO",
"AUDIT_TYPE_ID" => "MINIFY_JS",
"MODULE_ID" => "main",
"ITEM_ID" => "",
"DESCRIPTION" => "Clear cache"
));
}
}
/**
* Получим путь до UglifyJS
* @return string
*/
private static function getUglifyJsPath() {
return '/usr/local/bin/uglifyjs';
}
/**
* Поиск Не минифицированных js файлов в Директории (и её поддиректориях)
*
* @param $sDirPath
* @return array
*/
public static function findJsFilesInDir($sDirPath)
{
$arFilePaths = [];
$obDirectory = new RecursiveDirectoryIterator($_SERVER["DOCUMENT_ROOT"].$sDirPath);
$obIterator = new RecursiveIteratorIterator($obDirectory);
foreach ($obIterator as $obInfo) {
$file_formal = substr($obInfo->getfileName(), strrpos($obInfo->getfileName(), ".") + 1);
$name_search = array("js"); // Список форматов
foreach ($name_search as $key_name) {
if (
$file_formal == $key_name &&
!stristr($obInfo->getfileName(), '.min.js') &&
!stristr($obInfo->getfileName(), '.map.js')
) {
$arFilePaths[] = $obInfo->getPathname();
}
}
}
return $arFilePaths;
}
} |
# .min.js /local/components/**/*.min.js /local/templates/main/components/**/*.min.js /local/templates/main/js/**/*.min.js /local/admin/js/**/*.min.js #.min.css /local/components/**/*.min.css /local/templates/main/components/**/*.min.css /local/templates/main/css/**/*.min.css /local/admin/css/**/*.min.css /local/templates/main/theme/build/styles/**/*.min.css /local/templates/main/styles.min.css /local/templates/main/template_styles.min.css |
use \Bitrix\Main\Data\Cache;
use \Bitrix\Main\Application;
$cache = Cache::createInstance(); // Служба кеширования
$taggedCache = Application::getInstance()->getTaggedCache(); // Служба пометки кеша тегами
/*
* Чтобы тегированный кеш нашел что ему сбрасывать, необходим
* одинаковый путь в $cache->initCache() и $taggedCache->startTagCache()
* У нас путь указан в $cachePath
*/
$cachePath = 'mycachepath';
$cacheTtl = 3600;
$cacheKey = 'mycachekey';
if ($cache->initCache($cacheTtl, $cacheKey, $cachePath))
{
$vars = $cache->getVars();
/*
* Еще тут можно вывести данные в браузер, через $cache->output();
* Тогда получится замена классу CPageCache
*/
}
elseif ($cache->startDataCache())
{
// Начинаем записывать теги
$taggedCache->startTagCache($cachePath);
$vars = [
'date' => date('r'),
'rand' => rand(0, 9999), // Если данные закешированы - число не будет меняться
];
// Добавляем теги
// Кеш сбрасывать при изменении данных в инфоблоке с ID 1
$taggedCache->registerTag('iblock_id_1');
// Кеш сбрасывать при изменении данных в инфоблоке с ID 2
$taggedCache->registerTag('iblock_id_2');
// Если что-то пошло не так и решили кеш не записывать
$cacheInvalid = false;
if ($cacheInvalid)
{
$taggedCache->abortTagCache();
$cache->abortDataCache();
}
// Всё хорошо, записываем кеш
$taggedCache->endTagCache();
$cache->endDataCache($vars);
}
// Данные будут обновляться раз в час или при обновлении данных в инфоблоках 1 и 2
print_r($vars);
|
use \Bitrix\Main\Application;
$taggedCache = Application::getInstance()->getTaggedCache(); // Служба пометки кеша тегами
/*
* Где-то на отдельной странице чистим кеш по тегу
*/
$taggedCache->clearByTag('iblock_id_28');
|
// API credentials from https://login.sendpulse.com/settings/#api
define('SP_API_USER_ID', '---');
define('SP_API_SECRET', '---');
define('SP_FROM_NAME', 'Company name');
define('SP_FROM_EMAIL', 'your@email.com');
require("sendpulse/ApiInterface.php");
require("sendpulse/ApiClient.php");
require("sendpulse/Storage/TokenStorageInterface.php");
require("sendpulse/Storage/FileStorage.php");
require("sendpulse/Storage/SessionStorage.php");
require("sendpulse/Storage/MemcachedStorage.php");
require("sendpulse/Storage/MemcacheStorage.php");
use Sendpulse\RestApi\ApiClient;
use Sendpulse\RestApi\Storage\FileStorage;
function sendpulse($to = array(),$subject = "",$text = "",$html = "",$attachments = array()) {
// $to = array('subscriber@example.com','subscriber2@example.com');
// $attachments => array( 'file1.txt' => '/path/to/file1.txt', 'file2.txt' => '/path/to/file2.txt' )
if(count($to)) {
$to_array = array();
foreach($to as $email) {
$to_array[] = array('email' => $email);
}
$attachments_array = array();
if(count($attachments)) {
foreach($attachments as $name=>$path) {
$attachments_array[$name] = file_get_contents($path);
}
}
$SPApiClient = new ApiClient(SP_API_USER_ID, SP_API_SECRET, new FileStorage());
$email = array(
'text' => $text,
'subject' => $subject,
'from' => array(
'name' => SP_FROM_NAME,
'email' => SP_FROM_EMAIL,
),
'to' => $to_array,
'attachments' => $attachments_array
);
if(strlen($html)) {
$email['html'] = $html . "<p><a href='{{unsubscribe}}'>Unsubscribe</a></p>";
}
$SPApiClient->smtpSendMail($email);
}
}
function custom_mail($to, $subject, $message, $additionalHeaders = '') {
return true;
}
AddEventHandler("main", "OnBeforeEventAdd", "OnBeforeEventAddHandler");
function OnBeforeEventAddHandler(&$event, &$lid, &$arFields, &$message_id, &$files) {
$arfiles = array();
foreach($files as $f) {
if(is_numeric($f)) {
$f = $_SERVER['DOCUMENT_ROOT'] . CFile::GetPath($f);
}
$arfiles['attachment.'.substr(strrchr($f,'.'),1)] = $f;
}
$arFilter = Array(
"TYPE_ID" => $event,
"SITE_ID" => $lid,
"ACTIVE" => "Y",
);
$obMess = CEventMessage::GetList($by="site_id", $order="desc", $arFilter);
while ($arMess = $obMess->GetNext()) {
foreach($arFields as $k=>$v) {
$arMess['MESSAGE'] = str_replace('#' . $k . '#', $v, $arMess['MESSAGE']);
$arMess['EMAIL_TO'] = str_replace('#' . $k . '#', $v, $arMess['EMAIL_TO']);
$arMess['SUBJECT'] = str_replace('#' . $k . '#', $v, $arMess['SUBJECT']);
}
sendpulse(explode(",", $arMess['EMAIL_TO']),$arMess['SUBJECT'],$arMess['MESSAGE'],"",$arfiles);
}
}
|
| Mar 08 09:11:01 host=127.0.0.1 tls=on auth=off from=noreply@binpro.ru recipients=alex-00@mail.ru mailsize=3749 smtpstatus=250 smtpmsg='250 2.0.0 Ok: queued as A6E0723B4D' exitcode=EX_OK Mar 08 09:40:05 host=127.0.0.1 tls=on auth=off from=noreply@binpro.ru recipients=velobox@inbox.ru mailsize=36938 smtpstatus=250 smtpmsg='250 2.0.0 Ok: queued as 8FC7E23B4C' exitcode=EX_OK Mar 08 10:09:03 host=127.0.0.1 tls=on auth=off from=noreply@binpro.ru recipients=alex-00@mail.ru mailsize=3749 smtpstatus=250 smtpmsg='250 2.0.0 Ok: queued as D129E23B51' exitcode=EX_OK |
| # smtp account configuration for default account default logfile /home/bitrix/msmtp_default.log host 127.0.0.1 port 25 from noreply@binpro.ru keepbcc off auth off tls on tls_certcheck off |
| sendmail_path = sendmail -t -i -f noreply@binpro.ru ;bitrix-env |
127.0.0.1 localhost localhost.localdomain ::1 localhost localhost.localdomain 23.111.204.11 binpro.ru |
| if(mail("", "TEST SUBJECT", "TEST BODY"))echo "Почтовая система работает!"; else echo "Неудача, почтовая система не работает, попробуйте еще!"; |
| php -r "mail('', 'Test', 'Test');" |
| echo "hello from mail.com.ru." | msmtp --debug -a site.ru где site.ru - значение account в конфиге .msmtprc |
| # smtp account configuration for site.ru account site.ru logfile /home/bitrix/msmtp_site.ru.log host smtp.yandex.ru port 587 from keepbcc on auth on user password *********** tls on tls_starttls on tls_certcheck off |
$properties['PRICE_ADD'] = array(
'NAME' => 'Наценка',
'CODE' => 'PRICE_ADD',
'VALUE' => $request->getPost('price_add'),
'SORT' => 500
);
|
/**
* @param array $products
*
* @return Sale\Result
*/
public function getProductData(array $products)
{
$result = parent::getProductData($products);
// Во избежании казусов при работе с командной строкой PHP
if(!Bitrix\Main\Context::getCurrent()->getSite())
return $result;
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
$productDataList = array();
foreach($result->getData()['PRODUCT_DATA_LIST'] as $productId => $arProduct)
{
foreach($arProduct['PRICE_LIST'] as $basketItemId => &$arItem)
{
// При добавлении в корзину нет у товара ID, мы не сможем его свойства тут посмотреть
if((int)$basketItemId !== 0)
{
if($basketItem = $basket->getItemById($basketItemId))
{
$properties = $basketItem->getPropertyCollection()->getPropertyValues();
// Если есть наценка, добавляем её к цене
if(!empty($properties['PRICE_ADD']) && isset($properties['PRICE_ADD']['VALUE']))
{
$arItem['BASE_PRICE'] = $arItem['BASE_PRICE'] + (float)$properties['PRICE_ADD']['VALUE'];
$arItem['PRICE'] = $arItem['PRICE'] + (float)$properties['PRICE_ADD']['VALUE'];
}
}
}
}
$productDataList[$productId] = $arProduct;
unset($arItem);
}
$result->setData(['PRODUCT_DATA_LIST' => $productDataList]);
return $result;
}
|
$item->setField('QUANTITY', $value); |
$item->setFieldNoDemand('QUANTITY', $value); |
// Не надо нам при удалении ничего пересчитывать здесь. Таков путь.
if(!$_POST['sbblRemoveItemFromCart'])
{
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(\Bitrix\Sale\Fuser::getId(), SITE_ID);
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$result = $basket->refresh($refreshStrategy);
$basket->save();
}
|
$eventManager = \Bitrix\Main\EventManager::getInstance();
// draw user picture after login
$eventManager->addEventHandler(
"main",
"OnAdminListDisplay",
/** @param CAdminUiList $this_al */
static function (&$this_al) {
if ($this_al->table_id == "tbl_user") {
foreach ($this_al->aRows as &$row) {
$userId = (int)$row->arRes['ID'];
$picPath = CFile::GetPath( (CUser::GetByID($userId)->Fetch())["PERSONAL_PHOTO"] );
if (trim($picPath) != '') {
$row->aFields["LOGIN"]["view"]["value"] .= ' <br><a target="_blank" href="' . $picPath . '">'
. '<img style="max-width:200px;" src="' . $picPath . '"></a>';
}
}
}
}
); |