Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Problém s php scriptem pro generování e-mailu

Dotaz bude trochu složitější, omlouvám se... ale pokusím se co nejjednodušeji vysvětlit problém.
1) PHP příliš nerozumím, umím jen to, co jsem se naučil "za pochodu", což je opravdu hodně málo...
2) Používám CMS PHP-Fusion a rád bych použil soubor s "panelem" Tell a Friend, tedy jakési jednoduché doporučení stránky, na které uživatel je.
3) Na stránkách s mody pro CMS PHP-Fusion jsem našel jakýsi skript, který moc nefungoval a jestli dokážu laicky posoudit, zdál se mi poněkud "zmatený" a svými vlastními úpravami jsem ho dorazil. Nicméně po konzultacích s lidmi, kteří tomu rozumějí jsem ho jakžtakž dokázal zprovoznit, což považuji za malý zázrak. Ovšem dějí se v něm stále docela zvláštní věci.
4) Nejpozoruhodnější je následující: skript využívá proměnné z externího souboru (kvůli lokalizaci) např.

$webmasterEmail = $locale['TF_002'];

. Někdy to jde bez problémů, na jiném místě scriptu odkaz na jiný soubor nefunguje - a syntaxe je poodle věech lidí, se kterými jsem to konzultoval správná... Proto mi nezbývalo, než lokalizaci definovat "natvrdo".
5) A teď co vlastně potřebuji: hledám někoho, kdo dokáže odhalit problém s těmi odkazy na externí soubor a eventuálně ten script pročistit... (rád bych ještě jednu drobnou úpravu, ale tohle je teď to hlavní). Díky všem, kteří najdou tu odvahu a podívají se na to...

1. část scriptu:

if (!defined("IN_FUSION")) { header("Location:../../index.php"); exit; }
if (file_exists(INFUSIONS."tell_friend_panel/locale/".$settings['locale'].".php")) {
        include INFUSIONS."tell_friend_panel/locale/".$settings['locale'].".php";
} else {
        include INFUSIONS."tell_friend_panel/locale/English.php";
}

openside($locale['TF_001']);

$webmasterEmail = $locale['TF_002'];
$returnPage = $locale['TF_003'];
$sendNotification = 0;
$subject = $locale['TF_009'];
$customMessage = $locale['TF_016'];
$sendAsHtml = 0;
$htmlHeader = <<<EOD
EOD;

