Skripta za pošiljanje e-pošte

Z razmahom botov, ki pošiljajo neželeno pošto ter uporabnikov telefonov in tablic, ki nimajo nameščenih odjemalcev za pošiljanje e-pošte, je postalo objavljanje e-poštnega naslova na spletišču nesmiselno. V ta namen marsikdo poseže po katerem izmed spletnih obrazcev za pošiljanje e-pošte, ki zahtevajo, da ima obiskovalec nameščen le brskalnik, ki podpira obrazce. Za uporabo te skripte potrebujete PHP 5.2 ali novejši in dostop do funkcije mail().

Prejem

Izvorno kodo razreda za pošiljanje e-pošto lahko prejmete s klikom na prejem. Morebitne napake in predloge za izboljšave pa mi sporočite preko knjige gostov ali mojega obrazca za stik.

Vključitev kode na vašo stran

Vso kodo sem spisal v obliki razreda ePosta, ki ga v vašo stran vključite preko ukaza include ali require. Nato morate razred začeti (in mu izbirno podati parametre) ter ga na koncu tudi izpisati s pomočjo ukaza echo.

<?php
include('ePosta.class.php'); 
$ePosta = new ePosta();
 
// koda za preverjanje stanja obrazca
 
// koda za pošiljanje
 
echo $ePosta;
?>

V stavku if preverjamo ali je bil obrazec sploh poslan preko metode POST in če so bila vsa polja nastavljena. V primeru, da vse to drži, preko veriženja metod podamo zadevo, besedilo in pošiljatelja. Ker lahko nek obrazec glede na njegovo mesto na strani pošiljate na različne naslove, lahko v naslednji vrstici nastavite e-pošto prejemnika. Zaradi preprečevanja zlorab, morate znotraj razreda ePosta nastaviti dovoljeni seznam prejemnikov (več o tem kasneje).

if (isset($_POST['poslji']) && isset($_POST['zadeva']) && isset($_POST['besedilo']) && isset($_POST['posiljatelj'])) {
  // skripta je bila izvedena
  $ePosta->zadeva($_POST['zadeva'])->besedilo($_POST['besedilo'])->posiljatelj($_POST['posiljatelj']);
  $ePosta->prejemnik('example@example.com'); // zamenjajte z naslovom prejemnika
}

Sedaj je na vas samo še, da izvedete metodo poslji, ki poskuša poslati e-pošto in vrne false, če ji to ne uspe. Glede na stanje pošiljanja se tudi prikaže določeno besedilo. V kodo sem vključil tudi CSS slog .napaka, ki napačno izpolnjena polja označi z rdečo obrobo, ampak le, če je bil obrazec poslan in je prišlo do napake. Priporočam, da ta slog vključite v vašo glavno datoteko CSS in ne neposredno med kodo.

  if ($ePosta->poslji()) {
    // sporočilo je bilo uspešno poslano
    echo '<p>Zahvaljujemo se vam za vaš vnos!</p>' . "\n";
  } else {
    echo '<p>Niste pravilno izpolnili vseh polj!</p>' . "\n";
    echo '<style>.napaka {border: 1px solid red;}</style>' . "\n";
  }

Pregled razreda ePosta

Na začetku razreda imamo nastavljeno vidnost nekaterih spremenljivk. Te se naj ne bi nastavljale kar tako (to naj bi opravljale metode) ali pa sploh ne. Spremenljivko from morate nastaviti tako, da domena v nastavljenem naslovu ujema z domeno od koder se e-pošta pošilja. To prepreči prikaz opozorila »To sporočilo morda ni bilo poslano z naslova ...«. Nastavljeno je tudi najmanjše število znakov zadeve in besedila, ki ga po potrebi spremenite.

<?php
class ePosta 
{
  // te spremenljivke se ne nastavljajo neposredno
  private $besedilo;
  private $zadeva;
  private $from = 'info@example.com'; // domena v tej nastavitvi naj ustreza domeni od koder se e-pošta pošilja.
  private $posiljatelj;
  private $prejemnik;
  private $veljavni_prejemniki;
  private $min_dolzina_zadeve = 5; // najmanjše število znakov zadeve
  private $min_dolzina_besedila = 10;  // najmanjše število znakov besedila
 
  // izgrajevalnik
 
  // metode za nastavljanje
 
  // metoda poslji()
 
  // izpis obrazca
}
?>

Izgrajevalnik sprejme polje s parametri za nastavljanje ob začenjanju razreda. V primeru vključitve na stran ste videli, da sem raje uporabil veriženje metod. Izberite tisto, kar vam bolj ustreza. Znotraj izgrajevalnika morate tudi spremeniti polje veljavnih prejemnikov. Če boste to preskočili, se e-pošta ne bo poslala.

  public function __construct($parametri = null) 
  {
    // nastavi nekatere privzete spremenljivke in preveri obstoj vsakega parametra ter izvedi ustrezno metodo
    $this->veljavni_prejemniki = array('example@example.com', 'example2@example.com'); // spremenite v vaše veljavne e-naslove
    if (isset($parametri['zadeva'])) {
      $this->zadeva($parametri['zadeva']);
    }
    if (isset($parametri['besedilo'])) {
      $this->besedilo($parametri['besedilo']);
    }
    if (isset($parametri['posiljatelj'])) {
      $this->posiljatelj($parametri['posiljatelj']);
    }
    if (isset($parametri['prejemnik'])) {
      $this->prejemnik($parametri['prejemnik']);
    }
  }

