Содержание


Реальные веб-проекты на PHP и MySQL. Разработка почтовой службы с веб-интерфейсом

Часть 4. Создание пользователей системы и управление их учетными записями

Comments

Серия контента:

Этот контент является частью # из серии # статей: Реальные веб-проекты на PHP и MySQL. Разработка почтовой службы с веб-интерфейсом

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Реальные веб-проекты на PHP и MySQL. Разработка почтовой службы с веб-интерфейсом

Следите за выходом новых статей этой серии.

1. Введение

В предыдущих статьях многократно описывались вопросы настройки и запуска в эксплуатацию самых разнообразных почтовых служб, - таких как sendmail, postfix, exim, Communigate, qmail, использующих в качестве платформы самый широкий спектр современных Linux- и BSD-систем. В настоящее время, по мере развития Всемирной Паутины все чаще возникает вопрос об актуальности использования услуг электронной почты, основанной на веб.

В предыдущих частях цикла статей были рассмотрены вопросы построения почтовой системы с веб-интерфейсом, создания базы данных под учебный проект и обзора общей библиотеки функций для решения задач обработки почты. Кроме того, мы разобрали главный управляющий сценарий, а также реализацию входа и выхода пользователей системы. В четвертой статье будут рассмотрены вопросы реализации механизмов создания пользователей системы и манипулирования их учетными записями.

Перед началом работы в системе пользователь должен настроить одну или несколько учетных записей электронной почты. После того, как будет осуществлено нажатие на кнопку Account Setup (начало настройки учетной записи) переменная action управляющего сценария получает значение account-setup и при этом происходит повторный вызов главного управляющего сценария index.php. В браузере это выглядит следующим образом: рис. 1.

Рисунок 1.
Рисунок 1.
Рисунок 1.

Работа главного сценария на этапе настройки учетных записей

На этом этапе работы сценария переменная action определяет другое поведение работы сценария. Заголовок создается с отличиями от остальных режимов, но основные изменения при этом находятся в теле самой страницы. В этом случае вызывается функция display_account_setup($auth_user), код которой приводится ниже по тексту:

function display_account_setup($auth_user)
{
  // Выводит форму для определения новой учетной записи
  
  display_account_form($auth_user);
  $list = get_accounts($auth_user);
  $accounts = sizeof($list);
  
  // Отобразить все сохраненные учетные записи  
  foreach($list as $key => $account)
  {
    // Для каждой учетной записи вывести форму для представления 
    // детальной информации.
    // Обратите внимание, что мы отправляем пароли всех учетных записей
    // в виде простого HTML-кода. Это не самая лучшая идея.
    display_account_form($auth_user, $account['accountid'], $account['server'], 
                         $account['remoteuser'], $account['remotepassword'], 
                         $account['type'], $account['port']);
  }  
}

При вызове функция выводит пустую форму для добавления новой учетной записи, ниже которой следуют редактируемые формы, содержащие данные всех имеющих место учетных записей данного пользователя в системе. Именно функция display_account_form() выводит форму, которая показана на рис.1. Функция используется двумя способами: если ее вызвать без передачи параметров, то отобразится пустая форма, а при вызове с полным набором параметров отображается существующая учетная запись. Код функции приведен ниже по тексту:

function display_account_form($auth_user, $accountid=0, $server='', 
                              $remoteuser='', $remotepassword='', 
                              $type='IMAP', $port=143)
{
// Портом POP3 по умолчанию является 110, портом IMAP по умолчанию -- 143

// Выводит одну форму для параметров учетной записи

  if($server)
    $title = $server;
  else
    $title = 'Новая учетная запись';
?>
  <center>
  <form method=post action="index.php?action=store-settings">
  <table bgcolor='#cccccc' cellpadding = 6 cellspacing = 0 border =0>
   <tr>
     <th colspan = 2 bgcolor = '#ff6600'>
        <?php echo $title;?> 
     </th>
   </tr>
   <tr>
     <td>Имя сервера:</td>
     <td><input type = "text" name = "server" maxlength = 100 value = 
	 '<?php echo $server;?>'></td>
   </tr>
   <tr>
     <td>Номер порта:</td>
     <td><input type = "text" name = "port" maxlength = 5 value = 
	 '<?php echo $port; ?>'></td>
   </tr>
   <tr>
     <td>Тип сервера:</td>
     <?php
       echo '<td><select name = "type"><option'; 
       if ($type == IMAP) 
          echo ' selected';
       echo '>IMAP<option';
       if ($type == POP3) 
          echo ' selected';
       echo '>POP3</select></td>';
     ?>
   </tr>
   <tr>
     <td>Имя пользователя:</td>
     <td><input type="text" name="remoteuser" value = '<?php echo 
	 $remoteuser; ?>'></td>
   </tr>
   <tr>
     <td>Пароль:</td>
     <td><input type="password" name="remotepassword" value = 
	 '<?php echo $remotepassword; ?>'></td>
   </tr>
   <input type = "hidden" name="account" value = <?php echo $accountid; ?>>
   <tr>
   <?php if($accountid>0) 
      {
        echo '<td align=center>';
        display_form_button('save-changes'); 
        echo '</td>';
        echo '</form>';
        echo '<form action = "index.php?action=delete-account" method = "post">';
        echo "<input type = \"hidden\" name=\"account\" value = $accountid >";
        echo '<td align=center>';
        display_form_button('delete-account'); 
        echo '</td>';
        echo '</form>';
        echo '</tr>';
      }
      else
      {
        echo '<td colspan=2 align="center">';
        display_form_button('save-changes'); 
        echo '</td></form>';
      }
   ?>
   </tr> 
 </table>
 </center>
 <br />
<?php
}