error_reporting(E_ERROR); 
/* start main */
if(!isset($_POST["action"])) {
if($useHeader) include($headerFile);
show_form();
if($useFooter) include($footerFile);
} else {
//begin error checking
$_POST['senderEmail'] = trim($_POST['senderEmail']);

if(!isValid($_POST['senderEmail'])) {
$error[] = $locale['TF_005'];
unset($_POST['senderEmail']);
}
$validRecips = check_valid($_POST['friend']);
if($validRecips == FALSE) {
$error[] = $locale['TF_006'];
}
//end error checking

if($useHeader) include($headerFile);

if($error) {
echo "<center>\n";
foreach($error as $oneError) {
echo "$oneError<br>\n";
}
echo "</center>\n";

echo show_form();

if($useFooter) include($footerFile);

} else { //no error
$subject = str_replace("[SENDER_EMAIL]", $_POST['senderEmail'], $subject);
$message = $_POST['customMessage'] . "\n\n\n_________________________________________\n"
.$locale['TF_007']. $_SERVER['SERVER_NAME'] . $locale['TF_008']. "$webmasterEmail.";
Předmět Autor Datum
2. část scriptu: echo "<center>\n"; if($_POST['toself'] == TRUE) { array_push($validRecips, $_POST[…
Drbo 26.07.2007 23:32
Drbo
Losi, kde jsi...? Nezklam mě... :-)
Drbo 27.07.2007 15:43
Drbo
No potěš koště! :-) Takhle "nasucho" hledat chybu bude trochu problém. Někdy to jde bez problémů,…
host 27.07.2007 15:51
host
1) Ten externí soubor je includován - viz úvodní řádky sktiptu 2) Nejedou ty řádky, kde je natvrdo n…
Drbo 27.07.2007 16:01
Drbo
V konštante INFUSIONS máš relatívnu cestu? Keď používaš include, tak aktuálna cesta je rovnaká, ako…
los 27.07.2007 16:03
los
Bože můj, jak já bych chtěl vědět o čem mluvíš... :-( Ty nefunkční odkazy byly ve tvaru (např): ec…
Drbo 27.07.2007 16:08
Drbo
Píšeš, že ti nefunguje ti 2. až 6. riadok - include súboru. V include používaš konštantu INFUSIONS.…
los 27.07.2007 16:14
los
Alebo to nefunguje pri jednom volaní skriptu? Tak potom to môže byť tým, že vo funkcii nemáš tú prem…
los 27.07.2007 16:18
los
Czech.php vypadá takhle: <?php $locale['TF_001'] = "Doporučit tuto stránku"; $locale['TF_002'] = "a…
Drbo 27.07.2007 16:21
Drbo
Omlouvám se, opravdu jsem jen laik... takže nevím, jestli ti odpovím správně, ale konstanta INFUSION…
Drbo 27.07.2007 16:19
Drbo
Čo vlastne nefunguje - include alebo len nemáš prístupnú tú premennú? Akú chybovú hlášku to vypíše (…
los 27.07.2007 16:27
los
Nemám přístupné ty proměnné - ale jen někdy, což je právě zvláštní... Někde to funguje bez problémů…
Drbo 27.07.2007 16:35
Drbo
Kedy presne je to někdy? Ten riadok <tr>... value='".$locale['TF_018']."'>...</tr> v tom pôvodnom k…
los 27.07.2007 16:51
los
To je řádek z kódu, kdy jsem se to marně pokoušel přepsat... dělá to ve všech případech, kde je v to…
Drbo 27.07.2007 16:54
Drbo
Čiže to je v tej funkcii show_form? Keď dáš na začiatok tej funkcie toto, pomôže to? global $locale…
los 27.07.2007 16:57
los
Okamžik, vyzkouším...
Drbo 27.07.2007 17:05
Drbo
Ano, jsi génius!!! Asi to bylo v tom. tlačítko Odeslat funguje i s odkazem na local file... Překóduj…
Drbo 27.07.2007 17:28
Drbo
Ak chceš posielať iný text, tak musíš posielať ďalší e-mail. Zhůvěrilosti? Nevidím tam nič také str…
los 27.07.2007 18:22
los
OK, díky moc... jen nerozumím, proč přejmenovávat TF na WTF...
Drbo 27.07.2007 18:27
Drbo
Skrátka na niečo výstižnejšie, nemusí to byť WTF.
los 27.07.2007 18:38
los
WTF - měl jsi na mysli to co já? ]:)
host 27.07.2007 18:42
host
Tak zatím to všechno chodí... ještě jednou díky... ale objevil jsem další zvláštnost - tedy pro mě z…
Drbo 27.07.2007 17:59
Drbo
Tam ti něco chybí, ne? Tečku bych dal za input a na konec echa uvozovky. Zkus takto: echo "<tr><td>…
host 27.07.2007 18:22
host
OK, díky.
Drbo 27.07.2007 18:28
Drbo
$cesky = "Příliš žluťoučký kůň úpěl ďábelské ódy." $bez_diakritiky = StrTr ($cesky, "áäčďéěëíňóöřšťú…
host 27.07.2007 18:32
host
Mail si posielal ako text, takže ak je v prijatej správe bodka súčasťou odkazu, tak za to môže pošto…
los 27.07.2007 18:36
los
OK, díky všem.
Drbo 27.07.2007 19:02
Drbo
Přece jenom ještě dotaz, teď spíš ze zvědavosti... co v tom kódu znamená to <<<EOD
Drbo 27.07.2007 20:48
Drbo
$heredoc = <<<EOD Tady je nejaky text. Tady je nejaky text. Tady je nejaky text. Tady je nejaky text…
host 27.07.2007 21:13
host
Znamená to v tomto případě $htmlHeader = <<<EOD EOD; že tyhle řádky mohu smazat, protože proměnná…
Drbo 27.07.2007 21:17
Drbo
Ty řádky mají svůj význam, nemaž je. Obsah se do proměnné vloží na jiném místě skriptu.
host 27.07.2007 21:19
host
Ano, to jsem chtěl vědět. Díky. poslední
Drbo 27.07.2007 21:27
Drbo

2. část scriptu:

echo "<center>\n";

if($_POST['toself'] == TRUE) {
array_push($validRecips, $_POST['senderEmail']);
}

$content = ($sendAsHtml == TRUE ? "text/html" : "text/plain");
$message = stripslashes($message);
if($sendAsHtml == 1) $message = $htmlHeader . nl2br(trim($message));


$headers = "From: " . $_POST['senderEmail'] . "\r\n";
$headers .= "X-Mailer: ".$locale['TF_003']."\r\n";
$headers .= "Content-Type: $content";

foreach($validRecips as $recip) {
$friends .= $recip . " ";
@mail($recip, $subject, $message, $headers);
echo $locale['TF_010']."$recip<br>\n";
}
echo "</center>\n<br>\n<center><b>".$locale['TF_011']."</b><br><br>\n\n";

if($useFooter) include($footerFile);


}
}
/* end main */
/* mixed */ function check_valid($list) 
{
global $errorCode;

$numElements = sizeof($list);
$goodEmails = array();

foreach($list as $single) {
if(isValid($single)) {
$goodEmails[] = $single;
}
}

if(!empty($goodEmails)) {
return array_unique($goodEmails);
} else {
return FALSE;
}
}


