Jak odstranit emoji

Objevila se u mne potřeba ošetřit uživatelské texty tak, aby neobsahovaly emoji a podobné patvary, které umožňuje UTF-8 kódování. Pár napsaných funkcí jsem objevil, ale nic, co by bylo bezchybné. No a tak jsem přemýšlel co s tím, a netrvalo dlouho, a předkládám vlastní řešení.

Je to jednoduché. Stačí uživatelský vstup v UTF-8 převést do kódování WINDOWS-1250 a zpět, s příznakem IGNORE. Veškerý bordel, který WINDOWS-1250 neumí, se ztratí. Hotovo, dobrá práce :)

function remove_emoji($vstup="") {
	$vystup=iconv("UTF-8","WINDOWS-1250//IGNORE",$vstup);
	$vystup=iconv("WINDOWS-1250","UTF-8",$vystup);
	return $vystup;
}

Stahování obrázků z pinterestu

Následující skript je jednoduchý parser, který dokáže stáhnout obrázky z nástěnky jakéhokoliv pinterest účtu spolu s odkazem na detail obrázku.

Nejprve funkce, která ukládá obrázky do adresáře temp.

function ulozobrazek($novynazev,$url,$sirka,$maxvyska=0) {
  $adresa=false;
  $urlbez=preg_replace('/\\?.*/', '', $url);
  $ext=str_replace('.','',strrchr($urlbez,'.'));
  $ext=strtolower($ext);
  if ($pos=strpos($ext,"?")) $ext=substr($ext,0,$pos);
  $novy="tmp_".$novynazev.".".$ext;
  if ($ext=="jpg" || $ext=="jpeg" || $ext=="gif" || $ext=="png") {
    @$file=fopen($url,"rb");
    if ($file) {
      $fc=fopen("temp/$novy","wb");
      while (!feof($file)) { 
        $line=fread($file,8192); 
        fwrite($fc,$line); 
      } 
      fclose($fc);
      $sku=exif_imagetype("temp/$novy");
      switch ($sku) {
        case 1:	// IMAGETYPE_GIF
          $opr="gif";
        break;
        case 2:	// IMAGETYPE_JPEG
          $opr="jpg";
        break;
        case 3:	// IMAGETYPE_PNG
          $opr="png";
        break;
        default:
          $opr=$ext;
        break;
      }
      if ($ext!=$opr) $ext=$opr;
      $novynazev=$novynazev.".jpg";
      if ($ext=="jpg") {
        $im=imagecreatefromjpeg("temp/$novy");
      } elseif ($ext=="gif") {
        $im=imagecreatefromgif("temp/$novy");
      } elseif ($ext=="png") {
        $im=imagecreatefrompng("temp/$novy");
      }
      $im_width=imagesx($im);
      $im_height=imagesy($im);
      $vyska=round($im_height*$sirka/$im_width);
      if ($maxvyska>0 && $vyska>$maxvyska) {
        $sirka=round($sirka/$vyska*$maxvyska);
        $vyska=$maxvyska;
      }
      $new_im=imagecreatetruecolor($sirka,$vyska);
      imagecopyresampled($new_im,$im,0,0,0,0,$sirka,$vyska,$im_width,$im_height);
      imagedestroy($im);
      imagejpeg($new_im,"temp/".$novynazev,80);
      @unlink("temp/".$novy);
      return("temp/".$novynazev);
    }
  }
  return($adresa);
}

