• Почему не проходит DMARC?

    DMARC проходит в случае, если в письме есть авторизация SPF или DKIM которая находится в соответствии (align) c доменом в адресе отправителя (From:). Под элайном по умолчанию понимается совпадение организационного домена.
    В вашем случае организационный домен из адреса From: mta-my-mails.ru, организационный домен из DKIM adspromo.ru и организационный домен в SPF adspromo.ru. Соответственно ни DKIM ни SPF не соответствуют домену From, поэтому DMARC не проходит проверку.

    Т.е. вам надо либо поменять адрес отправителя на @adspromo.ru либо использовать DKIM/SPF домена mta-my-mails.ru (или хотя бы DKIM).
    Ответ написан
    2 комментария
  • Почему gulp-sass прогрессивно увеличивает время исполнения таска?

    reskwer
    @reskwer Автор вопроса
    front-end developer
    Решение найдено! Всему виной оказался Вотчер, к примеру имеем мы вот такой вотчер для стилей.
    gulp.task('watch', function() {
    	gulp.watch('sass/**/*.scss', gulp.series('style'));
    });

    Всему виной вот эта конструкция, **
    bc1a60d24bd74453801fdf083fb135b1.png

    Не используйте в вотчере такую конструкрую, пишите прямо все папки где искать, к примеру вот так
    gulp.watch(['sass/*.scss', 'sass/block/*.scss', 'sass/page/*.scss'], gulp.series('style'));

    В данном примере мы указали 3 папки где будут вотчится все файлы, это sass, block, page. и если теперь вы будете редактировать файлы из этих папак, то стили у вас будут собираться рекордно быстро, и время исполнения таска НЕ БУДЕТ УВЕЛИЧИВАТЬСЯ

    ПРИМЕР!!
    Имея вот такой таск вотчера.
    gulp.task('watch', function() {
    	gulp.watch('sass/**/*.scss', gulp.series('style'));
    });

    Я захожу в файл sass/components/header.scss и редактирую рас 10, пока время выполнения таска не доходит до секунды, потом захожу в файл sass/block.scss и редактирую его 3 раза, обратити внимания на скорость выполнения таска.. 150-180 милисекунд дальше я опять редактирую фай sass/components/header.scss и время выполнения таска уже больше однойсекунды.. так что делайте вывод господа..
    ba7cfc8431e544f28cf001a426b50753.png
    Ответ написан
    3 комментария
  • Как перенести БД пользователей из WordPress в 1С Битрикс?

    Express777
    @Express777 Автор вопроса
    Наконец то смог импортировать пользоватлей из вордпресса в битрикс.
    Я уже достаточно написал в обновлениях, чтобы можно было самому уже написать весь код.
    Но, на всякий случаи привожу свою версию с комментариями. Может и пригодится:

    1. Пользователей мы будем импортировать через стандатный сервис битрикса "импоритровать пользователей". Через него можно импортировать практический все, что относиться к юзерам:
    Импорт пользователей через CSV
    2. Если хотите импортировать пользовательское свойство, просто укажите название колонки с доп свойством, например UF_USER_FIELD и значения в нем, ( если это не множественное свойство, о множественных ниже).
    Если картинку (аватар), просто укажите в колонке PERSONAL_PHOTO относительный путь до картинки. Папку, с которой будут браться картинки, указываете в админ панели при импорте юзеров: "Путь к картинкам относительно корня сайта ".

    Теперь к конкретике.
    информация о юзерах в вордпрессе хранится в таблицах:
    wp_users - логин, пароль, емаил
    wp_bp_xprofile_data - аналогия с пользовательскими свойствами битрикса, хранятся значения
    wp_bp_xprofile_fields - названия пользовательских свойств

    Нужно в запросе связать эти таблицы и создать CSV file.
    Example:
    //  Подключение к БД вордпресса
    $mysqli = new mysqli("localhost", "root", "", "wp") or die("Not connected"); 
    if ($mysqli->connect_errno) {
        printf("Connect failed: %s\n", $mysqli->connect_error);
        exit();
    }
    $query = "select 
    	t_users.ID as `UF_OLD_USER_ID` /*Заранее создал поль 
            свойство с таким именем. Понадобится при импорте аватарок, 
            да и лучше сохранить старые ИД. На всякий случаи. */
    	, '1.jpg' as `PERSONAL_PHOTO`
    	, t_users.user_login as `LOGIN`
    	, t_users.user_pass as `PASSWORD`
    	, t_users.user_email as `EMAIL`
    	, t_users.user_registered as `DATE_REGISTER`
    	, SUBSTRING_INDEX(t_users.display_name, ' ', 1) as `NAME`
    	, SUBSTRING_INDEX(t_users.display_name, ' ', -1) as `LAST_NAME`
    	, max(CASE WHEN t2.name = 'Телефон'
    		THEN t1.value ELSE null END) as `PERSONAL_PHONE` 
    	, max(CASE WHEN t2.name = 'Город'
    		THEN t1.value ELSE null END) as `PERSONAL_CITY` 
    	, max(CASE WHEN t2.name = 'Адрес студии'
    		THEN t1.value ELSE null END) as `UF_ADDRESS` 
    	, max(CASE WHEN t2.name = 'Сайт'
    		THEN t1.value ELSE null END) as `PERSONAL_WWW` 
    	, max(CASE WHEN t2.name = 'Образ'
    		THEN t1.value ELSE null END) as `MASTER_SERVICE_1` 
    	, max(CASE WHEN t2.name = 'Визажист'
    		THEN t1.value ELSE null END) as `MASTER_SERVICE_2` 
    	
    
    	
    FROM wp_bp_xprofile_data as t1
    INNER JOIN  wp_bp_xprofile_fields as t2
    	on t1.field_id = t2.id
    INNER JOIN wp_users t_users
    	ON t_users.ID = t1.user_id 
    #where user_id = 3
    group by t1.user_id
    ";
    
    if( !$mysqli->query( $query ) )
    {
    	printf("Error: %s\n<br />", $mysqli->error);	
    }
    
    $create_q = "";
    $res = $mysqli->query( $query);
    $fp = fopen('file.csv', 'w+'); // Создание csv файла
    
    while ( $row = $res->fetch_assoc())
    {
    	// Некоторые значения хранятся в сериализированном виде. Преобразуем в массив.
    	$tmp1 = unserialize($row["MASTER_SERVICE_1"]) ? unserialize($row["MASTER_SERVICE_1"])  : array(); 
    	$tmp2 = unserialize($row["MASTER_SERVICE_2"]) ? unserialize($row["MASTER_SERVICE_2"])  : array();
    	// в Битриксе в сер виде хранятся значения множественных свойств.
    	$tmp = array_merge( $tmp1, $tmp2);


    Есть два пути сохранить значения множ свойств в Битриксе.
    Первый, по битриковский: Для каждого значения нужно создать новую строку в CSV.
    То есть, в каждой новой строчке должный быть те же данные
    у простых типов и меняться значение только у множественного свойства.
    И так, пока не переберешь все значения.


    Второй, через костыль.
    Сохранить все значения множ свойства в массив и:
    2.1 Записать значения напрямую в БД битрикса
    2.2 Через метод Cuser::update обновить значения у уже созданного пользователя. В качестве значения, нужно передавать как раз массив.
    По незнанию я выбрал метод 2.1


    Если нужно, подправляем данные в массиве tmp.

    Импортируем старые аватарки.
    Как я уже писал автарки хранятся как /uploads/avatars/[member_id]/[avatar file]

    $pathName = "./uploads-portfolio/avatars/".$row["UF_OLD_USER_ID"]."/";
    	$entries = scandir( $pathName );
    	$pattern = "#[\w\d]*-bpfull\.(png|jpg)$#";
    	
    	foreach($entries as $entry) 
    	{
    	    if ( preg_match($pattern, $entry)) 
    	    {
    	        $row["PERSONAL_PHOTO"] = "/".$row["UF_OLD_USER_ID"]."/".$entry;
    	    }
    	}
    
    	$tmp = array_unique( $tmp );
    // У меня UF_MASTER_SERVICE поль свойство множественного значения
    	$row["UF_MASTER_SERVICE"] = serialize($tmp);
    	fputcsv($fp, $row, ";", '"');
    	
    }

    Файл для импорта почти готов. Не забудьте добавить названия колонок. Сделать можно в Экселе или Libre Calc.

    Теперь в init.php добавляем события:
    Про сохранение паролей, прочитайте здесь:
    dev.1c-bitrix.ru/community/webdev/user/42405/blog/... ( Petr Zhuchkov Petr Zhuchkov )
    AddEventHandler("main", "OnAfterUserAdd", "__afterUserAdd");
    function __afterUserAdd( $arParams )
    {
         if(defined("USER_IMPORT_EXECUTION_TIME"))
         {
             // Adding multiply property for imported User
             // MY_MASTER_SERVICE - название колонки с множественным свойством
             // RESULT - ИД только, что созданного пользователя
             $mysqli = new mysqli("localhost", "root", "", "bitrix_db");
             $sql = "UPDATE b_uts_user SET UF_MASTER_SERVICE = '"
                    .$arParams["MY_MASTER_SERVICE"]
                    ."' WHERE VALUE_ID =".$arParams["RESULT"];
             $result = $mysqli->query( $sql);
             if( !$result )
             {
                 echo $mysqli->error;
             }
         }
    }

    Будье осторожны при этом методе. Внесенные данные видны в профиле пользователя. Даже берутся методом Getlist. Но, почему то не работают в поиске. А мне как раз нужен был поиск по этому свойству. Выход в цикле обновить значения множ свойства всех пользователей через Cuser::update.

    Все.
    Ответ написан
    1 комментарий
  • Какой алгоритм шифрования подойдет для доступа несколькими паролями?

    Любой симметричный (да и асимметричный) алгоритм.
    Зашифруйте storage мастер-ключом достаточной стойкости, а затем добавляйте к хранилищу в служебных данных мастер-ключ, зашифрованный разными пользовательскими ключами.
    Это стандартный прием.

    P.S. Если алгоритм - асимметричный, то такая технология называется "депонирование" (key escrow) и широко используется, когда к зашифрованным данным нужно предоставить доступ еще и различным надзорным/силовым ведомствам.
    Ответ написан
    Комментировать
  • Какой смысл в использовании шаблонизаторов?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Шаблонизатор шаблонизатору рознь. Но в целом следует выделить общие задачи. которые должны решать за вас шаблонизаторы. С blade не работал и не вижу смысла есть есть twig.

    Безопасность. Это пожалуй можно поднять на верх. Типичная картина в шаблонах на php - <?= $someUserInput; ?>. Частенько это можно встретить в выводе инпутов, при формировании ошибок поиска (мол "по запросу $userInput ничего не найдено. То есть вставляем в инпут подключение наших js скриптиков, если это форма поиска - делимся с "другом" и забираем его сессию. Ну или еще какие забавные штуки можно делать. А ведь все очень просто решается. Ставим какую-то функцию, которая по умолчанию будет фильтровать XSS инъекции при выводе, и не будет этого делать только если мы попросим. Если писать просто на php - появляются отвратные функции, которые можно просто забыть вызвать. А с шаблонизаторами мы пишем красивые {{ someUserInput }} и можем спать спокойно.

    Помогают соблюдать принцип DRY. Современные средства шаблонизации (twig например), предоставляют вам возможность разделять шаблоны на блоки, переиспользовать их несколько раз, выделять макросы, наследовать шаблоны... словом все что угодно. лишь бы вы могли реюзать куски html а не копипастить их.

    Ограничивают полет фантазии разработчика. Далеко не новость что разработчики ленивые засранцы. Особенно молодые. Если им в шаблоне внезапно понадобились какие-то данные из БД, или данные связанные с запросом, большинство не будет париться и зафигачит нужный код прямо в темплейте. Так же некоторые грешат тем что часть бизнес логики размазывают по шаблонам. Так же встречал проекты отданные на суппорт, где чуваки в шаблонах разбирали через xpath ответы от сторонней апишки (которая использовалась вместо базы данных. То есть это дело было размазано по всему проекту). Рефакторинг в случае изменения апишки будет болью.

    Хороший шаблонизатор должен настолько сильно усложинить вам процесс написания говнокода в шаблонах, что бы вы перехотели это делать и подумали как это можно сделать нормально. На выходе же мы имеем чистенькие шаблоны, которые ничего не знаю о бизнес логике приложения и знают только о логике отображения, чего мы и добиваемся вообще разделяя логику от представления. Это так же упрощает жить верстальщику (если он отдельно существует) или вам же в будущем при суппорте.

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

    Так как за все эти приятные вещи мы по сути ничего не платим (шаблонизатор должен компилировать все это в нативный php так что оверхэда просто не будет), почему бы не пользоваться?
    Ответ написан
    1 комментарий