/* void */ function show_form()
{
global $validRecips, $customMessage;
$senderEmail = (!isset($_GET['se']) ? $_POST['senderEmail'] : urldecode($_GET['se']));
//sender vars
echo "<form method='POST' action='".FUSION_SELF.(FUSION_QUERY ? "?".str_replace("&","&",FUSION_QUERY) : "")."'>\n
<input type='hidden' name='action' value='submit'>\n
<table border='0' align='center' cellpadding='1' cellspacing='0>'\n
<tr><td>E-mail odesílatele:</td></tr>\n
<tr><td><input class='textbox' style='width:150px' type='text' name='senderEmail' value='' size='10'></td></tr>\n
<tr><td>E-mail příjemce:</td></tr>\n
<tr><td><input class='textbox' style='width:150px' type='text' name='friend[]' value='' size='10'></td></tr>\n";

function selfURL1() {
$s = empty($_SERVER["HTTPS"]) ? ''
: ($_SERVER["HTTPS"] == "on") ? "s"
: "";
$protocol = strleft1(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
$port = ($_SERVER["SERVER_PORT"] == "80") ? ""
: (":".$_SERVER["SERVER_PORT"]);
return $protocol."://".$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
}
function strleft1($s1, $s2) {
return substr($s1, 0, strpos($s1, $s2));
}

echo "<tr><td><input class='textbox' name='customMessage' type='hidden' value='";
print($customMessage.(selfURL1()));
echo "'></td></tr>\n
<tr><td><input type='checkbox' name='toself'> Kopie odesílateli</td></tr>\n
<tr><td align='center'><input class='button' type='submit' value='Odeslat'></td></tr>\n
</table>\n
</form>\n";
}

/* bool */ function isValid($email)
{
return eregi("^[a-z0-9\._-]+@+[a-z0-9\._-]+\.+[a-z]{2,4}$", $email);
}
closeside();

No potěš koště! :-)

Takhle "nasucho" hledat chybu bude trochu problém.

Někdy to jde bez problémů, na jiném místě scriptu odkaz na jiný soubor nefunguje

Na jakém řádku konkrétně a jaký odkaz nefunguje? Jak se to projevuje? Týká se to jen tohoto jednoho skriptu? Je includován ten externí jazykový soubor?

...a svými vlastními úpravami jsem ho dorazil.

Co to bylo za úpravy? Jak vypadá originál skript?

http://php-fusion.co.uk/forum/viewthread.php?forum_ id=26&thread_id=16775&pid=98202 8-)

1) Ten externí soubor je includován - viz úvodní řádky sktiptu
2) Nejedou ty řádky, kde je natvrdo nakódována čeština místo odkazu na ten externí soubor
3) Ano, ten originál skript (který ale nefungoval jak měl) je na té adrese v php-fusion fóru - BTW, to je moje vlákno, kde jsem právě řešil ty úpravy...:-D

Díky za každou myslitelnou i nemyslitelnou pomoc...

Bože můj, jak já bych chtěl vědět o čem mluvíš... :-(

Ty nefunkční odkazy byly ve tvaru (např):

echo "<td>".$locale['TF_002']."</td>";

a tak podobně... ten externí soubor je stále jeden a tentýž...

P.S. Los nezklamal! :-) Tedy zatím jen svojí přítomností... Ale jak už jsem psal v tom vláknu ohledně javascriptu, my zvířata bychom si měla pomáhat (severské - los x jihoamerické - lama)

