Отправка почты из docker контейнера



 RUN apt-get update && \
  apt-get install -y msmtp && \
  apt-get clean && \
  echo "account yandex" >> ~/.msmtprc && \
  echo "logfile ~/.msmtp.log" >> ~/.msmtprc && \
  echo "host smtp.yandex.ru" >> ~/.msmtprc && \
  echo "port 587" >> ~/.msmtprc && \
  echo "from no-reply@serov.eu" >> ~/.msmtprc && \
  echo "keepbcc on" >> ~/.msmtprc && \
  echo "auth on" >> ~/.msmtprc && \
  echo "user no-reply@serov.eu" >> ~/.msmtprc && \
  echo "password Uzum2G9pkZt" >> ~/.msmtprc && \
  echo "tls on" >> ~/.msmtprc && \
  echo "tls_starttls on" >> ~/.msmtprc && \
  echo "tls_certcheck off" >> ~/.msmtprc && \
  chmod 0600 ~/.msmtprc && \
  cp -p ~/.msmtprc /etc/.msmtp_php && \ 
  chown www-data:www-data /etc/.msmtp_php && \ 
  touch /var/log/msmtp.log && \ 
  chown www-data:www-data /var/log/msmtp.log
 

в php.ini

sendmail_path = "/usr/bin/msmtp -C /etc/.msmtp_php --logfile /var/log/msmtp.log -a yandex -t"

Другие конфиги



account yandex
 logfile /var/log/msmtp.log
 host smtp.yandex.ru
 port 587
 from mail@yandex.ru
 keepbcc on
 auth on
 user mail@yandex.ru
 password пароль
 tls on
 tls_starttls on





account yahoo
 tls on
 tls_starttls off
 tls_certcheck off
 auth on
 host smtp.mail.yahoo.com
 user user1
 from user1@yahoo.com
 password yourYahooPa5sw0rd





account gmail
 tls on
 tls_certcheck off
 auth on
 host smtp.gmail.com
 port 587
 user user1@gmail.com
 from user1@gmail.com
 password yourgmailPassw0rd



Тестирование:


echo -e "test message" | /usr/bin/msmtp --debug -t -i name@site.ru

Сортировка данных в php

Например, у нас есть какой то набор данных, в stdClass. Он многомерный, и его надо сортировать, например по дате.
Делаем первое

array_walk_recursive($t, function(&$t) {return $t->date=strtotime($t->Created);});

Здесь мы создаем дополнительный элемент, к каждому набору записи, в которую записываем unix timestamp для сравнения.
Далее, сортируем набор данных по полю date

usort($t, function($a, $b){
return ($b->date - $a->date);
});

Не знаю, насколько это быстрее foreach или for, пока у меня не было несколько миллиардов записей, а до 1000 записей, существенной разницы не увидим.

Для более сложной сортировки, лучше использовать array_multisort, но это уже только для массива, хотя stdClass позволяет работать как с массивом.

Область видимости объектов в памяти PHP

1.php Создадим объект класса и запишем его в массив.

<?php
$std = new stdClass();
$std->first = 1;
session_start();
$_SESSION['test1'] = $std;
print_r($_SESSION['test1']);

2.php В другом файле прочитаем его.

<?php
session_start();
$std = $_SESSION['test1'] ;
$std->first = 'first';

3.php В третьем файле выводим

<?php
session_start();
print_r($_SESSION['test1']->first);

Что получим? Правильно

first

Хотя мы не записывали переменную std в Сессию, так как это объект, str ссылается на объект, который в сессии, и при изменение его, мы меняем этот же объект в сессии.

То же самое правильно для функции.

При передачи объекта в функцию, при модификации объекта в функции он изменяется и после нее.

 

 

 

Вытащить из яндекс список популярных страниц.

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

На сайте стоит яндекс метрика, а яндекс через api предлагает получить список популярных страниц.

 

Написал две функции, которые справляются с поставленной задачей.

 

 

