Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Подтверждение номера на DLE
Форумы портала PHP.SU » PHP » Пользовательские функции » Подтверждение номера на DLE

Страниц (1): [1]
 

1. Mordent - 11 Августа, 2014 - 21:31:44 - перейти к сообщению
Всем здрасьте! Радость Скажу сразу, код предоставлен в ознакомительных целях. Умников просьба не умничать. комментарии по факту - приветствуются.
Предыстория... Я долго искал варианты подтверждения телефонного номера клиента под DLE собственноручно, без использования громоздких модулей и sms-шлюзов (не редки случаи, когда начинают "переподтверждать" свой номер, дабы нанести материальный ущерб владельцу сайта). Мне это нужно, чтобы пользователь без подтвержденного номера, не мог оставить заказ на выполнение работ (сами понимаете, сложно созвониться с тем, чего номера нет). Собственно толкового ничего не было, поэтому пришлось калдырить самому. Сразу скажу, для поля с телефонным номером я использовал уже устаревшее поле ICQ. Правку текста "ICQ" на "Телефон" описывать не стану. Скажу лишь, что переменные в БД и шаблоне ({icq}) остались такие же.
Для начала, я подправил шаблон registration.tpl таким образом, чтоб поля
CODE (html):
скопировать код в буфер обмена
  1. <div class="111"><div class="222">Номер Телефона:</div><input type="text" id="icq" name="icq" class="333" value="" /></div>

оказались над закрывающимся тегом

напоминаю, id и name у инпута я специально оставил старыми, чтоб меньше было искать по всем остальным модулям. Однако, не стоит забывать, что юзверь - переменная не постоянная и один и тот же номер может ввести по-разному. А нам нужны только цифры (ровно 11 штук). Поэтому, поискав на просторах необъятной паутины, нашел интересное решение на jQuery от товарища по имени Леонид. Ссылка на решение (Не реклама!)
Плюс, по какому-то кодексу, пользователь должен дать своё согласие на обработку своих данных. Так в шаблоне появился еще и чекбокс (код будет ниже). Однако, Великому господину надо бы сообщить, что будет, если он не захочет подтверждать номер. Таким образом ещё одна конструкция с алертами на JS была пришпилена к шаблону...
Понимаю, заскучали. Скоро конец)
финальный вид части кода моего шаблона:
CODE (html):
скопировать код в буфер обмена
  1. [registration]
  2.     <script src="{THEME}/js/jquery.maskedinput.js" type="text/javascript"></script>
  3.     <script type="text/javascript">
  4. jQuery(function($){
  5.    $("#icq").mask("8 (999) 999-9999");
  6. });
  7. </script>
  8.  
  9. /*часть кода*/
  10.  
  11. <div class="111"><div class="222">Номер Телефона:</div><input type="text" id="icq" name="icq" class="333" value="" /><input type="checkbox" name="confirm" id="confirm" value="1"><span> Я хочу подтвердить номер!</span></div>
  12. <script type="text/javascript">
  13. $(function() {
  14. $( "#confirm" ).on( "click", function() {
  15.             if($(this).is(":checked")) {alert("Администратор свяжется с Вами для подтверждения!"); }
  16.    else {alert("Без подтверждения Вы не сможете оставлять заказы и участвовать в акциях компании!");}
  17. })
  18. });
  19. </script>
  20. <div class="111"><div class="222">Ваш E-Mail:</div><input type="text" name="email" class="333" /></div>
  21.  
  22. /*ещё часть кода*/
  23.  
  24. [/registration]
  25. [validation]


Собственно, с шаблоном всё! можно залить на хостинг и проверить, работает или нет. Теперь нам необходимо знать, отправил ли нам Юзер телефон и хочет ли он его подтвердить...
ищем файл ../engine/modules/register.php
копируем к себе и правим.
находим строчки
PHP:
скопировать код в буфер обмена
  1.         $icq = intval( str_replace("-", "", $_POST['icq'] ) );
  2.         if( $icq < 1 ) $icq = "";

PHP:
скопировать код в буфер обмена
  1. if( strlen( $icq ) > 20 ) $stop .= $lang['reg_err_17'];