Píšeš, že ti nefunguje ti 2. až 6. riadok - include súboru. V include používaš konštantu INFUSIONS. Ak je prázdna, tak sa inkludovaný súbor "tell_friend_panel/locale/..." berie z aktuálneho adresára.

Predpokladám, že ti to funguje vtedy, keď inkluduješ tento skript z toho istého adresára a nefunguje to vtedy, keď ho inkluduješ z iného adresára. Je to tak?

Takže aký je vlastne aktuálny adresár pri volaní include v prípade, že to nefunguje a v prípade, že to funguje?

Czech.php vypadá takhle:

<?php
$locale['TF_001'] = "Doporučit tuto stránku";
$locale['TF_002'] = "admin@drbo.cz"; //zde vyplňte e-mail webmastera
$locale['TF_003'] = "www.drbo.cz"; //zde vyplňte adresu vašeho webu
$locale['TF_004'] = "";
$locale['TF_005'] = "Není zadána e-mailová adresa odesílatele.";
$locale['TF_006'] = "Není zadána e-mailová adresa příjemce.";
$locale['TF_007'] = "Tato zpráva byla automaticky generována z webu ";
$locale['TF_008'] = " na základě požadavku odesílatele.\nPokud Vám odesílatel není znám, prosím kontaktujte administrátora na adrese ";
$locale['TF_009'] = "Doporučení zajímavé stránky";
$locale['TF_010'] = "Doporučení bylo odesláno na adresu ";
$locale['TF_011'] = "Děkujeme :)";
$locale['TF_012'] = "";
$locale['TF_013'] = "";
$locale['TF_014'] = "E-mail odesílatele:";
$locale['TF_015'] = "E-mail příjemce:";
$locale['TF_016'] = "Na internetu jsem objevil zajímavou stránku. Odkaz na ni je ";
$locale['TF_017'] = " Kopie odesílateli";
$locale['TF_018'] = "Odeslat";
?>

Omlouvám se, opravdu jsem jen laik... takže nevím, jestli ti odpovím správně, ale konstanta INFUSIONS jenom odkazuje na cestu root/infusions. V adresáři infusions je adresář "tell_friend" a ten obsahuje jednak tenhle php soubor, jednak složku "locale" kde je ten inkludovaný - vida, už si připadám jako programátor :-) - soubor.

Nemám přístupné ty proměnné - ale jen někdy, což je právě zvláštní... Někde to funguje bez problémů a někde to prostě nereaguje - chybovou hlášku to nenapíše žádnou, jen se to prostě nezobrazí... Typický příklad:

Tohle funguje, normálně se zobrazí tlačítko s popiskem "Odeslat"

<tr><td align='center'><input class='button' type='submit' value='Odeslat'></td></tr>\n

a tohle ne:

<tr><td align='center'><input class='button' type='submit' value='".$locale['TF_018']."'></td></tr>\n

Žádnou hlášku to ale nevyhodí, prostě se objeví tlačítko bez popisku.

To je řádek z kódu, kdy jsem se to marně pokoušel přepsat... dělá to ve všech případech, kde je v tom původním kódu napsaná česká věta místo toho, aby to odkazovalo na ten inkludovaný soubor. (správně by se tam žádná čeština vůbec neměla objevit a všechny věty by měly odkazovat ven kvůli lokalizaci do jiných jazyků).

Ano, jsi génius!!! Asi to bylo v tom. tlačítko Odeslat funguje i s odkazem na local file... Překóduji to všude a pak uvidíme... Měl bych ještě jednu prosbu, jestli bys nemohl letmo shlédnout celý ten script jednak jestli tam nejsou nějaké další zhůvěřilosti, které já samozřejmě nepoznám a jednak jestli by nebylo možné někde určit, aby text mailu který jde (pokud se zaškrtne volba) jako kopie odesílateli byl jiný než ten doporučující adresátovi... uff, snad jsem to řekl srozumitelně...

Za tu první korekci ještě jednou dík, snad to bude fungovat i ve zbytku toho scriptu...

Ak chceš posielať iný text, tak musíš posielať ďalší e-mail.

Zhůvěrilosti? Nevidím tam nič také strašné, čo by som neprežil. Iba drobnosť: adresa v hlavičke Location by mala byť podľa špecifikácie absolútna, hoci som sa ešte nestretol s programom, ktorý by s tým mal problém.

