Válasz a hozzászólásra

Email címek spam védelme

Az interneten közzétett e-mail címeket könnyen megtalálják kereső robotok, hogy aztán a postaládát teletömjék kéretlen levelekkel. Szerencsére a fórumozók nagyon-nagy többsége tisztában van ezzel a jelenséggel, ezért kerülik az e-mail címek közvetlen megadását. A másik jó megoldás egy teljes levél küldési űrlap elhelyezése. Persze ezt is védeni kell. De még így is lehetnek olyan esetek amikor az e-mail címet láthatóvá kell tenni. Smink & jQuery párossal ezeket is meg lehet védeni.

A megoldás alapját Boros Ádám trükk tarisznyájából előhúzott pesudo filter adja. A HTML-szűrő ami része az alapértelmezett Filtered HTML beviteli formának, a megtalált e-mail címeket kattintható linkekké alakítja.
Ilyenről gipsz-jakab@example.com
Ilyenre <a href="mailto:gipsz-jakab@example.com">gipsz-jakab@example.com</a>
Ez egyaránt kényelmes a felhasználóknak és a robotoknak is :)

A lényeg az hogy a felhasználó által helyesen beírt e-mail címet el kell rontani, még a szerver oldalon, de csak annyira, hogy a robotok ne ismerjék fel, de egy 10-es IQ-val rendelkező felhasználó is azért még gyanút fogjon.
Például így: gipsz-jakab [kukac] example [pont] com

A feladat első része a smink template.php állományában implementálni a phptemplate_preprocess_node() függvényt.

function deep_marine_preprocess_node(&$vars) {
  _deep_marine_protect_email_addresses($vars['content']);
}
 
function _deep_marine_protect_email_addresses(&$subject) {
  $user   = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+';
  $domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+';
  $ipv4   = '[0-9]{1,3}(\.[0-9]{1,3}){3}';
  $ipv6   = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}';
 
  //Ez a csinos kis RegEx keresi a HTML-filter által készített kattintható e-mail címeket.
  //Nem véletlenül van 2 string-ből összerakva.
  $pattern_email_href = "/<a href=\"mailto:($user)@($domain|(\[($ipv4|$ipv6)\]))\">".'\1@\2<\/a>/';
 
  $matches = array();
  $result = preg_match_all($pattern_email_href, $subject, $matches, PREG_SET_ORDER);
  if ($result) {
    //Ha van e-mail cím a szövegben akkor,
    //el kell küldeni a böngészőnek azt a JavaScript-et ami majd visszaalakítja.
    drupal_add_js(drupal_get_path('theme', 'deep_marine') .'/dm_eposta.js', 'theme');
  }
 
  //A kulcs elemeket álcázó szövegek.
  $dot = t('[dot]');
  $at  = t('[at]');
 
  //A találatok feldolgozása egyenként
  //Ha ugyanaz az e-mail cím többször is szerepel a szövegben
  //akkor nem a legoptimálisabb.
  //mert már az első feldolgozásnál az összes előfordulás lecserélődik.
  foreach ($matches as $match) {
    if ( preg_match("/$domain/", $match[2])) {
      //ha az e-mail cím domain része nem IP címmel van megadva
      //hanem rendesen szöveggel,
      //akkor az utolsó pontot kell lecserélni az álcára
      $dot_pos = strrpos($match[2], '.');
      $match[2] = substr($match[2], 0, $dot_pos) .' '. $dot .' '. substr($match[2], $dot_pos + 1);
    }
    //A username és domain rész közé bekerül a kukacot álcázó szöveg,
    //és eltünik a href attributum, ezáltal nem lesz kattintható a link.
    //A robotoknak persze mindegy,
    //de a felhasználó nem fogja anyázva nyomkodni a nem működő linket.
    //Legfontosabb, hogy kap egy class-t ami alapján majd a jQuery
    //azonosítja az ilyen linkeket.
    $protected = "<a class=\"eposta\">{$match[1]} $at {$match[2]}</a>";
    $subject = str_replace($match[0], $protected, $subject);
  }
  //Nincs return mert referenciával veszi át a függvény a $subject-et
}

Earl Hickey követendő példáját szem előtt tartva én is készítettem egy listát az elrontott e-mail címekről, és ezennel visszaalakítom őket.
dm_eposta.js

$(document).ready(
  function() {
    var dot = Drupal.t('[dot]');
    var at  = Drupal.t('[at]');
    $("a[class=eposta]").each( function(i) {
      address = $(this).text().replace(" "+ at +" ", "@").replace(" "+ dot +" ", ".");
      this.href = "mailto:" + address;
      $(this).removeClass("eposta");
      $(this).text(address);
    });
  }
);

Nem csak tartalmakra(node) és kommentekre lehet alkalmazni, hanem a page.tpl.php-ban alkalmazva akár a teljes kimenetet lehet szűrni. Viszont figyelni kell arra, hogy a drupal_add_js() függvényhívás haszontalan, hiszen ilyenkor már a $scripts változó tartalmazza a HTML kimenetet. A jQuery kódot olyan fájlba kell rakni amit biztosan megkap a böngésző.

Biztos vagyok benne, hogy ennek a problémának a megoldására nem ez a legprofibb és leghatékonyabb módszer, viszont egyszerű. :-)

gipsz-jakab [at] example [dot] com

Válasz

A mező tartalma nem nyilvános.
  • A webcímek és email címek automatikusan linkekké alakulnak.
  • Engedélyezett HTML elemek: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • A sorokat és bekezdéseket a rendszer automatikusan felismeri.
  • You can enable syntax highlighting of source code with the following tags: [code], [blockcode]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

További információ a formázási lehetőségekről

Type the characters you see in this picture. (verify using audio)
A képen látható karaktereket kell megadni. Ha olvashatatlan, akkor egy üres beküldéssel lehet új képet kérni. Nem betűérzékeny.