Для извлечения существующих учетных записей применяется функция function get_accounts($auth_user), код которой приводится ниже :

function get_accounts($auth_user)
{
  $list = array();
  if($conn=db_connect())
  {
    $query = "select * from accounts where username = '$auth_user'";
    $result = $conn->query($query);
    if($result)
    {
      while($settings = $result->fetch_assoc())
        array_push($list, $settings);
    }
    else
      return false;
  }
  return $list;
}

Эта функция подключается к базе данных, из которой извлекает все учетные записи, существующие для определенного пользователя, и возвращает их в сценарий в виде массива.

Создание новой учетной записи

При заполнении пользователем формы для учетной записи и выполнения сохранения введенных изменений (путем нажатия кнопки Save Changes) активизируется действие события store-settings.

Функция store_account_settings($auth_user, $settings) сохраняет введенные данные для новой учетной записи в базе данных. Ее код приведен ниже по тексту:

function store_account_settings($auth_user, $settings)
{
  if(!filled_out($settings))
  {
    echo 'Все поля должны быть заполнены.  Повторите попытку.<br /><br />';
    return false;
  }
  else
  {
    if($settings['account']>0)
      $query = "update accounts  set server = '$settings[server]',
                  port = $settings[port], type = '$settings[type]',
                  remoteuser = '$settings[remoteuser]', 
                  remotepassword = '$settings[remotepassword]' 
                where accountid = $settings[account] 
                  and username = '$auth_user'";
    else
      $query = "insert into accounts values ('$auth_user', 
                     '$settings[server]', $settings[port], 
                     '$settings[type]', '$settings[remoteuser]', 
                     '$settings[remotepassword]', NULL)";
    if($conn->db_connect())
    {
      $result = $conn->query($query);
      if ($query)
        return true;
      else
        return false;
    }
    else
    {
      echo 'Невозможно сохранить изменения.<br /><br /><br /><br /><br /><br />';
      return false;
    }
  }
}

Основная работа этой функции заключается в реализации двух опций – ввод новой учетной записи и обновление уже существующей. Она выполняет сохранение данных новой учетной записи и осуществляет возврат к этапу вывода участка основной страницы в главном сценарии index.php. Затем также выполняется функция display_account_setup($auth_user) для вывода списка данных по учетной записи пользователя.

Изменение существующей учетной записи

Удаление учетной записи:

Удаление учетной записи пользователя активируется при нажатии на кнопку Delete Account, при этом активируется событие delete-account и вызывается функция delete_account($auth_user, $accountid):

function delete_account($auth_user, $accountid)
{
  // Удаляет одну учетную запись данного пользователя из базы данных

  $query = "delete from accounts where accountid='$accountid' and username = 
  '$auth_user'";
  if($conn=db_connect())
  {
    $result = $conn->query($query);
  }
  return $result;
}

Удаление учетных записей необходимо выполнять до обработки заголовка, так как именно внутри него предоставлен выбор учетной записи для использования. Этот список должен быть обновлен для корректного использования.

После того, как эта функция закончит свою работу происходит возврат к сценарию index.php, а именно у его разделу, связанному с формированием тела страницы.

Выбор учетной записи пользователя

После настройки пользователем своих учетных записей появляется возможность подключения к серверу с использованием этих учетных записей и начала работы с почтовыми сообщениями. Для чтения почты должна быть активирована учетная запись путем ее выбора из числа имеющихся. Текущий выбор сохраняется в переменной сеанса $selected_account. При этом, если пользователь зарегистрировал в системе единственную учетную запись, то она будет автоматически выбрана при входе в систему. Функция number_of_accounts($auth_user) служит как раз для выявления случаев связи с одним пользователем нескольких учетных записей. Код этой функции представлен ниже по тексту:

function number_of_accounts($auth_user)
{
  // Получает количество учетных записей, которые относятся к данному 
  // пользователю
  
  $query = "select count(*) from accounts where username = '$auth_user'";

  if($conn=db_connect())
  {
    $result = $conn->query($query);
      if($result)
      {
        $row = $result->fetch_array();
        return $row[0];
      }
  }
  return 0;
}