коментим или удаляем. поясняю: в том месте где они сейчас стоят толку от них не будет, да и проверка на 20 символов (такое поле у таблицы в БД) тоже не к чему, когда используем модифицированный инпут.
также ищем
PHP:
скопировать код в буфер обмена
  1. $db->query( "UPDATE " . USERPREFIX . "_users SET fullname='$fullname', info='$info', land='$land', icq='$icq', xfields='$filecontents' WHERE user_id='{$row['user_id']}'" );

и удаляем из запроса любое упоминание об icq
итог:
PHP:
скопировать код в буфер обмена
  1. $db->query( "UPDATE " . USERPREFIX . "_users SET fullname='$fullname', info='$info', land='$land', xfields='$filecontents' WHERE user_id='{$row['user_id']}'" );

отформатировали? замечательно.
скроллим этот же файл в самый верх, находим все функции check_reg (3) и в скобки, после $email, дописываем $icq. Зачем? чтобы задать проверку на повторение номера.
теперь ищем строчку
PHP:
скопировать код в буфер обмена
  1. return $stop;
и над ней добавляем код
PHP:
скопировать код в буфер обмена
  1. if ( $stop == "" ) {
  2. $row = $db->super_query( "SELECT COUNT(*) as count FROM " . USERPREFIX . "_users WHERE icq = '$icq'" );
  3. if( $row['count'] ) $stop .= $lang['reg_err_icq2']; }
далее ищем
PHP:
скопировать код в буфер обмена
  1. $password2 = $_POST['password2'];
ниже вставляем
PHP:
скопировать код в буфер обмена
  1. $icq = $_POST['icq'];
  2. if ( $icq != "" ) {
  3. $searchNum = array(" ", "-", "(", ")");
  4. $icq = intval( str_replace( $searchNum, "", $icq ) );
  5. $QuestConfirm = intval( $_POST['confirm'] );
  6. } else {
  7. $icq = "";
  8. $QuestConfirm = 0;
  9. }

пояснялка, по строчка:
1. Получаем значение поля из формы
2. Поверяем, не пустое ли
3. если нет, формируем массив выборки цифр (если помним, в форме есть скобки, пробелы и дефисы)
4. Делаем выборку
5. Получаем значение чекбокса (хочет ли пользователь подтвердить номер - планирую использовать познее)
6. если всё-таки пустое
7. задаем пустое поле для номера телефона
8. задаем нулевое значение (использую позднее)

теперь ищем запрос
PHP:
скопировать код в буфер обмена
  1. $db->query( "INSERT INTO " . USERPREFIX . "_users (name, password, email, reg_date, lastdate, user_group, info, signature, favorites, xfields, logged_ip) VALUES ('$name', '$regpassword', '$email', '$add_time', '$add_time', '" . $config['reg_group'] . "', '', '', '', '', '" . $_IP . "')" );

дописываем туда полученные значения. получается так:
PHP:
скопировать код в буфер обмена
  1. $db->query( "INSERT INTO " . USERPREFIX . "_users (name, password, email, icq, questconfirm, reg_date, lastdate, user_group, info, signature, favorites, xfields, logged_ip) VALUES ('$name', '$regpassword', '$email', '$icq', '$QuestConfirm', '$add_time', '$add_time', '" . $config['reg_group'] . "', '', '', '', '', '" . $_IP . "')" );

теперь в файле ../language/Russian/website.lng ищем reg_err_1 и ниже пишем
PHP:
скопировать код в буфер обмена
  1. 'reg_err_icq2'  =>      "<li>Пользователь с таким номером телефона уже зарегистрирован!</li>",


осталось сделать 2 запроса к базе данных:
CODE (SQL):
скопировать код в буфер обмена
  1. ALTER TABLE `dle_users` ADD `questconfirm` INT( 1 ) NOT NULL DEFAULT '0';
  2. ALTER TABLE `dle_users` ADD `confirm_num` INT( 1 ) NOT NULL DEFAULT '0';