// отправляем запрос курлом
function getTokenYandex2($url,$peremen,$headers) {
    $post_arr=array();
    foreach ($peremen as $key=>$value) {
        $post_arr[]=$key."=".$value;
    }
    $data=implode('&',$post_arr);

    $handle=curl_init();
    curl_setopt($handle, CURLOPT_URL, $url);
    curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($handle, CURLOPT_POST, true);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
    $response=curl_exec($handle);
    $code=curl_getinfo($handle, CURLINFO_HTTP_CODE);
    return array("code"=>$code,"response"=>$response);
}


function getInfoYandex($token){


    $startTime = strtotime(date('Y-m-d')." -1 month");
    $startTime=date("Ymd",$startTime);

    $ch = curl_init( 'http://api-metrika.yandex.ru/stat/content/popular?id=____ID___5&per_page=500&date1='.$startTime.'&date2='.date('Ymd', time()));

    // получать заголовки
    curl_setopt ($ch, CURLOPT_HEADER, 0);
    // если ведется проверка HTTP User-agent, то передаем один из возможных допустимых вариантов:
    curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
    // авторизация в яндекс по токену
    curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Authorization: OAuth '.$token, 'Accept: application/x-yametrika+json', 'Content-Type: application/x-yametrika+json'));
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10 );
    curl_setopt ($ch, CURLOPT_TIMEOUT, 10 );
    // возвращать результат работы
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    // не проверять SSL сертификат
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
    // не проверять Host SSL сертификата
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
    // следовать редиректу
    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
    // выполнить запрос
    curl_exec ($ch);
    // получить результат работы
    $result = curl_multi_getcontent ($ch);

    return json_decode($result);

}


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

 

Все это вызывается вот так:

 

 

// вызываем функцию получения токена
$result=getTokenYandex2("https://oauth.yandex.ru/token",
    array(
        'grant_type'=> 'password', // тип авторизации
        'username'=> '_____ВАШ__ЛОГИН________',
        'password'=>'______ВАШ_ПАРОЛЬ_____________',
        'client_id'=>'_____КЛИЕНТ_ID__ПОЛУЧАЕМ_В_ЯНДЕКС_API___________',
        'client_secret'=>'______ПОЛУЧАЕМ_В_ЯНДЕКС_API___________',
    ),
    array('Content-type: application/x-www-form-urlencoded','Connection: close')
);



$token=json_decode($result['response']);
// спрашиваем у яндекса, какие страницы популярны
$listPageYandex=GetInfoYandex($token->access_token);

в итоге у нас массив из популярных страниц, дальше находил эти страницы в bitrix и менял им вес.

PS. Список популярных страниц запрашивается за последний месяц.

 

 

PPS.

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

Замутил даже на сокете авторизацию :)

 

 

$sock=fsockopen('ssl://oauth.yandex.ru', 443);	// curl замена
$fields="grant_type=password&username=LOGIN&password=PASSWORD&client_id=400000000000000000000000000000&client_secret=4000000000000000000003";
$msg="POST /token HTTP/1.1\r\nHost: oauth.yandex.ru\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: close\r\nContent-Length: ".(strlen($fields))."\r\n\r\n".$fields."\r\n\r\n\r\n";
fwrite($sock, $msg);
$resp='';
while (!feof($sock)) {
    $resp.=fgets($sock, 128);
};
fclose($sock);
$arr=Array();
preg_match_all("/{.*?}/", $resp, $arr);
$json=json_decode($arr[0][0]);
var_dump($json);

Это в принципе работает, но курлом как то правильнее что-ли.
Тут кстати есть подводные камни, сервер яндекс все никак не хотел закрывать соединения, пока не добавил Connection: close.

Импорт в bitrix

Есть задачка, прочитать excel файл, напротив каждого региона есть запись. Нужно регион сопоставить с его ID в bitrix и дальше методом add добавить.

Написал такую функцию

 

 