A následuje skript, který uloží posledních 12 pinů z nástěnky uživatele pinterest (https://cz.pinterest.com/pinterest/pins/) jako obrázky a vrátí řetězec obrázků s odkazy v proměnné $data.

$data = '';
$subject = file_get_contents('https://cz.pinterest.com/pinterest/pins/');
$pattern = '/\"orig\": \{\"url\": \"(.*?)\", \"width\":/si';
preg_match_all($pattern, $subject, $matches);
$i=0;
foreach ($matches[1] as $item) {
  $item=str_replace("\\","",$item);
  $nazevobrazku=time().$plusobrazek;
  $nazevobrazku="pinterest_".sha1($nazevobrazku);
  $plusobrazek++;
  $vratobrazek=ulozobrazek($nazevobrazku,$item,100);
  if ($vratobrazek) {
    list($sirka,$vyska)=getimagesize($vratobrazek);
    $data .= '<a href="https://cz.pinterest.com/pinterest/pins/" target="_blank"><img src="' . $vratobrazek . '" style="width:'.$sirka.'px;height:'.$vyska.'px;margin-bottom:5px;"></a>';
    $i++;
    if ($i==12) break;
  }
}

Volání funkce ulozobrazek si můžete upravit a nastavit potřebnou maximální šířku, případně i výšku uloženého obrázku.

Zvýraznění výsledků vyhledávání

Jednoduchá funkce pro zvýraznění výsledků ve vyhledávání. Všechny nálezy označí třídou marked.

function highlightStr($needle,$haystack) {
    if (strlen($haystack) < 1 || strlen($needle) < 1) {
        return $haystack;
    }
    preg_match_all("/$needle+/i", $haystack, $matches, PREG_SET_ORDER);
    if (is_array($matches[0]) && count($matches[0]) >= 1) {
        foreach ($matches[0] as $match) {
            $haystack = str_replace($match, '<span class="marked">'.$match.'</span>', $haystack);
        }
    }
    return $haystack;
}

Čtení emailů přes IMAP v PHP

V dnešním článku se zaměříme na to, jak zpracovat příchozí e-maily. Pokud potřebujete deaktivovat odběratele newsletteru, kteří mají nedostupnou schránku a vám se vrací emaily o nedoručitelnosti, je řešením takovéto emaily projít a adresu odstranit. Nemusíme to však dělat ručně, dá se to zautomatizovat.

Předpokládám, že na odesílání newsletteru se bude používat spíše samostatná schránka, něco jako no-reply@domena.cz. Pokud by se používala nějaká pracovní, tak by se mohlo stát, že byste prošvihli e-mail o nedoručení, který jste prošvihnout nechtěli.

Následující skript se tedy nejprve připojí do schránky přes imap. Projde všechny zprávy a přečte si jejich obsah. V textu zprávy najde všechny e-mailové adresy, vyloučí ty, které mají co dočinění s doménou odesílatele, a naznačí zpracování co se s těmi adresami dá udělat, typicky smazat nebo deaktivovat.

$mbox = imap_open("{imap.domena.cz:143/notls}Inbox", "jmeno", "heslo") or die();
$MC = imap_check($mbox);
$result = imap_fetch_overview($mbox,"1:{$MC->Nmsgs}",0);
foreach ($result as $overview) {
  $uid=$overview->uid;
  if ($overview->from == "MAILER-DAEMON@domena.cz") {
    $zprava=imap_fetchbody($mbox,$uid,1,FT_UID);
    $pattern = '/[a-z0-9_\-\+]+@[a-z0-9\-]+\.([a-z]{2,3})(?:\.[a-z]{2})?/i';
    preg_match_all($pattern, $zprava, $matches);
    foreach ($matches[0] as $email) {
      if (strpos($email,'domena')===false) {
        --- /zkontroluj email v databázi a pokud najdeš shodu/ {
          --- /smaž nebo deaktivuj/
          imap_delete($mbox,$uid,FT_UID);
          break;
        }
      }
    }
  }
}
imap_expunge($mbox);
imap_close($mbox);

Načtení kategorií z heureky

Pokud chcete úspěšný eshop, budete pravděpodobně párovat u zboží kategorie s heurekou. K tomu potřebujete ideálně do databáze dostat všechny heureka kategorie, a následně je buď u kategorií nebo u zboží spárovat. Budu se nyní zabývat tím, jak dostat celý strom kategorií na lokální server do databáze.

V databázi předpokládám tabulku s názvem heureka_kategorie a s jediným sloupcem pojmenovaným nazev. Níže uvedený kód načte všechny kategorie heureky a uloží je do dočasného XML souboru na disku. Následně tento soubor zpracuje a všechny kategorie uloží do databáze, přičemž je ukládá jako textový řetězec včetně celé cesty, tzn. názvy kategorií odděleny oddělovačem |.

$file="http://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml";
$ch = curl_init($file);
$fp = @fopen("tmp/heureka.xml", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);

function vetev($PARENT) {
  global $dbh;
  if (isset($PARENT->CATEGORY)) {
    foreach($PARENT->CATEGORY as $CHILD) {
      $CATEGORY_FULLNAME = isset($CHILD->CATEGORY_FULLNAME) ? $CHILD->CATEGORY_FULLNAME : "";
      $CATEGORY_FULLNAME = trim(str_replace("Heureka.cz |", "", $CATEGORY_FULLNAME));
      if ($CATEGORY_FULLNAME) $dbh->query("insert into heureka_kategorie (nazev) values ('".$CATEGORY_FULLNAME."')");
      vetev($CHILD);	
    }
  }
}

if (file_exists("tmp/heureka.xml")) {

$xml = file_get_contents("tmp/heureka.xml");
$HEUREKA = new SimpleXMLElement($xml);

try {
  $dbh = new PDO("mysql:host=localhost;dbname=nazevdatabaze;charset=utf8",'jmeno','heslo');
  $dbh->query("truncate table heureka_kategorie");
  vetev($HEUREKA);
  $dbh = null;
} catch (PDOException $e) {
    echo "Error!: " . $e->getMessage() . "<br/>";
    exit();
}

}

Načítání měnových kurzů z ČNB nebo ČSOB

Jelikož potřebuji na některých eshopech převádět české koruny na eura, napsal jsem si třídu, která dokáže aktuální kurzy načíst z ČNB nebo z ČSOB. Třídu můžete stáhnout zde.

Co umí? Dokáže načíst online měnový kurz pro jakoukoliv měnu, kterou má daná banka přístupnou na webu. A také načíst všechny tyto údaje do pole a vyhodit jej pro případ, že budete chtít zobrazit více kurzů.

Následující kód vypíše EUR kurz z ČNB:

require_once('kurzy.class.php');
$kurz = new Courses('CNB');
echo $kurz->showOneCourse('EUR');

Tento kód vypíše pole měnových kurzů z ČSOB:

require_once('kurzy.class.php');
$kurz = new Courses('CSOB');
var_dump($kurz->showCourses());

Jak jste jistě pochopili, pro vytvoření instance třídy se použije new Courses(‚nazev_banky‘) a existují dvě metody:

1. showOneCourse(‚mena‘)
– vrátí aktuální kurz pro jednu měnu
2. showCourses()
– vrátí pole kurzů ($pole[‚mena‘])

Název banky může nabývat hodnot ‚CNB‘ nebo ‚CSOB‘. Měna pak ‚EUR‘, ‚USD‘, ‚GBP‘, …

Na závěr doporučení, pokud byste aktualizovali přes tuto třídu kurzy online a třeba každou vteřinu, budete zatěžovat mateřský server banky a to se jim nemusí zrovna dvakrát líbit. Doporučuji proto kurzy skrz tuto třídu ukládat třeba do databáze a aktualizovat jednou za hodinu, nebo jednou za den, dle potřeby.

Odesílání e-mailů v PHP

Pro zasílání e-mailů jsem si oblíbil knihovnu swiftmailer. Je zdarma a je jednoduchá na použití. Umí samozřejmě odesílat i přílohy a využívat funkci mail() anebo přímo smtp server.

require_once('lib/swift_required.php');
$transport = Swift_SmtpTransport::newInstance('smtp.example.org',25)
  ->setUsername('username')
  ->setPassword('password')
;
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('predmet emailu');
$textzpravy = "Ahoj, posílám obrázek: <img src=".$message->embed(Swift_Image::fromPath('image.jpg')).">";
$message -> setFrom('emailodesilatele');
$message -> setBody($textzpravy);
$message -> setTo(array('emailprijemce'));
$result = $mailer -> send($message);