Ak hrozí, že ten skript budeš udržiavať/rozširovať (alebo niekto iný, kto vie, kde bývaš), tak by som ničnehovoriace názvy kľúčov TF_xxx premenoval (napr. na trochu výstižnejšie WTF_xxx).

Tak zatím to všechno chodí... ještě jednou díky... ale objevil jsem další zvláštnost - tedy pro mě zvláštnost, pro tebe pravděpodobně logickou věc... Nicméně pohlédni na následující řádky:

echo "<tr><td><input class='textbox' name='customMessage' type='hidden' value='".$locale['TF_016'];
print(selfURL1());
echo ".'></td></tr>\n

Ta tečka na začátku echa ve třetím řádku je "tečka za větou", která následuje po doporučované adrese. V tom doporučovacím mailu je ovšem ta tečka součástí linku , takže ten pak zní "www.xxx.cz.", je aktivní na kliknutí a odkaz je pak vlastně chybný...

Druhá drobnost je, že přijatý mail nezobrazuje korektně češtinu:

...na základě požadavku odesílatele...

Jistě bych to mohl přeformulovat tak, aby se nikde v textu nevyskytoval háček, ale přece jen - chybí tam někde nějaké nastavení?

Tam ti něco chybí, ne? Tečku bych dal za input a na konec echa uvozovky. Zkus takto:

echo "<tr><td><input class='textbox' name='customMessage' type='hidden' value='".$locale['TF_016'];
print(selfURL1());
echo "'>.</td></tr>\n";

A češtinu v mailu generovaném v PHP doporučuju nepoužívat, raději to překonvertuj na znaky bez diakritiky.

$cesky = "Příliš žluťoučký kůň úpěl ďábelské ódy."
$bez_diakritiky = StrTr ($cesky, "áäčďéěëíňóöřšťúůüýžÁÄČĎÉĚËÍŇÓÖŘŠŤÚŮÜÝŽ", "aacdeeeinoorstuuuyzAACDEEEINOORSTUUUYZ");

Pokud bys trval na diakritice, musel bys poslat v mailu hlavičku definující kódování, nějak takto:

$zprava="Nějaký text s českou diakritikou!";
$zprava=Base64_Encode($zprava);
$hlavicka .= "From: adresa@domena.cz\n".
    "MIME-Version: 1.0\n".
    "Content-Type: text/plain; charset=\"windows-1250\"\n".
    "Content-Transfer-Encoding: base64";
... další kód ...
Mail($prijemce,$predmet,$zprava,$hlavicka);
... další kód ... ?>

Mail si posielal ako text, takže ak je v prijatej správe bodka súčasťou odkazu, tak za to môže poštový klient, ktorý nesprávne rozoznáva adresy. Môžeš tomu zabrániť tak, že dáš adresu na samostatný riadok (bez bodky).

Kódovanie e-mailu sa nastavuje v hlavičke Content-Type, takže tam do jedného riadku doplníš ešte kódovanie napr. UTF-8:

$headers .= "Content-Type: $content; charset=utf-8";

Kódovanie predmetu (ak treba) musíš určiť priamo v hlavičke Subject (viď Google).

$heredoc = <<<EOD
Tady je nejaky text. Tady je nejaky text. Tady je nejaky text.
Tady je nejaky text. Tady je nejaky text. Tady je nejaky text.
Tady je nejaky text. Tady je nejaky text. Tady je nejaky text.
Tady je nejaky text. Tady je nejaky text. Tady je nejaky text.
EOD;

V PHP 4 byl zaveden třetí způsob deklarace proměnné typu string, tzv. heredoc syntaxe. Ta je vhodná pro delší úseky textu, protože nevyžaduje používání escape sekvencí pro některé znaky, ale zároveň umožňuje expanzi proměných.

Tento zápis umožňuje vkládání dlouhých textů do proměnných bez nutnosti používat uvozovky nebo apostrofy a zároveň je možné vypisovat hodnoty proměnných a používat escape sekvence jako např. \n.

Text je nutné uzavřít mezi sekvenci <<<identifikátor a identifikátor;. Jako identifikátor můžeme použít jakýkoliv sled alfanumerických znaků a podtržítko, ale nesmí začínat číslicí a nesmí být obsažen v textu. Identifikátor musí být umístěn na samostatné řádce.

Zpět do poradny Odpovědět na původní otázku Nahoru