второй запрос нужен для последующих манипуляций, которые описаны будут позднее, ибо время уже позднее...
2. Ts.Saltan - 11 Августа, 2014 - 23:41:57 - перейти к сообщению
Когда мне понадобилось подтверждать номера телефонов, искал сайты с бесплатной отправкой смс и писал к ним парсер, находились даже без капчи. Минусы в том, что доходили смс одна из 5-10.
Но потом пришлось переделать. Большинство операторов предлагают услугу смс с сайта. В таком случае смс точно доходит, но есть и свои камни: ограничение на ip (прокси), у абонента должна быть подключена эта услуга (чаще бесплатно), капча. Вот с капчей пришлось повозиться, только один оператор хранил код зашифрованным в get параметре, под остальные пришлось либо писать распознаватели (долго, нудно, громоздко, кпд около 60%), либо прогонять через сервисы распознавания (быстро, кпд под 95, но платно - 1$/1000картинок)
3. Mordent - 13 Августа, 2014 - 17:57:19 - перейти к сообщению
Сорри за задержку в обновлении. вчера работал.
для начала, небольшой апдейт по первой части:
код
PHP:
скопировать код в буфер обмена
  1.     $icq = $_POST['icq'];
  2.     if ( $icq != "" ) {
  3.     $searchNum = array(" ", "-", "(", ")");
  4.     $icq = intval( str_replace( $searchNum, "", $icq ) );
  5.     $QuestConfirm = intval( $_POST['confirm'] );
  6.     } else {
  7.     $icq = "";
  8.     $QuestConfirm = 0;
  9.     }
правим так:
PHP:
скопировать код в буфер обмена
  1. $icq = $_POST['icq'];
  2. $rand_ome = mt_rand(1, 9999);
  3. if ( $icq != "" ) {
  4. $searchNum = array(" ", "-", "(", ")");
  5. $icq = intval( str_replace( $searchNum, "", $icq ) );
  6. $QuestConfirm = intval( $_POST['confirm'] );
  7. } else {
  8. $icq = "";
  9. $QuestConfirm = 0;
  10. }
добавили переменную $rand_ome, чтобы можно было проверить пользователя при подтверждении.
и к запросам:
CODE (SQL):
скопировать код в буфер обмена
  1. ALTER TABLE `dle_users` ADD `questconfirm` INT( 1 ) NOT NULL DEFAULT '0';
  2. ALTER TABLE `dle_users` ADD `confirm_num` INT( 1 ) NOT NULL DEFAULT '0';
Добавляем ещё 1. Получается так:
CODE (SQL):
скопировать код в буфер обмена
  1. ALTER TABLE `dle_users` ADD `questconfirm` INT( 1 ) NOT NULL DEFAULT '0';
  2. ALTER TABLE `dle_users` ADD `confirm_num` INT( 1 ) NOT NULL DEFAULT '0';    
  3. ALTER TABLE `dle_users` ADD `randconfirm` INT( 4 ) NOT NULL DEFAULT '0';
ну или можно все 3 объединить в 1. кому как удобнее.
Едем дальше!
сейчас поясняю, зачем мне нужна была переменная $QuestConfirm и $rand_ome.
Как я и писал ранее, подтверждать номер я хочу с минимумом затрат, однако сидеть и смотреть зарегился кто на сайте и хочет ли он подтвердить свой телефон целый день желания нет. поэтому, при наилучшем варианте (Юзверь ввел телефон и нажал галочку "Хочу подтвердить"), нам будет падать на e-mail сообщение.
итак. мы помним, как добавляли в запрос к базе номер телефона (icq) и questconfirm
ниже должна быть строчка
PHP:
скопировать код в буфер обмена
  1. $id = $db->insert_id();
после нее дописываем код отправки e-mail:
PHP:
скопировать код в буфер обмена
  1. if ($QuestConfirm == 1) {
  2. include_once ENGINE_DIR . '/classes/mail.class.php';
  3. $path = $config['http_home_url'];
  4. $subject = "Подтверждение номера";
  5. $toMail = "Здесь адрес, куда слать";
  6. $message .= "Пользователь: " . $name . "<br />С ID: " . $id . "<br />Хочет подтвердить свой номер: " . $icq . "<br />Код подтверждения: " . $rand_ome . "<br />C Уважением, Робот сайта RooM208.Ru"  ;
  7. $mail = new dle_mail( $config, true );
  8. $mail->from = $config['admin_mail'];
  9. $mail->send( $toMail, $subject, $message );
  10. }