function getNumberRegion($name){

    $arrayRegion=array(
        38285=>'Брянская область',
        38284=>'Владимирская область',
        38283=>'Волгоградская область',
        38282=>'Вологодская область',
        38281=>'Воронежская область',
        38280=>'Еврейская автономная область',
        38279=>'Ивановская область',
        38278=>'Иркутская область',
        38277=>'Калининградская облатсь',
        38276=>'Калужская область',
        38275=>'Кемеровская область',
        38274=>'Кировская область',
        38273=>'Костромская область',
        38272=>'Курганская область',
        38271=>'Курская область',
        38269=>'Липецкая область',
        38268=>'Магаданская область',
        38267=>'Москва',
        38265=>'Мурманская область',
        38264=>'Республика Адыгея',
        38263=>'Нижегородская область',
        38262=>'Республика Алтай',
        38261=>'Республика Башкортостан',
        38260=>'Новгородская область',
        38259=>'Новосибирская область',
        38258=>'Республика Бурятия',
        38257=>'Республика Дагестан',
        38256=>'Омская область',
        38255=>'Республика Ингушетия',
        38254=>'Кабардино-Балкарская республика',
        38253=>'Оренбургская область',
        38252=>'Орловская область',
        38251=>'Пензенская область',
        38250=>'Псковская область',
        38249=>'Ростовская область',
        38248=>'Рязанская область',
        38247=>'Самарская область',
        38246=>'Санкт-Петербург',
        38245=>'Саратовская область',
        38244=>'Сахалинская область',
        38243=>'Свердловская область',
        38242=>'Смоленская область',
        38241=>'Тамбовская область',
        38240=>'Тверская область',
        38239=>'Томская область',
        38238=>'Тульская область',
        38237=>'Тюменская область',
        38236=>'Ульяновская область',
        38235=>'Челябинская область',
        38234=>'Ярославская область',
        38233=>'Ханты-Мансийский автономный округ - ЮГРА',
        38232=>'Чукотский автономный округ',
        38231=>'Ямало-Ненецкий автономный округ',
        38230=>'Республика Калмыкия',
        38229=>'Карачаево-Черкесская республика',
        38228=>'Республика Карелия',
        38227=>'Республика Коми',
        38226=>'Республика Марий Эл',
        38225=>'Республика Мордовия',
        38224=>'Республика Саха (Якутия)',
        38223=>'Республика Северная Осетия-Алания',
        38222=>'Республика Татарстан',
        38221=>'Республика Тыва',
        38220=>'Удмуртская республика',
        38219=>'Республика Хакасия',
        38218=>'Чеченская республика',
        38217=>'Чувашская республика',
        38216=>'Забайкальский край',
        38215=>'Камчатский край',
        38214=>'Краснодарский край',
        38213=>'Красноярский край',
        38212=>'Пермский край',
        38211=>'Приморский край',
        38210=>'Ставропольский край',
        38209=>'Хабаровский край',
        38208=>'Амурская область',
        38207=>'Архангельская область',
        38206=>'Астраханская область',
        38190=>'Ленинградская область',
        38189=>'Белгородская область',
        38188=>'Алтайский край',
        38185=>'Московская область',
    );
    // в нижний регистр массив
    array_walk_recursive($arrayRegion, function (&$item, $key) { if (is_string($item)) $item = mb_strtolower($item); });
    return array_search(mb_strtolower(trim($name)),$arrayRegion,true);

}

function delc2a0($str){
    return str_replace("\xc2\xa0", '', $str);
}

 

подаем на функцию регион, он возвращает его номер,  ничего сложного.

PS функция delc2a0 для удаления мусора, когда читаем excel.

 

SOAP and BASE64

Потратил около часа, чтобы понять, почему при кодировании в base64 и передачи это через SOAP, получатель не может прочитать файл.

Оказалось все просто. SOAP сам упаковывает данные в BASE64 и конструкция

$imgbinary = fread(fopen($data['FormFileBuffer'], "r"), filesize($data['FormFileBuffer']));
 $base64File = base64_encode($imgbinary);

 

оказалась не нужна, достаточно сразу было отдать $imgbinary

 

Удалить все куки с вашего сайта

Delete all cookies of my website.

Это можно сделать через JS, или через запрос сервера.

Как выяснилось, через JS нельзя удалить все куки.

Вот скрипт на php + JS, которой удалить все куки, установленные на вашем сайте + куки всяких сторонних сервисов (гугл плюс, фейсбук и тд)

 

<?php

$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
setcookie( $key, $value, $past, '/' );
}

?>
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Clear </title>
</head>
<body>

<script>
function deleteAllCookies() {
var cookies = document.cookie.split(";");

for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
deleteAllCookies();
</script>

</body>
</html>