Okrog metod za nastavljanje ni kaj preveč za filozofirati. Metode poskrbijo, da so vnosi nastavljeni in dovolj dolgi, e-pošta pošiljatelja se preverja preko filtra, e-pošta prejemnika pa se izbere iz seznama veljavnih prejemnikov. V kolikor pogojem ni zadoščeno, se spremenljivka razreda ne nastavi in pošiljanje ne bo uspelo. V te metode lahko vključite tudi lastne pogoje.

  public function zadeva($zadeva = null) 
  {
    // nastavi zadevo e-pošte
    if (!is_null($zadeva) && strlen($zadeva) >= $this->min_dolzina_zadeve) {
      $this->zadeva = $zadeva;
    }
    return $this;
  }
  public function besedilo($besedilo = null) 
  {
    // nastavi besediloo e-pošte
    if (!is_null($besedilo) && strlen($besedilo) >= $this->min_dolzina_besedila) {
      $this->besedilo = $besedilo;
    }
    return $this;
  }
  public function posiljatelj($posiljatelj = null) 
  {
    // nastavi pošiljateljao e-pošte
    if (!is_null($posiljatelj)) {
      $posiljatelj = filter_var($posiljatelj, FILTER_VALIDATE_EMAIL);
      if ($posiljatelj !== false) {
	$this->posiljatelj = $posiljatelj;
      }
    }
    return $this;
  }
  public function prejemnik($prejemnik = null) 
  {
    // nastavi prejemnika e-pošte
    if (!is_null($prejemnik) && in_array($prejemnik, $this->veljavni_prejemniki)) {
      $this->prejemnik = $prejemnik;
    }
    return $this;
  }

Metoda poslji() preveri, če so vsi parametri sploh nastavljeni in jih šele nato posreduje funkciji mail(). Ta vrne true, če je pošiljanje uspelo in false, če ni. @ poskrbi za to, da se v primeru napake ne prikaže obvestilo o napaki. Besedilo se prelomi pri 70 znakih, za kar poskrbi funkcija wordwrap(). Ker smo preko metode posiljatelj() preverili, če je $_POST['posiljatelj'] res e-poštni naslov, smo relativno varni pred zlorabami, ki v $glave vrinejo poljubno kodo.

    public function poslji() 
  {
    // pošlje obvestilo na e-mail
    if (!is_null($this->zadeva) && !is_null($this->besedilo) && !is_null($this->posiljatelj) && !is_null($this->prejemnik)) {
      $glave = 'Content-Type: text/plain; charset=UTF-8' . "\r\n" . 'From: ' . $this->from . "\r\n" . 'Reply-To:' . $this->posiljatelj;
      return @mail($this->prejemnik, $this->zadeva, wordwrap($this->besedilo, 70), $glave);
    }
    return false;
  }

Zadnja metoda skrbi za izpis obrazca za pošiljanje ob izpisu razreda preko echo. Kot lahko vidite, imajo vsa polja obrazca atribut required, ki že v brskalniku prikaže opozorilo, da je polje treba izpolniti. Če je polje prazno, se nastavi slog CSS napaka, podatki pa se ob pošiljanju ne pobrišejo iz polja temveč ohranijo (pridobivam jih iz vrednosti $_POST). Na tem mestu lahko dodate kodo, ki bo ob uspešnem pošiljanju te vrednosti počistila.

  public function __toString() 
  {
    // izpise vnosno polje
    $html = '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">    
    <table>	
    <tr>
      <td><label for="posiljatelj">E-poštni naslov (zahtevano)</label></td>
      <td><input' . (is_null($this->posiljatelj) ? ' class="napaka"' : '' ) . ' type="email" name="posiljatelj" id="posiljatelj" aria-label="E-poštni naslov (zahtevano)" placeholder="E-poštni naslov (zahtevano)" value="' . $_POST['posiljatelj'] .'" required /></td>
    </tr><tr>
      <td><label for="zadeva">Zadeva (' . $this->min_dolzina_zadeve . ' ali več znakov, zahtevano)</label></td>
      <td><input' . (is_null($this->zadeva) ? ' class="napaka"' : '' ) . ' type="text" id="zadeva" name="zadeva" aria-label="Kratka zadeva (' . $this->min_dolzina_zadeve . ' ali več znakov, zahtevano)" placeholder="Kratka zadeva (zahtevano)" value="' . $_POST['zadeva'] . '" required /></td>
    </tr><tr>
      <td><label for="besedilo">Besedilo (' . $this->min_dolzina_besedila . ' ali več znakov, zahtevano)</label></td>
      <td><textarea' . (is_null($this->besedilo) ? ' class="napaka"' : '' ) . ' id="besedilo" name="besedilo" rows="8" cols="70" aria-label="Besedilo (zahtevano)" placeholder="Besedilo (' . $this->min_dolzina_besedila . ' ali več znakov, zahtevano)" required>' . $_POST['besedilo'] . '</textarea></td>
    </tr><tr>
      <td></td><td><button type="submit" name="poslji">Pošlji</button></td>
    </tr>
    </table>
  </form>';
    return $html;
  }

Vam je vsebina všeč? Delite jo na: