За последние 24 часа нас посетили 37954 программиста и 3305 роботов. Сейчас ищут 1462 программиста ...

Оцените правильность подтверждения регистрации.

Тема в разделе "PHP для новичков", создана пользователем виталий032, 4 ноя 2017.

  1. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Хочу спросить, говнокод я написал или нет?
    Подтверждение аккаунта по email и ключу. Ключ в таблице в поле 'act_key'. В поле 'send_date' дата отправки юзеру ссылки активации.
    На сайтах обучалках дата просрочки ссылки везде проверяется лишь вычитанием текущей даты и даты отправки ссылки подтверждения. А, если месяцы разные, а если год разный (30 декабря и 1 января), а если год високосный и месяц февраль. Поэтому я приготовил это:

    PHP:
    1. public function activate($user_email, $key, Request $request)
    2.     {
    3.         $user = Activate_users::where([
    4.             ['email', $user_email],
    5.             ['act_key', $key]
    6.         ])->select('email', 'activate', 'act_key', 'send_date')->get();
    7.  
    8.  
    9.         // if act_key exists in database and act_key from database matches key from activation link
    10.         if(isset($user[0]->act_key) && $user[0]->act_key == $key)
    11.         {
    12.             // send_date format: Y-m-d
    13.             $send_date  = explode('-', $user[0]->send_date);
    14.             $send_year  = $send_date[0];
    15.             $send_month = $send_date[1];
    16.             $send_day   = $send_date[2];
    17.  
    18.             $today_date = explode('-', date('Y-m-d'));
    19.             $today_year = $today_date[0];
    20.             $today_month = $today_date[1];
    21.             $today_day = $today_date[2];
    22.  
    23.             $special_year = array(
    24.                 '0' => '2016',
    25.                 '1' => '2020',
    26.                 '2' => '2024',
    27.                 '3' => '2028',
    28.                 '4' => '2032',
    29.                 '5' => '2036',
    30.             );
    31.  
    32.             $days_in_month = array(
    33.                 '01'  => 31,
    34.                 '02'  => 28,
    35.                 '03'  => 31,
    36.                 '04'  => 30,
    37.                 '05'  => 31,
    38.                 '06'  => 30,
    39.                 '07'  => 31,
    40.                 '08'  => 31,
    41.                 '09'  => 30,
    42.                 '10'  => 31,
    43.                 '11'  => 30,
    44.                 '12'  => 31,
    45.             );
    46.  
    47.             // count how many days passed from the day when we sent to user activation link
    48.             $days_have_passed = $today_day - $send_day;
    49.  
    50.             // if years match and months match
    51.             if($today_year == $send_year && $today_month == $send_month)
    52.             {
    53.                 // if only 3 or less days passed from sending activation link
    54.                 if(preg_match('/^[0-3]$/', $days_have_passed))
    55.                 {
    56.                     // activate user
    57.                 }
    58.                 // if $days_have_passed bigger than 3
    59.                 throw new Exception('Activation_error');
    60.             }
    61.             // if years match but months are different
    62.             elseif($today_year == $send_year && $today_month - 1 == $send_month)
    63.             {
    64.                 /*
    65.                  * Event
    66.                  *
    67.                  * Send date: The 3d of October
    68.                  * User clicked on the link on 3d of November
    69.                  *
    70.                  * $send_month_has_days = 31;
    71.                  * $days_to_today_month = 28;
    72.                  * $days_have_passed    = 28 + 3 = 31;
    73.                  */
    74.                 $send_month_has_days = $days_in_month[$send_month];
    75.                 $days_to_today_month = $send_month_has_days - $send_day;
    76.                 $days_have_passed = $days_to_today_month + $today_day;
    77.  
    78.                 // if only 3 or less days passed from sending activation link
    79.                 if(preg_match('/^[0-3]$/', $days_have_passed))
    80.                 {
    81.                     // activate user
    82.                 }
    83.  
    84.                 // if $days_have_passed bigger than 3
    85.                 throw new Exception('Activation_error');
    86.             }
    87.             // if today is 2018 and send_year is 2017
    88.             elseif($today_year - 1 == $send_year)
    89.             {
    90.                 // if it was leap-year when we sent to user activation link (28 days in February)
    91.                 for($i=0; $i<6; $i++)
    92.                 {
    93.                     if($send_year == $special_year[$i])
    94.                     {
    95.                         $days_in_month['02'] = 29;
    96.                     }
    97.                 }
    98.  
    99.                 /*
    100.                  * Event
    101.                  *
    102.                  * Send date: The 29th of December 2017
    103.                  * User clicked on the link on 3d of January 2018
    104.                  *
    105.                  * $send_month_has_days = 31;
    106.                  * $days_to_today_month = 2;
    107.                  * $days_have_passed    = 2 + 3 = 5;
    108.                  */
    109.                 $send_month_has_days = $days_in_month[$send_month];
    110.                 $days_to_today_month = $send_month_has_days - $send_day;
    111.                 $days_have_passed = $days_to_today_month + $today_day;
    112.  
    113.                 // if only 3 or less days passed from sending activation link
    114.                 if(preg_match('/^[0-3]$/', $days_have_passed))
    115.                 {
    116.                     // activate user
    117.                 }
    118.  
    119.                 // if $days_have_passed bigger than 3
    120.                 throw new Exception('Activation_error');
    121.             }
    122.         }
    123.     }
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Есть такое блестящее изобретение человечества, как UNIX TIMESTAMP - вычитаете из секунд секунды, с секундами сравниваете - 3 строчки. А другие умные люди сделали класс DateTime как часть стандартной библиотеки PHP, опять же, $date1->diff($date2) - и там уже все года, века, тысячелетия будут учтены. И не нужно таких портянок писать.
     
    виталий032 нравится это.
  3. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.821
    Симпатии:
    1.333
    Адрес:
    Лень
    что значит в твоем приготовлении Request ?
     
  4. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    По моему это все излишнее, достаточно будет отправить ссылку с ключем, а юзер хочет не хочет переходит по ней)
     
  5. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Это инъекция объекта класса Request. Остался, как рудимент, забыл удалить. Так как это laravel, то через request можно работать с сессией, с данными POST и GET.

    На большинстве сайтов ссылка имеет срок, в течении которого действительна и нынешний заказчик сайта наверняка захочет, чтобы такое было и у него на сайте. А у меня будет как раз готовое решение. В случае, если не захочет, то ссылку без срока активации будет сделать очень просто, удалив пару строчек.
     
  6. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Спасибо. Убрал портянки. Получилось вот так, коротко, не страшно и работает как надо:

    PHP:
    1. public function activate($user_email, $key)
    2.     {
    3.         $user = Activate_users::where([
    4.             ['email', $user_email],
    5.             ['act_key', $key]
    6.         ])->select('email', 'activate', 'act_key', 'send_date')->get();
    7.  
    8.  
    9.         // if act_key exists in database and act_key from database matches key from activation link
    10.         if(isset($user[0]->act_key) && $user[0]->act_key == $key) {
    11.             // send_date format: Y-m-d
    12.             $send_date = explode('-', $user[0]->send_date);
    13.             $send_year = $send_date[0];
    14.             $send_month = $send_date[1];
    15.             $send_day = $send_date[2];
    16.  
    17.             $today_date = explode('-', date('Y-m-d'));
    18.             $today_year = $today_date[0];
    19.             $today_month = $today_date[1];
    20.             $today_day = $today_date[2];
    21.  
    22.  
    23.             //> count how many days passed from the day when we sent to user activation link
    24.             $today_unix_date = mktime(0, 0, 0, $today_month, $today_day, $today_year);
    25.             $send_unix_date = mktime(0, 0, 0, $send_month, $send_day, $send_year);
    26.  
    27.             $diff = $today_unix_date - $send_unix_date;
    28.             $days_have_passed = $diff / 60 / 60 / 24; // seconds/minutes/hours/days
    29.             //<
    30.  
    31.             // if it has passed from 0 to 3 days from the date of sending the message
    32.             if (preg_match('/^[0-3]$/', $days_have_passed)) {
    33.                 // activate user
    34.                 $status = 'success';
    35.             }
    36.             // if it has passed more than 3 days
    37.             else {
    38.                 $status = 'error';
    39.             }
    40.  
    41.             $error = 'Ссылка не действительна. Пройдите регистрацию повторно';
    42.             $success = 'Аккаунт подтвержден';
    43.  
    44.             dump($$status); // show response
    45.  
    46.             /*return view('мой шаблон представления', [
    47.                'status' => $$status
    48.             );*/
    49.         }
    50.     }
     
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Можно ещё короче. Почитайте https://secure.php.net/strtotime и https://secure.php.net/manual/ru/datetime.createfromformat.php
     
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.821
    Симпатии:
    1.333
    Адрес:
    Лень
    один хрен на низкоуровневом кодинге тоже полезно для ума
     
  9. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Сделал в три строки:
    PHP:
    1. // send_date format: Y-m-d
    2.  
    3. //> count how many days passed from the day when we sent to user activation link
    4. $today_unix_date = new DateTime("now");
    5. $send_unix_date = DateTime::createFromFormat('Y-m-d', $user[0]->send_date);
    6. $days_have_passed = $today_unix_date->diff($send_unix_date)->format('%a');
    7. //<
    Ну, или в одну::)
    PHP:
    1. $days_have_passed = (new DateTime("now"))->diff(DateTime::createFromFormat('Y-m-d', $user[0]->send_date))->format('%a');
     
    #9 виталий032, 5 ноя 2017
    Последнее редактирование: 5 ноя 2017
  10. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118