теперь понятно, зачем нужна была лишняя переменная? e-mail будет отправляться только при выполнении 2х условий: номер не пустой и стоит галочка. при других вариантах: номер пуст, но галочку пользователь зачем-то поставил, или номер пуст и нет галочки, или номер есть, но нет галочки - смотрим выше: либо $QuestConfirm скрипт принудительно присвоит 0, либо "возьмет" 0 из формы.

Собственно на этом работа с модулем регистрации закончена.
Повторюсь, переделка ведется для DLE 10.0. за работоспособность младших версий не отвечаю, как и за адекватную работу в других системах!

Почитали, испугались... не закрыли?
кулибничаем дальше)
вот пользователь ввел свой номер, захотел его подтвердить, нам на почту упало сообщение. всё чудесно. но как админу подтвердить номер?
ищем в папке ./engine/inc. файл editusers.php. перекачиваем для правки
ищем в нем строчку
PHP:
скопировать код в буфер обмена
  1. $row['descr'] = $parse->decodeBBCodes( $row['descr'], false );
и после строчки
PHP:
скопировать код в буфер обмена
  1. $skin = trim( totranslit($_REQUEST['skin'], false, false) );
(их 2, поэтому ориентируемся на верхнюю) дописываем код подтверждения (Тот что будет ввиде формы в окне редактирования пользователей из админки):
PHP:
скопировать код в буфер обмена
  1. if ($row['questconfirm'] == 0) {
  2. $confHTML = "<input size=\"20\" value=\"{$row['icq']}\" class=\"edit bk\" disabled=\"disable\" ><div> Пользователь не хочет подтверждать номер!</div";
  3. } else {
  4. if ($row['confirm_num'] == 1) {
  5. $confHTML = "<input size=\"20\" value=\"{$row['icq']}\" class=\"edit bk\" disabled=\"disable\" ><div> Телефон уже подтвержден!</div";
  6. } else {
  7. $confHTML = "<input size=\"20\" name=\"editicq\" value=\"{$row['icq']}\" class=\"edit bk\" ><br><input type=\"radio\" name=\"confirm_numbers\" value=\"1\" /><span>Телефон подтвержден.</span><br><input type=\"radio\" name=\"confirm_numbers\" value=\"0\" /><span>Телефон не подтвержден.</span>";
  8.         }
  9. }
  10. $editNumHTML = "<input type=\"checkbox\" name=\"editNum\" value=\"1\"><span> Пользователь хочет изменить номер!</span>" ;

как обыно, поснялка:
1-2. если пользователь не отправлял запрос, мы и подтверждать ничего не будем.
3. если отправлял, то проверяем, не был ли уже номер подтвержден
4-5. если да - выводим в форму инфу о ненадобности подтверждать
6-7. нет - выводится номер телефона (с возможностью правки) и 2 радио-кнопки: подтвердил юзер или нет
следует понимать, что после подтверждения номер редактировать уже нельзя. поэтому
10. добавляем чекбокс с подписью что пользователь хочет сменить номер (после сохранения номер телефона будет сброшен и станет доступен для регистрации).
это - форма. теперь нам надо её вывести.
ищем
CODE (html):
скопировать код в буфер обмена
  1. <td colspan="2"><input size="20" name="editicq" value="{$row['icq']}" class="edit bk"></td>

заменяем на
CODE (html):
скопировать код в буфер обмена
  1.    <td colspan="2">{$confHTML}</td>
  2. </tr>
  3. <tr>
  4.    <td style="padding:4px;">Изменить номер?</td>
  5.    <td colspan="2">{$editNumHTML}</td>
  6. </tr>

на экран вывели. теперь осталось получить данные об изменениях, если они были
ищем строку
PHP:
скопировать код в буфер обмена
  1. if ( $_POST['banned'] ) $banned = "yes";