Функция get_account_list($auth_user) извлекает только имена учетных записей. Если пользователь зарегистрировал несколько учетных записей, то потребуется использовать только одну из них для начала работы. В этом случае заголовки будут содержать список <select> с перечислением других доступных учетных записей. При выборе любой их них будет автоматически отображен почтовый ящик с его содержимым. Код функции приведен ниже по тексту:

function get_account_list($auth_user)
{
  // Получает массив идентификаторов учетных записей, которые относятся к 
  // данному пользователю

  $query = "select accountid from accounts where username = '$auth_user'";
  $list = array();
  
  if($conn=db_connect())
  {
    $result = $conn->query($query);
    $num = $result->num_rows;
    for($i = 0; $i<$num; $i++)
    {
      $row = $result->fetch_array();
      array_push($list, $row[0]);
    }
  }
  return $list;
}

Эта опция <select> генерируется в рамках функции do_html_header($auth_user, $title = '', $selected_account). Код функции do_html_header… приводится ниже по тексту:

function do_html_header($auth_user, $title = '', $selected_account)
{
  // Выводит HTML-заголовок, включая крутой логотип :)

  global $table_width;

  // Выводит область заголовка 
?>
  <html>
  <head>
    <title><?php echo $title; ?></title>
    <style>
      h1 { font-family: 'Comic Sans MS',  sans-serif; font-size: 32; 
           font-weight: bold; color:  black; margin-bottom: 0}
      b { font-family: 'Arial', sans-serif; font-size: 13; 
          font-weight: bold; color: black }
      th { font-family: 'Comic Sans MS',  sans-serif; font-size: 18
           font-weight: bold; color:  black; }
      body, li, td { font-family: Arial, Helvetica, sans-serif; 
                     font-size: 12; margin = 5px }
      a { color: #000000 }
    </style>
  </head>
  <body>
  <table width = <?php echo $table_width; ?> cellspacing = 0 
  cellpadding = 3 bgcolor = "#ff6600" border = 0>
  <tr bgcolor = "#ff6600">
  <td bgcolor = "#ff6600" width = 103><img src = "images/warm-mail.gif" 
                 width = 103 height = 45 alt ="" valign = "middle" /></td>
  <td bgcolor = "#ff6600" width = <?php echo ($table_width-110);?>><h1>
  <?php echo $title;?></h1></td>
  <?php
  // Включать кнопку выбора учетной записи, только если пользователь имеет их несколько
  if(number_of_accounts($auth_user)>1)
  {
    echo '<form target="index.php?action=open-mailbox" method="post">';
    echo '<td bgcolor = "#ff6600" align = "right" valign = "middle">';
    display_account_select($auth_user, $selected_account);
    echo '</td>';
    echo '</form>';
  }
  ?>
  </tr>
  </table>
  <table width = <?php echo $table_width;?> cellpadding = 0 cellspacing = 0 border = 0>
  <tr><td>
<?php
}

В зависимости от учетных записей текущего пользователя функция display_account_select генерирует HTML код, выводящий сам элемент <select>. Код функции приведен ниже по тексту:

function display_account_select($auth_user, $selected_account)
{
  // Выводит выпадающий список для выбора пользователем учетной записи
  
  $list = get_account_list($auth_user);
  $accounts = sizeof($list);

  if($accounts>1)
  {
    echo'<select onchange=window.location=this.options[selectedIndex].value 
	name=account>';
    if($selected_account=='')
    echo '<option value = 0 selected>Выберите учетную запись</a>';
    for($i = 0; $i<$accounts; $i++)
    {
      $account = get_account_settings($auth_user, $list[$i]);
      echo "<option value = 'index.php?action=select-account&account=".$list[$i]."'";
      if($list[$i]==$selected_account)
        echo ' selected';
      echo '>'.$account['server'].'</option>';
    }
    echo '</select>';
  }
}

Функция display_account_select($auth_user, $selected_account) извлекает и отображает список доступных учетных записей. Кроме этого, она вызывает при необходимости рассмотренную ранее функцию get_account_list($auth_user). В результате выбора одной из опций списка <select> активизируется событие select_account.

Выводы

В четвертой статье цикла, подробно рассмотрены вопросы общей структуры создаваемой почтовой системы с веб-интерфейсом и порядка ее функционирования. Приведены и описаны фрагменты кода главного управляющего сценария системы электронной почты с веб-интерфейсом, отвечающие за организацию входа и выхода из системы. Рассмотрены функции вывода HTML-формы для добавления новых учетных записей пользователей, заголовка страницы, выводимой при настройке учетной записи, функции, отвечающие за извлечение имеющихся учетных записей из базы данных проекта, создания новой учетной записи пользователя, выбора из числа имеющихся и их изменения.

Обзорно рассмотрен логический порядок работы частей сценария, показано для чего и как они функционируют, что является источником инициализации тех или иных событий в работе. Приведены снимки экрана, поясняющие работу сценариев и отдельных участков кода.

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


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=587407
ArticleTitle=Реальные веб-проекты на PHP и MySQL. Разработка почтовой службы с веб-интерфейсом: Часть 4. Создание пользователей системы и управление их учетными записями
publish-date=11162010