<?php
// OPOZORILA: PROGRAM MORA BITI NUJNO POD IMENOM index.php IN POGANJATI SE MORA POD Apache 2, ki podpria RewriteEngine, Imeti moraš SQL uporabnika in bazo,
// .htaccess mora delati, potrebno je imeti dovoljenja za pisanje v mapo. .htaccess ob prvem zagonu ne sme
// obstajati, naredi se sam. NUJNO MORATE SKOPIRATI MAPO securimage iz phpcaptcha.org/download/ zraven index.php, drugače captcha ne bo delala.
// (C) 2019 Anton Šijanec.
// Uporaba dovoljena za učenje in za nekomercijalne namene, brez zaslužkov in z navedbo avtorja. Hvala!
// exit("Balkan ŠortLink je v pripravi. Pripravljen bo čez okoli 2 dni. Anton Šijanec, Projekt začet 20. januarja, predviden čas začetka obratovanja storitve
// je 23. januar 2019. Program bo odprtokoden in dostopen na mojem GitHubu, AstiriL!");
session_start();
clearstatcache();
// ini_set('display_errors', 'On'); // debug
// error_reporting(E_ALL); // debug
$nadaljuj = "ja";
include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
$securimage = new Securimage();
$verzija = "0.0.19.01.21";
$log .= "Verzija: " . $verzija . "\n";
// definicije - uporabniškega vnosa ne preverjam, zato si ne naredite sql vrivanja (angl. sql injection) ali vrinjanja skript (ni htmlchars sanitizacije).
// drugače pa je program dokaj varen prej vrivanjem... upajmo... vsi ostali uporabniški vnosi so sanitizirani.
$servername = "lol.u.though.i.will.show.a4l.space"; // domena, IP naslov oziroma ime gostitelja za dostop do MySQL ali ekvivalentne SQL podatkovne baze (strežnika)
$username = "nofreesqlforyou"; // uporabniško ime za dostop do strežnika SQL
$password = "donttrytoconnect"; // geslo za dostop do strežnika SQL
$baza = "itdoesntwork"; // podatkovna baza SQL v katero naj pišem - naredi jo pred zagonom programa
$tabela = "srslyitdoesnt"; // tabela, ki naj jo naredim v podatkovni bazi SQL oziroma tabela v podatkovni bazi SQL, ki naj jo uporabljam
$rxshort = "/^[0-9a-z]{1,6}$/"; // angleško regular expression, ki naj ga uporabim za kratek niz - nujno popravi še besedilne opise. Pusti ga takega, kot je!
$domena = "š.ga"; // tvoja domena
$captcha = "ja"; // ja/ne: ali naj uporabljam captcho? potrebujete phpcaptcha.org, mapo securimage skopirajte zraven index.php (tega programa).
// samoinštalacija - .htaccess ne sme obstajati ob prvem zagonu
if(!file_exists(".htaccess")) {
$htaccess = "
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?r=$1 [NC,L,QSA]
";
if(file_put_contents(".htaccess", $htaccess)) {
exit("Program je bil verjetno zagnan prvič. Izdelava .htaccess je uspela.\n");
} else {
$log .= "Program je bil zagnan verjetno prvič. Izdelava .htaccess ni uspela. Popravi dovoljenja mape.\n";
}
}
if($captcha !== "ne") {
if(!file_exists("securimage")) {
exit("securimage mapa z datotekami za captcho ne obstaja. Naložite jo iz phpcaptcha.org/download in jo postavite zraven index.php, ali pa spremenite
nastavitev captcha v konfiguracijah (definicije) iz ja na ne (ne priporočam).\n");
} else {
// okejjjjj
}
}
// sql povezava in izbira podatkovne baze
$conn = mysqli_connect($servername, $username, $password, $baza); // naredi povezavo
if (!$conn) { // preveri povezavo
die("<pre>Povezava v podatkovno bazo ni uspela. <!-- Razhroščevanje: " . mysqli_connect_error() . "-->\n</pre>");
}
$log .= "Povezava v podatkovno bazo uspešna.\n";
if(mysqli_select_db($conn,$baza)) {
$log .= "Izbira podatkovne baze uspešna.\n";
} else {
die("Podatkovne baze ni bilo mogoče izbrati. <!-- Razhroščevanje: " . mysqli_error($conn) . "-->\n");
}
//poglej če tabela links obstaja
$alitabelaobstaja = mysqli_query($conn, 'SELECT 1 from `'.$tabela.'`');
if($alitabelaobstaja !== FALSE) {
$log .= "Tabela v podatkovni bazi obstaja. Program je že bil v uporabi.\n";
} else {
// ne - naredi jo!
$log .= "Tabela v podatkovni bazi ne obstaja. Program je bil zagnan prvič. Poskusil jo bom narediti.\n";
$sql = "CREATE TABLE IF NOT EXISTS `".$tabela."` (
`short` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`long` text(767) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`short`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
if (mysqli_query($conn, $sql)) {
$log .= "Tabela v podatkovni bazi je bila uspešno narejena.\n";
} else {
die("<pre>Napaka v izdelavi tabele v podatkovni bazi! <!-- razhroščevanje: " . mysqli_error($conn) . "-->\n</pre>");
}
}
//če je potrebna preusmeritev (glej .htaccess, pa ti bo jasno)
if(!empty($_REQUEST['r'])) {
// preveri, če dolg niz že obstaja
$safer = mysqli_real_escape_string($conn, $_REQUEST['r']);
// echo $safer; //debug
$query = "SELECT `long` from `".$tabela."` where `short`='".$safer."';";
$result = mysqli_query($conn, $query);
echo mysqli_error($conn); //debug
if(mysqli_num_rows($result) > 0) {
// echo array_pop(mysqli_fetch_row($result); //debug //to je to!
$dolgkiobstaja = array_pop(mysqli_fetch_row($result)); //to je to!
// ŠortLink obstaja, preusmerjam!
header("Location: ".$dolgkiobstaja);
} else {
$log .= "Kratek URL še ne obstaja v podatkovni bazi.\n";
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka!</b> Kratek URL še ne obstaja v podatkovni bazi.
</div><br>";
}
}
// če je zahteva za vpis, vpiši!
if(!empty($_REQUEST['submit'])) {
$log .= "Obrazec je bil izpolnjen, začenjam preverjanje vnosa.";
if($captcha !== "ne") {
if ($securimage->check($_POST['captcha_code']) == false) {
$log .= "Preverjanje človeštva (CAPTCHA) je negativno. Mogoče niste človek, zato ne bom nadaljeval.";
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka preverjanja!</b> Preverjanje CAPTCHA je pokazalo negativni rezultat. Mogoče niste človek, zato ne bom nadaljeval.
</div><br>";
$nadaljuj = "ne";
} else {
$log .= "Preverjanje človeštva (CAPTCHA) je pozitivno. Človek ste.";
}
}
// regex match kratkega niza
if(preg_match($rxshort, $_REQUEST['short'])) {
$log .= "Preverjanje krajšalnega niza je pozitivno. Krajševalni niz se lahko uporabi.\n";
} else {
$log .= "Krajšalni niz se ne ujema z regexom " . $rxshort . ", zato ne bom nadaljeval.\n";
$nadaljuj = "ne";
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka vnosa!</b> Krajševalni niz se ne ujema z njegovimi pravili. Mora biti 1 do 6 znakov dolg in lahko vsebuje male črke in številke.
</div><br>";
}
// preverjanje, ce je res URL
if(filter_var($_REQUEST['long'], FILTER_VALIDATE_URL)) {
$log .= "Preverjanje dolgega URL-ja je pozitivno. Dolg URL se lahko uporabi.\n";
} else {
$log .= "Preverjanje dolgega URL-ja je negativno, zato ne bom nadeljeval.\n";
$nadaljuj = "ne";
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka vnosa!</b> Dolg URL se ne ujema z standardi. Poskusite ponovno.
</div><br>";
}
// preprecevanje sql prekoračitve
if(strlen($_REQUEST['long']) > 767) { //strlen pove bajte, mb_strlen pove dolžino niza
$log .= "Dolg URL je predolg. Mora biti krajši od 767 bajtov, drugače lahko pride do napak v podatkovni bazi.\n";
$nadaljuj = "ne";
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka vnosa!</b> URL je predolg. Mora biti krajši od 767 bajtov.
</div><br>"; //drugače lahko pride do napak v SQL bazi podatkov
} else {
$log .= "Dolg URL ni predolg. To je v redu.\n";
}
if($nadaljuj == "ja") { //nadaljuj z sql stvarmi, samo, če so zgornji pogoji zadostni
//preveri, če kratek niz že obstaja
$safeshort = mysqli_real_escape_string($conn, $_REQUEST['short']);
$query = "SELECT * from `".$tabela."` where `short`='".$safeshort."';";
$result = mysqli_query($conn, $query);
if(mysqli_num_rows($result) > 0) {
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka!</b> Krajšalni tekst že obstaja v podatkovni bazi. Izberite drugega.
</div><br>";
$log .= "Krajševalni tekst že obstaja v podatkovni bazi, zato ne morem nadaljevati.\n";
$nadaljuj = "ne";
} else {
$log .= "Krajševalni tekst še ne obstaja v podatkovni bazi. To je v redu.\n";
}
// preveri, če dolg niz že obstaja
$safelong = mysqli_real_escape_string($conn, $_REQUEST['long']);
$query = "SELECT `short` from `".$tabela."` where `long`='".$safelong."';";
$result = mysqli_query($conn, $query);
if(mysqli_num_rows($result) > 0) {
// echo array_pop(mysqli_fetch_row($result); //debug //to je to!
$kratekkiobstaja = array_pop(mysqli_fetch_row($result)); //to je to!
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka!</b> Dolg URL že obstaja v podatkovni bazi. Nanj kaže <b>".$domena."/".htmlspecialchars($kratekkiobstaja)."</b>
</div><br>";
$log .= "Dolg URL že obstaja v podatkovni bazi, zato ne morem nadaljevati.\n";
$nadaljuj = "ne";
} else {
$log .= "Dolg URL še ne obstaja v podatkovni bazi. To je v redu.\n";
}
/*
//idk ne dela -- v redu, vem zakaj: podpičje manjka! jaoooo in še `'" jaooooo sql nima ", ' je za nize, ` je za stolpce, tabele,...
$prepared = mysqli_prepare($conn, "SELECT * FROM ".$tabela." WHERE short=?");
// var_dump(mysqli_error($conn)); //debug
$binded = mysqli_stmt_bind_param($prepared, "s", $_REQUEST['short']);
// echo $binded; //debug
$executed = mysqli_stmt_execute($prepared);
echo $executed; //debug
$binded_result = mysqli_stmt_bind_result($prepared, $rezultat);
echo $rezultat; //debug
$fetched = mysqli_stmt_fetch($prepared);
echo $fetched; //debug
$result = mysqli_query($conn, $prepared);
echo mysqli_error($conn); //debug
if(mysqli_num_rows($result) == 0) {
$log .= "Krajševalni tekst še ne obstaja v podatkovni bazi. To je v redu.\n";
} else {
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka!</b> Krajšalni tekst že obstaja v podatkovni bazi. Izberite drugega.
</div><br>";
$log .= "Krajševalni tekst že obstaja v podatkovni bazi, zato ne morem nadaljevati.\n";
$nadaljuj = "ne";
}
//preverjanje, če krajševalni niz že obstaja
$prepared = mysqli_prepare($conn, "SELECT * FROM ".$tabela." WHERE long=?");
// echo mysqli_error($conn); //debug
mysqli_stmt_bind_param($prepared, "s", $_REQUEST['long']);
$result = mysqli_query($conn);
if(mysqli_num_rows($result) == 0) {
$log .= "Dolg URL še ne obstaja v podatkovni bazi. To je v redu.\n";
} else {
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Napaka!</b> Dolg URL že obstaja v podatkovni bazi. Nanj vodi <b>".$domena."/".htmlspecialchars($result)."</b>.
</div><br>";
$log .= "Dolg URL že obstaja v podatkovni bazi, zato ne morem nadaljevati. Nanj vodi ".$domena."/".htmlspecialchars($result).".\n";
$nadaljuj = "ne";
}
*/
}
if($nadaljuj !== "ja") {
$log .= "URL ni bil okrajšan. Glej napake zgoraj!";
} else {
$query = "INSERT INTO `".$tabela."` (`short`, `long`) VALUES ('".$safeshort."','".$safelong."');";
$result = mysqli_query($conn, $query);
// var_dump(mysqli_error($conn)); //debug
//preveri uspeh
$query = "SELECT * FROM `".$tabela."` WHERE `short`='".$safeshort."';";
$result = mysqli_query($conn, $query);
if(mysqli_num_rows($result) == 0) {
// var_dump(mysqli_error($conn)); //debug
$alert .= "<div class=alert>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Sistemska napaka!</b> Neznana napaka podatkovne baze.
</div><br>";
$log .= "Neznana napaka podatkovne baze. Glej sistemske dnevnike.\n";
} else {
$alert .= "<div class=alertok>
<span class=closebtn onclick=this.parentElement.style.display='none';>×</span>
<b>Uspešno!</b> Šortlink <b>".$domena."/".htmlspecialchars($_REQUEST['short'])."</b> je bil uspešno narejen!
</div><br>";
$log .= "Šortlink ".$domena."/".htmlspecialchars($_REQUEST['short'])." je bil uspešno narejen!\n";
}
}
} else {
$log .= "Obrazec ni bil izpolnjen, zato samo prikazujem stran.\n";
}
$print .= "
<style>
.alert {
opacity: 1;
transition: opacity 0.6s; /* 600ms za izgine */
}
/* Škatla z obvestilom */
.alert {
padding: 20px;
background-color: #f44336; /* Rdeča */
color: white;
margin-bottom: 15px;
}
.alertok {
padding: 20px;
background-color: #43f436; /* Zelena */
color: white;
margin-bottom: 15px;
}
/* Gumb za zapreti */
.closebtn {
margin-left: 15px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
/* Ko je miška pod gumbom za zapreti */
.closebtn:hover {
color: black;
}
</style>
<script>
// Dobi vse elemente z class=closebtn
var close = document.getElementsByClassName('closebtn');
var i;
// Pojdi čez vse gumbe za zapreti
for (i = 0; i < close.length; i++) {
// Ko je gumb kliknjen
close[i].onclick = function(){
// Dobi starša od <span class=closebtn> (<div class=alert>)
var div = this.parentElement;
// Nastavi -prosojnost div-a na 0 (prozorna)
div.style.opacity = 0;
// Skrij div po 600ms (Ko izgine, izginotje je definirano tudi v CSS-ju)
setTimeout(function(){ div.style.display = 'none'; }, 600);
}
}
</script>
";
$print .= "
<title>ŠortLink Balkan</title>
<h1 align=center>ŠortLink Balkan</h1>
<h2 align=center>Ste kdaj hoteli narediti iz dolgega linka ŠortLink tako, da bi izgledal bolj balkansko?</h2>
<h2 align=center>Tudi če niste, je tukaj ŠortLink Balkan, edini Link Šortener, namenjen predvsem slovanskim narodom,saj za njegovo uporabo potrebujete črko Š!</h2>
<h3 align=center>Vsi Šortani linki se bodo začeli z š.ga, na primer š.ga/tekst. Najs ane?</h3>
<div align=center>
<form method=POST action=''>
<input autocomplete=off type=url name=long placeholder='Vpiši dolg URL ...' required=required align=center><br>
".$domena."/<input autocomplete=off type=text name=short placeholder='Vpiši krajšalnico ...' required=required align=center><br>
<img id=captcha src=/securimage/securimage_show.php alt='Dostop samo ljudem. Prepiši znake iz slike, da potrdiš, da nisi program.' align=center /><br>
<input autocomplete=off placeholder='Prepiši znake ...' type=text name=captcha_code size=10 maxlength=6 align=center/><br>
<input autocomplete=off type=submit name=submit value=Skrajšaj! align=center>
</form>
<br><small align=center>
ŠortLink Balkan za svoje delovanje potrebuje in uporablja sejne piškotke. Z uporabo storitve se strinajte z shranjevanjem piškotkov
v vaš brskalnik za največ 24 minut. Piškotek se uporablja samo za interni namen, torej za to, da izvemo katere črke si imel na preverjanju za ljudi (CAPTCHA)
in nikakor ne za namene vohunjenja (tracking cookies). Piškotki so vidni samo na domeni š.ga, torej samo našemu strežniku. To sporočilo smo vam po veljavnem EU
zakonu morali pokazati, ker sta Hrvaška in Slovenija v Evropski Uniji in morata zato upoštevati te glupe zakone.
</small>
</div>
";
// $print .= "<h4 align=center>Ker še nisem sprogramiral, ŠortLink Balkan še ne deluje. Ne uporabljaj ga, ker ne bo nič naredil.</h4>"; // a je že?
echo "<pre>" . $log . "</pre>"; // zakomentiraj to vrstico, da dnevnika ne boš prikazal, ali pa samo naredi HTML komentar, da lahko v sili še vedno pogledaš
echo $print;
echo $alert;
?>