НАД ней пишем
PHP:
скопировать код в буфер обмена
  1. if ($_POST['editicq']) {
  2.         $editicq = intval( $_POST['editicq'] );
  3.         switch( $_POST['confirm_numbers'] )     {
  4.                 case '0':
  5.                         $confNum = 0;
  6.                         break;
  7.                 case '1':
  8.                         $confNum = 1;
  9.                         //$editlevel = 3;
  10.                         break;
  11.         }
  12.         $db->query( "UPDATE " . USERPREFIX . "_users set icq='$editicq', confirm_num='$confNum' WHERE user_id='$id'" );
  13. }
  14. $editNum = intval( $_POST['editNum'] );
  15. if ($editNum == 1) $db->query( "UPDATE " . USERPREFIX . "_users set icq='', confirm_num='0',  questconfirm='1' WHERE user_id='$id'" );
  16.  
Стандартненько:
1. Проверка, пришло ли что-нибудь из формы с именем editicq (немного выше, мы сделали так, что name="editicq" было только в момент подтверждения номера. таким образом мы облегчили скрипт от постоянной проверки и перезаписи БД). если да, то
2. "оцифровываем" номер из поля инпут
3. ищем, где стоит радиокнопка
13. обновляем данные в БД
15-16. проверка флажка о том что пользователь хочет ИЗМЕНИТЬ номер. если стоит флажок, обновляем значения в БД для редактирования
закоменченная $editlevel это уже длань моей фантазии. перед переделкой скриптов, я переназвал 3 и 4 группы на "Клиенты (номер подтвержден)" и "Клиенты (номер не подтвержден)" соответственно. таким образом, при подтверждении номера, автоматически повышается группа (соответственно становятся доступны новые плюшки).
на этом правка этого модуля закончена.
но не закончен мой анализ действий пользователя. Пример: Гость зарегился на сайте, но номер указывать не стал, или указал, но не захотел подтверждать. как ему это сделать позднее? только из своего профиля. поэтому, ищем файл ./engine/modules/profile.php
для начала закрываем доступ к профилям других пользователей, кроме своего, если ты не админ (мы же не хотим, чтоб какой-нибудь спамер на нашем сайте сколотил себе телефонную базу Радость )
ищем строчку
PHP:
скопировать код в буфер обмена
  1. $user_found = TRUE;
ниже вставляем
PHP:
скопировать код в буфер обмена
  1. if ( $member_id['name'] != $user AND $member_id['user_group'] != 1 ) {
  2. msgbox("Доступ закрыт","К страничке профиля имеет доступ только ее владелец.");
  3. } else {
теперь ищем
PHP:
скопировать код в буфер обмена
  1. $db->free( $sql_result );
и ниже добавляем
PHP:
скопировать код в буфер обмена
  1. }
теперь ищем строчку
PHP:
скопировать код в буфер обмена
  1. if( $_POST['allow_mail'] ) $allow_mail = 0; else $allow_mail = 1;
и ниже добавляем код опроса формы
PHP:
скопировать код в буфер обмена
  1. $numconf = $row['questconfirm'];
  2. if( $_POST['numconf'] ) {
  3.         $numconf = 1;
  4.         $nameE = $row['name'];
  5.         $icqE = $row['icq'];
  6.         $randomE = $row['randconfirm'];
  7. }
строчки
PHP:
скопировать код в буфер обмена
  1. $icq = intval( str_replace("-", "", $_POST['icq'] ) );
  2. if( ! $icq ) $icq = "";
нужно закоментить или удалить
теперь ищем по началу строки
PHP:
скопировать код в буфер обмена
  1. $sql_user = "UPDATE " . USERPREFIX
всего 2 запроса (они рядом). из них удаляем icq='$icq' и добавляем questconfirm='$numconf'. получается так:
PHP:
скопировать код в буфер обмена
  1. if( strlen( $password1 ) > 0 ) {
  2.         $password1 = md5( md5( $password1 ) );
  3.         $sql_user = "UPDATE " . USERPREFIX . "_users SET fullname='$fullname', land='$land', {$mailchange} info='$info', signature='$signature', password='$password1', allow_mail='$allow_mail', questconfirm='$numconf', xfields='$filecontents', allowed_ip='$allowed_ip' WHERE user_id = '{$id}'";
  4.         } else {
  5.         $sql_user = "UPDATE " . USERPREFIX . "_users SET fullname='$fullname', land='$land', {$mailchange} info='$info', signature='$signature', allow_mail='$allow_mail', questconfirm='$numconf', xfields='$filecontents', allowed_ip='$allowed_ip' WHERE user_id = '{$id}'";
  6.         }
код привел полностью, чтоб было удобнее.
теперь после
PHP:
скопировать код в буфер обмена
  1. $db->query( $sql_user );
дописываем немного изменненый отправщик e-mail
PHP:
скопировать код в буфер обмена
  1. if ($numconf == 1) {
  2.         include_once ENGINE_DIR . '/classes/mail.class.php';
  3.         $path = $config['http_home_url'];
  4.         $subject = "Подтверждение номера";
  5.         $toMail = "Ваш адрес";
  6.         $message .= "Пользователь: " . $nameE . "<br />С ID: " . $id . "<br />Хочет подтвердить свой номер: " . $icqE . "<br />Код подтверждения: " . $randomE . "<br />C Уважением, Робот сайта RooM208.Ru"  ;
  7.         $mail = new dle_mail( $config, true );
  8.         $mail->from = $config['admin_mail'];
  9.         $mail->send( $toMail, $subject, $message );
  10. }
теперь ищем
PHP:
скопировать код в буфер обмена
  1. $tpl->set( '{pm}', $lang['news_pmnew'] );
ниже дописываем
PHP:
скопировать код в буфер обмена
  1. $numHTML = "";
  2. $numHTMLb = "";
  3. if ( $row['icq'] != "" ) {
  4.         if ( $row['confirm_num'] == 1) {
  5.                 $numHTML = "<div>Номер подтвержден!<br><span style=\"color:#F8070B\">Изменить номер можно только через <a href=\"$PHP_SELF?do=pm&doaction=newpm&user=1\">Заявку Администратору</a></span></div>";
  6.         } else {
  7.                 if ( $row['questconfirm'] == 1 ) {
  8.                         $numHTML = "<div>Запрос на подтверждение отправлен! Ваш Код Подтверждения: <span style=\"color:#F8070B\">" . $row['randconfirm'] . "</span></div>";
  9.                 } else {
  10.                         $numHTML = "<div>Чтобы подтвердить номер:<br>- Нажмите <span style=\"color:#F8070B\">\"Редактировать профиль\"</span><br>- Установите галочку перед <span style=\"color:#F8070B\">\"Хочу подтвердить номер\"</span><br>- Нажмите <span style=\"color:#F8070B\">\"Отправить\"</span></div>";
  11.                         $numHTMLb = "<input type=\"checkbox\" name=\"numconf\" value=\"1\" />Хочу подтвердить номер!";
  12.                 }
  13.         }
  14. } else {
  15.         $numHTML = "<div style=\"color:#F8070B\">Чтобы добавить номер, напишите <a href=\"$PHP_SELF?do=pm&doaction=newpm&user=1\">Заявку Администратору</a></div>";
  16. }
  17. $tpl->set( '{numhtmlb}', $numHTMLb );
  18. $tpl->set( '{numhtml}', $numHTML );
открываем файл шаблона userinfo.tpl. Меняем ICQ на Телефон, ниже добавляем<li>{numhtml}</li>.
находим поле для редактирования icq (input name=icq) и закрываем его (в диве, где объявляется инпут, дописать disabled="disable") а рядом вставляем {numhtmlb}.
все. мы настроили регистрацию, подтверждение и вывод различной информации о номере телефона пользователя.
краткое пояснение по последним действиям:
мы настроили вывод разного рода информационных сообщений исходя из различных условий (есть телефон - нет подтверждения - нет запроса; есть телефон - нет подтверждения - есть запрос; есть телефон - есть подтверждение; нет телефона).
вот, собственно и всё.
может кому понадобится.
всем Бобра!

 

Powered by ExBB FM 1.0 RC1