Biurokratyczne ciasteczka

Tak to jest gdy na siłę chce się ludziom pomagać. Wczorajszego dnia wszedł w życie nowy przepis wymuszający na każdym właścicielu strony umieszczenie na niej widocznej informacji dotyczącej ciasteczek.

Wraz z pojawieniem się tych przepisów pojawiło mi się kilka pytań.

  1. Czy powtarzana na każdej stronie informacja o ciasteczkach sprawi, że ludzie nie ogarnięci w internecie będą bardziej bezpieczni?
  2. Czy serwisy za każdym razem będą informować o wszystkich informacjach zapisywanych za pomocą ciasteczek czy będzie to tylko ogólna nformacja?
  3. Jak traktować iframe na stronie? Czy będzie ono traktowane za część naszej strony? Czy będzie ono brane za oddzielną stronę wyświetlaną w iframe? Jeżeli to pierwsze to informacja o ciasteczkach będzie mogła być „wspólna”, ale to oznaczało by, że serwisy takie jak wykop są właścicielami większości internetu. Jeżeli to drugie, to takie iframe powinny wyświetlać nam swoje powiadomienia…
  4. Czy nie powinno się wprowadzić podobnych przepisów które regulowały by używanie starodawnych awaryjnych przeglądarek (które to w praktyce jest groźniejsze od ciasteczek)?
  5. W końcu najważniejsze – jak będzie wyglądała egzekucja tego prawa i ile będzie kosztowała obsługa takiej egzekucji. Czy spowoduje to powstanie nowych stanowisk pracy w urzędach?

No cóż. Pewnie usłyszymy jeszcze nie jedną i nie dwie dyskusje na ten temat.
Zapewne za kilkanaście dni każdy użytkownik internetu będzie miał wykutą na pamięć regułkę, która będzie się pokazywać na każdej stronie. Może też za kilka dni powstanie stosowny „block” który będzie z automatu usuwał te mało przydatne popupy, bary i inne śmieci, albo pojawią się stosowne dodatki do przeglądarek – coś w stylu RSS?

W każdym bądź razie nas webmasterów powinien zainteresować zapis:

Art. 173 ust. 1 ustawy Prawo telekomunikacyjne

2. Abonent lub użytkownik końcowy może wyrazić zgodę, o której mowa w ust. 1 pkt 2, za pomocą ustawień oprogramowania zainstalowanego w wykorzystywanym przez niego telekomunikacyjnym urządzeniu końcowym lub konfiguracji usługi.

http://www.trustedshops.pl/wiadomosci/6691-nowe-przepisy-dotyczace-plikow-cookies-ciasteczka-cz-i.html

Jak wynika z powyższego zapisu, nie musimy dawać użytkownikowi możliwości wyboru czy chce używać ciasteczek czy nie. Wystarczy tylko pokazać stosowną informację (najczęściej z linkiem do podstrony, na której problem ciasteczek jest omówiony bardziej dogłębnie). Wyboru dokonujemy instalując przeglądarkę, lub zmieniając odpowiednie opcje w jej ustawieniach.

Kodujemy informacyjną belkę

Na koniec tego wątpliwego artykuliku stworzymy prostą belkę która przyklejona do góry ekranu będzie męczyć użytkowników.

<div class="cookie-bar">
     <div>
         W ramach naszej witryny stosujemy pliki cookies, aby ułatwić Ci korzystanie z naszego serwisu oraz do celów statystycznych i marketingowych. 
         Korzystanie z witryny bez zmiany ustawień dotyczących plików cookies oznacza zgodę na ich użycie oraz zapisanie w pamięci urządzenia. 
         Możesz samodzielnie zarządzać cookies i dokonać zmiany ustawień w swojej przeglądarce.<br>
         Więcej informacji w naszej <a href="#">Polityce prywatności</a>. 
     </div>
     <span title="Zamknij (ESC)">Zamknij</span>
</div>

Środkowy div służy do wycentrowania treści w poziomie, bo cały cookie-bar będzie rozciągał się na całą szerokość ekranu. Nasz pasek będzie miał stałą pozycję fixed, która dla mobilnych urządzeń przyjmie wartość relative (bo fixed tragicznie jest tam obsługiwana). I właściwie tyle co ciekawszych informacji.

Stylowanie dla naszej belki nie jest jakieś super trudne.

body {
     margin:0;
}
.cookie-bar {
    position:relative;
    background:#eee;
    overflow:hidden;
    box-shadow:inset 0 -1px 1px rgba(0, 0, 0, 0.2);
}
.cookie-bar > div {
    font:11px Arial, sans-serif;
    color:#444;
    max-width:960px;
    margin:10px auto;
    text-align:left;
    padding-left:10px;
    padding-right:100px;
}
.cookie-bar a {
    text-decoration:none;
    color:#1373cc;
    text-decoration:underline;
}
.cookie-bar .close {
    font:bold 12px/28px Arial, sans-serif;
    color:#fff;
    position:absolute;
    top:50%;
    margin-top:-15px;
    right:10px;
    cursor:pointer;
    background:#666;
    display:inline-block;
    border-radius:3px;
    height:30px;
    width:60px;
    display:block;
    text-align:center;
    -webkit-box-sizing:border-box;
    -moz-box-sizing:border-box;
    box-sizing:border-box;
}
.cookie-bar .close:hover {
    background:#555;
}

Dodatkowo dla urządzeń mobilnych zmieńmy nieco wyglad, tak by guzik zamykania był możliwy do trafienia paluchem, a belka miała pozycję relatywną:

@media only screen and (max-width: 400px) {
    .cookie-bar > div {
        padding-left:10px;
        padding-right:10px;
        margin:15px 0;
    }
    .cookie-bar .close {
        position:relative;
        display:block;
        width:96%;
        margin:5px 2%;
        top:0;
        right:0;
    }
}

Pokaż demo

Po stworzeniu wyglądu czeka nas najlepsza zabawa, czyli oskryptowanie tego dziadostwa. Co musimy zrobić? Po kliknięciu na przycisk OK chowamy naszą belkę, a po chowaniu ustawiamy… ciasteczko, które będzie w przyszłości określało, czy pozywać belkę czy nie.

Aby ustawić ciasteczko, musimy obsłużyć zapisywanie go w js. Hej! Już to kiedyś robiliśmy. Pamiętacie te przygody? Jak nie, to zapraszam do tego artykułu. Tym razem jesteśmy już na emeryturze i skorzystamy z gotowego pluginu do jQuery, którego cały kod wygląda tak:

$.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { //set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString();
        }

        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { //get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

Reszta skryptu jest już dziecinnie prosta.

function destroyCookie() {
     $('.cookie-bar').remove();
     $.cookie('hideCookieBar', 1, {expires: 100, path: '/'}); //na 100 dni
}

$(function() {
     //pokazujemy lub usuwamy belkę
     if ($.cookie('hideCookieBar')) {
          $('.cookie-bar').remove();
     } else {
          $('.cookie-bar').show();
     }

     //obsługa zamknięcia belki
     $(document).keyup(function(e) {
         e.preventDefault();
         if (e.keyCode == 27) {
             $('.cookie-bar .close').click();             
         }
     });

     $('.cookie-bar .close').on('click', function(e) {
         e.preventDefault();
         $(this).parents('.cookie-bar').animate({'top' : -100}, function() {
              destroyCookie();
         });
     });
})

Na początku wykonujemy wspomniane sprawdzenie i w zależności od niego pokazujemy lub usuwamy naszą belkę. Kolejna część to obsługa zamknięcia belki. Aby użytkownik miło wspominał naszą pracę, ułatwimy mu zamknięcie za pomocą obsługi klawisza ESC.

Zakładając ciasteczko pamiętajmy by użyć parametru path (patrz kod). Inaczej może być tak, że ciasteczka będą zakładane dla każdej z podstron z osobna.

W niektórych przypadkach potrzebne będzie także użycie parametru domain=”…”. Określa on domenę dla której zakładamy ciasteczka. Jeżeli na swojej stronie linkujesz do swoich podstron stosując linki z www i bez www, to zapewne będziesz musiał skorzystać z tego parametru. Więcej na ten temat dowiesz się pod tym linkiem: http://stackoverflow.com/questions/1062963/how-do-browser-cookie-domains-work

Wykrywanie ciasteczka w js możemy zamienić na odpowiednik w PHP:

<?php if (!isset($_COOKIE['cookieInfo'])): ?>
<div class="cookie-bar">
     <div>
         Na wielu stronach internetowych, także u nas, wykorzystywane są cookies (ciasteczka). Służą ona m.in. do tego, by ... <br>
         Nowe regulacje prawne zobowiązują nas do poinformowania Cię o tym w wyraźniejszy, niż dotąd, sposób.<br>
         Lorem ipsum poczytaj sobie o tym na naszej <a href="">polityce prywatności</a>
         <span title="Zamknij (ESC)">Zamknij</span>
     </div>
</div>
<?php endif; ?>

Zastosujemy tutaj „popupową technikę” mistrza Szamsona. Obługujemy więc zdarzenie keyup dla całego dokumentu i wykrywamy w nim kod klawisza. Po wykryciu odpowiedniego kodu (w naszym przypadku 27 czyli ESC) „klikamy” (czyli wywołujemy kliknięcie) na elemencie który zamyka popup:

$(document).keyup(function(e) {
     e.preventDefault();
     if (e.keyCode == 27) {
         $('.popup .close').click(); //wywołujemy poniższe zdarzenie
     }
});

$('.popup .close').on('click', function(e) {
    //...zamykamy popup - np:
    $(this).closest('.popup').fadeOut(function() {
       $(this).remove(); //po zniknięciu usuwamy popup
    });
});

Ot cała magiczna technika. W poprzednim skrypcie właśnie z niej korzystamy.

Oczywiście po zamknięciu belki musimy ustawić odpowiednie ciasteczko. Robi to dla nas funkcja destroyCookie() (nazwy funkcji zawsze powinny mówić nam co dana funkcja robi…). Jak będziesz testował powyższy skrypt lokalnie za pomocą Chrome (np z pulpitu), wtedy możesz mieć problem z zapisaniem ciasteczka. Dlatego lepiej jest przenieść testy na serwer lokalny albo zdalny. To tak nawiasem mówiąc…

I właściwie to tyle. Całość pracy możecie zobaczyć pod poniższym linkiem:

Pokaż demo

Tutaj możesz sobie ściągnąć gotowy kod, który po umieszczeniu na początku kodu strony wygeneruje ci powyższą belkę. Pamiętaj by zmienić ścieżki do linków oraz podłubać w samym tekście informacyjnym :)

Komentarze

  • Afn

    Ciekawi mnie podejście do użytkowników, którzy już zrezygnowali z ciasteczek. Czy pytanie o pozwolenie w przypadku, kiedy już nie wyrazili zgody przy każdym wejściu na witrynę nie jest zbyt uciążliwe? ;)

    • Krakers

      Spytaj tych co siedzą na stołkach Unijnych i wielce dbają o nasze interesy… Łatwo zauważyć że wszystkie mechanizmy działają tak że będą właśnie przeszkadzać bo jak ktoś ma wyłączoną akceptację cookies (czy świadomie wcześniej czy pod wpływem naszej [dez]informacji o takiej możliwości…) będzie zawsze te „balony” oglądać wchodząc na nasze strony… zaczynam się zastanawiać czy komuś z Unii właśnie chodzi by:

      1) wszystcy dla świętego spokoju włączyli akceptację by uniknąć tych „baloników” na większości stron, albo

      2) siostrzeniec, któregoś z urzędasów nie napisał programy blokującego „balony” a potrzebuje na nowy wóz więc mógłby zarobić na tym ;)

      ale to mniemania i dywaginacje i zboczenia w jednym :P

      Sprawa nadaje się do skierowania do Ciasteczkowego Potwora i tyle w temacie.

  • Ciekawe pytanie. Pierwsza myśl? Założenie ciasteczka i sprawdzenie jego istnienia. Nie istnieje? Znaczy to że nie chce – nie pokazujemy belki. Pytanie tylko czy zakładanie ciastka w przypadku gdy użytkownik tego nie chce to nie złamanie prawa?

  • Afn

    Jeśli chodzi o moją interpretacje zapisu: to użytkownik który za pomocą oprogramowania wyraża zgodę na zapis, jednocześnie nie musi być odpytywany o zgodę, a jedynie powiadomiony o sposobie wykorzystania plików oraz możliwości wyłączenia tej opcji w przeglądarce.
    Równoznaczne jest to z tym, że możemy przetestować możliwość zapisu ciasteczka. W przypadku nie powodzenia nie ma sensu informować użytkownika o możliwościach wyłączania ciasteczek. W tym przypadku przydatny będzie komunikat zamienny o udogodnieniach i jakie płyną z ich wykorzystania. Przyda się też alternatywna informacja jak włączyć pliki ciasteczek, aby strona działała poprawnie jeśli to konieczne.
    Co myślisz o takim podejściu „user-friendly” ?

  • Czyli robimy test. Jeżeli wypadnie pomyślnie informujemy usera o tym do czego wykorzystujemy ciasteczka. Jeżeli wypadnie negatywnie, informujemy że lepiej jak włączy, bo tylko na tym zyska. Jest to sensowne.

    Chociaż gdybym był prawnikiem to osobiście chciałbym wiedzieć czy ten początkowy test jest dozwolony gdy użytkownik nie wyraził zgody na ciasteczka (wyłączył ciasteczka).

  • Afn

    Jeśli wyłączył to przecież nie zapiszesz bo jego przeglądarka na to nie pozwoli. Czy w tym przypadku będzie próba popełnienia „przestępstwa/wykroczenia”? Sprawdziłem zagadnienie i istnieje możliwość sprawdzenia ustawień przeglądarki jeśli chodzi o zapis ciasteczek przed wyświetleniem komunikatu.
    Etap testu można jednak pominąć. Ciekawe jak wiele serwisów zadba o tego typu rozwiązania.

  • Pierwsza lepsza strona: http://forum.trojmiasto.pl/ Po co komu takie info i jaki jest jego cel? Biurokratycznie wracamy do czasów gdy strony informowały nas „ta strona najlepiej działa w rozdzielczości 1024”

  • Swoją drogą czemu nikt nie informuje o lokalnym schowku (local storage)?

  • Damian

    Mam problem z umieszczeniem tego na mojej stronie. Używam smarty templatów javascript i php no i nie wiem gdzie dokladnie ktore czesci skryptu mam gdzie umiescic a w dodatku strona posiada kilka jezykow, a wiec potrzebuje kod zmodyfikowac tak abym mogl klikajac na dany jezyk przeczytac go w nim.

  • kartofelek007

    Na samym końcu tekstu, tuż nad tym komentarzem jest mały link z gotowym kodem. Kopiuj, wklej w jakieś miejsce na swojej stronie cały kod. Nie musisz tego dzielić na części, bo i tak po akceptacji cały kod nie będzie się pokazywał. A co do tłumaczenia to już nie wiem jak tam masz zrobione.

  • Damian

    Tak, tyle że jak tak zrobię to paraliżuje mi całą stronę i jej nie pokazuje. Pliki cookies się „gryzą” a nie wiem jak to zmienić. Moja strona inruilwarenhuis.nl

  • kartofelek007

    Nie masz jquery dodanej, a i skrypt php ci przerobił na html (widać go w źródle).

  • Damian

    Kod mojej strony jest troche zbyt skomplikowany i sie gubie troche przez to. Oparty jest na php i poprzez smarta tworzy templata w html.

    Kod funkcji (includa) pisze w php w osobnym pliku a nastepnie na templacie te funkcje wykonuje i konwertuje na kod html calej strony.

  • kartofelek007

    Za pomocą samego JS możesz tak: http://pastebin.com/QMfbWZBr

    Ale jest lepsze i łatwiejsze rozwiązanie. NIE MUSISZ tego wstawiać na belkę na górze strony. Wystarczy, że wrzucisz stosowny kod w stopkę strony.

    • Musi to być w widoczym miejsu – czyli w stopce nie.

  • Damian

    Już się orientuje co jest nie tak. Oskryptowanie funkcji ciasteczka nie pasuje do mojej strony. U mnie ciasteczko na mojej stronie jest używane do przetrzymywaniu ustawień języka zawartości produktów koszyka itp. muszę to jakoś opatentować w funkcji inaczej.

    To skrypt mojej strony:

    Head.tpl.html

    {$page_title|default:”Baby warenhuis, Inruil warenhuis”}

    Inruilwarenhuis.nl gebruikt cookies, gebruik van cookies is vereist voor een goede werking van onze website, als u niet akkoord sluit de webpagina.

    OK

    {literal}

    function open_window(link,w,h) //opens new window

    {

    var win = „width=”+w+”,height=”+h+”,menubar=no,location=no,resizable=yes,scrollbars=yes”;

    newWin = window.open(link,’newWin’,win);

    newWin.focus();

    }

    function confirmDelete() //unsubscription confirmation

    {

    temp = window.confirm(‚{/literal}{$smarty.const.QUESTION_UNSUBSCRIBE}{literal}’);

    if (temp) //delete

    {

    window.location=”index.php?killuser=yes”;

    }

    }

    function validate_custinfo() //validate customer information

    {

    if (document.custinfo_form.first_name.value==”” || document.custinfo_form.last_name.value==””)

    {

    alert(„{/literal}{$smarty.const.ERROR_INPUT_NAME}{literal}”);

    return false;

    }

    if (document.custinfo_form.email.value==””)

    {

    alert(„{/literal}{$smarty.const.ERROR_INPUT_EMAIL}{literal}”);

    return false;

    }

    if (document.custinfo_form.country.value==””)

    {

    alert(„{/literal}{$smarty.const.ERROR_INPUT_COUNTRY}{literal}”);

    return false;

    }

    if (document.custinfo_form.zip.value==””)

    {

    alert(„{/literal}{$smarty.const.ERROR_INPUT_ZIP}{literal}”);

    return false;

    }

    if (document.custinfo_form.city.value==””)

    {

    alert(„{/literal}{$smarty.const.ERROR_INPUT_CITY}{literal}”);

    return false;

    }

    return true;

    }

    {/literal}

    head.php

    0)

    {

    $q = db_query(„SELECT name FROM „.CATEGORIES_TABLE.” WHERE categoryID0 and categoryID=’$categoryID'”) or die (db_error());

    $r = db_fetch_row($q);

    $page_title = str_replace(„””,”‚”,$r[0].” – „.CONF_SHOP_NAME);

    }

    else if (isset($productID) && $productID>0)

    {

    $q = db_query(„SELECT name FROM „.PRODUCTS_TABLE.” WHERE productID=’$productID'”) or die (db_error());

    $r = db_fetch_row($q);

    $page_title = str_replace(„””,”‚”,$r[0].” – „.CONF_SHOP_NAME);

    }

    else $page_title = CONF_SHOP_NAME;

    // META

    $r = array(); $r[0] = „”;

    if (isset($categoryID) && !isset($productID) && $categoryID>0)

    {

    $q = db_query(„SELECT name, description FROM „.CATEGORIES_TABLE.” WHERE categoryID0 and categoryID=’$categoryID'”) or die (db_error());

    $r = db_fetch_row($q);

    $page_meta = str_replace(„””,”‚”,$r[0].”, „.$r[1]);

    }

    else if (isset($productID) && $productID>0)

    {

    $q = db_query(„SELECT name, brief_description FROM „.PRODUCTS_TABLE.” WHERE productID=’$productID'”) or die (db_error());

    $r = db_fetch_row($q);

    $page_meta = str_replace(„””,”‚”,$r[0].”, „.$r[1]);

    }

    else $page_meta = CONF_SHOP_NAME.”, powered for Babywarenhuis”;

    $smarty->assign(„page_meta”,$page_meta);

    $smarty->assign(„page_title”,$page_title);

    ?>

    index.tpl.html

    {include file=”head.tpl.html”}

    {$smarty.const.LINK_TO_HOMEPAGE}

     

    {$smarty.const.STRING_PRICELIST}

     

    {$smarty.const.ADMIN_ABOUT_NL_PAGE}

     

    {$smarty.const.ADMIN_SHIPPING_NL_PAGE}

     

    {$smarty.const.ADMIN_CONTACT_NL_PAGE}

    {include file=”language.tpl.html”}

    {include file=”search_form.tpl.html”}

    {if $smarty.const.CONF_SHOW_ADD2CART eq 1}

    {$smarty.const.CART_TITLE}

    {include file=”shopping_cart_info.tpl.html”}

     

    {/if}

    {$smarty.const.ADMIN_CATALOG}

    {include file=”category_tree.tpl.html”}

    Meer benodigdheden voor de baby?

    Direct Contact

    0 107505916

    Wij streven naar een hoog service niveau!!

    Bezoeken:

    {include file=”$main_content_template”}

     

    Copyright © {$smarty.const.CONF_COPYRIGHT_YEAR} http://www.inruilwarenhuis.nl All rights reserved.

    {literal}

    if ( ! (navigator.userAgent.indexOf(‚Opera’) != -1) )

    {

    Nifty(„div.topmenu_notselected,div.topmenu_selected”,”top transparent”);

    Nifty(„td.topcorners”,”tl transparent”);

    var tt_layers= getElementsBySelector(„td.topcorners”);

    for(var k=0, len=tt_layers.length; k<len; k++)

    {

    tt_layers[k].parentNode.style.backgroundColor = "#e0e7ff";

    }

    Nifty("td.topcorners","tr transparent");

    Nifty("td.bottomcorners","bl transparent");

    var tt_layers= getElementsBySelector("td.bottomcorners");

    for(var k=0, len=tt_layers.length; k<len; k++)

    {

    tt_layers[k].parentNode.style.backgroundColor = "#e0e7ff";

    }

    Nifty("td.bottomcorners","br transparent");

    }

    {/literal}

    index.php

    <?php

    //core file

    ini_set("display_errors", "1");

    // ————————-INITIALIZATION—————————–//

    //make sure that URL does not contain something like index.php/?parameter1=1&… //

    //include core files

    include("./cfg/connect.inc.php");

    include("./includes/database/mysql.php");

    include("./cfg/general.inc.php");

    include("./cfg/appearence.inc.php");

    include("./cfg/appearence_details.inc.php");

    include("./cfg/functions.php");

    include("./cfg/category_functions.php");

    include("./cfg/language_list.php");

    session_start();

    ini_set("display_errors", "1");

    //init Smarty

    require 'smarty/smarty.class.php';

    $smarty = new Smarty; //core smarty object

    $smarty_mail = new Smarty; //for e-mails

    //select a new language?

    if (isset($_POST["new_language"]))

    {

    $_SESSION["current_language"] = $_POST["new_language"];

    }

    //current language session variable

    if (!isset($_SESSION["current_language"]) ||

    $_SESSION["current_language"] count($lang_list))

    $_SESSION[„current_language”] = 0; //set default language

    //include a language file

    if (isset($lang_list[$_SESSION[„current_language”]]) &&

    file_exists(„languages/”.$lang_list[$_SESSION[„current_language”]]->filename))

    {

    //include current language file

    include(„languages/”.$lang_list[$_SESSION[„current_language”]]->filename);

    }

    else

    {

    die(„ERROR: Couldn’t find language file!„);

    }

    //connect to the database

    db_connect(DB_HOST,DB_USER,DB_PASS) or die (db_error());

    db_select_db(DB_NAME) or die (db_error());

    //get currency ISO 3 code

    $currency_iso_3 = (defined(‚CONF_CURRENCY_ISO3’)) ? CONF_CURRENCY_ISO3 : „USD” ;

    $smarty->assign(„currency_iso_3”, $currency_iso_3);

    //load all categories to array $cats to avoid multiple DB queries (frequently used in future – but not always!)

    $cats = array();

    $i=0;

    $q = db_query(„SELECT categoryID, name, parent, products_count, description, picture FROM „.CATEGORIES_TABLE.” where categoryID0 ORDER BY name”) or die (db_error());

    while ($row = db_fetch_row($q))

    {

    $cats[$i++] = $row;

    }

    //set $categoryID

    if (isset($_GET[„categoryID”]) || isset($_POST[„categoryID”]))

    $categoryID = isset($_GET[„categoryID”]) ? $_GET[„categoryID”] : $_POST[„categoryID”];

    else $categoryID = 0;

    $categoryID = (int)$categoryID;

    //$productID

    if (!isset($_GET[„productID”]))

    {

    if (isset($_POST[„productID”]))

    {

    $productID = (int)$_POST[„productID”];

    }

    }

    else

    {

    $productID = (int)$_GET[„productID”];

    }

    //and different vars…

    if (isset($_GET[„register”]) || isset($_POST[„register”]))

    $register = isset($_GET[„register”]) ? $_GET[„register”] : $_POST[„register”];

    if (isset($_GET[„update_details”]) || isset($_POST[„update_details”]))

    $update_details = isset($_GET[„update_details”]) ? $_GET[„update_details”] : $_POST[„update_details”];

    if (isset($_GET[„order”]) || isset($_POST[„order”]))

    $order = isset($_GET[„order”]) ? $_GET[„order”] : $_POST[„order”];

    if (isset($_GET[„check_order”]) || isset($_POST[„check_order”]))

    $check_order = isset($_GET[„check_order”]) ? $_GET[„check_order”] : $_POST[„check_order”];

    if (isset($_GET[„proceed_ordering”]) || isset($_POST[„proceed_ordering”]))

    $proceed_ordering = isset($_GET[„proceed_ordering”]) ? $_GET[„proceed_ordering”] : $_POST[„proceed_ordering”];

    if (!isset($_SESSION[„vote_completed”])) $_SESSION[„vote_completed”] = array();

    //checking for proper $offset init

    $offset = isset($_GET[„offset”]) ? $_GET[„offset”] : 0;

    if ($offsettemplate_dir = $lang_list[$_SESSION[„current_language”]]->template_path;

    $smarty_mail->template_dir = $lang_list[$_SESSION[„current_language”]]->template_path.”/mail”;

    //assign core Smarty variables

    $smarty->assign(„lang_list”, $lang_list);

    $smarty->assign(„lang_list_count”, count($lang_list));

    if (isset($_SESSION[„current_language”])) $smarty->assign(„current_language”, $_SESSION[„current_language”]);

    // – following vars are used as hidden in the customer survey form

    $smarty->assign(„categoryID”, $categoryID);

    if (isset($productID)) $smarty->assign(„productID”, $productID);

    if (isset($_GET[„currency”])) $smarty->assign(„currency”, $_GET[„currency”]);

    if (isset($_GET[„user_details”])) $smarty->assign(„user_details”, $_GET[„user_details”]);

    if (isset($_GET[„aux_page”])) $smarty->assign(„aux_page”, $_GET[„aux_page”]);

    if (isset($_GET[„show_price”])) $smarty->assign(„show_price”, $_GET[„show_price”]);

    if (isset($_GET[„adv_search”])) $smarty->assign(„adv_search”, $_GET[„adv_search”]);

    if (isset($_GET[„searchstring”])) $smarty->assign(„searchstring”, $_GET[„searchstring”]);

    if (isset($register)) $smarty->assign(„register”, $register);

    if (isset($order)) $smarty->assign(„order”, $order);

    if (isset($check_order)) $smarty->assign(„check_order”, $check_order);

    //set defualt main_content template to homepage

    $smarty->assign(„main_content_template”, „home.tpl.html”);

    // includes all .php files from includes/ dir

    $includes_dir = opendir(„./includes”);

    while ( ($inc_file = readdir($includes_dir)) != false )

    if (strstr($inc_file,”.php”))

    {

    include(„./includes/$inc_file”);

    }

    // output:

    //security warnings!

    if (file_exists(„./install.php”))

    {

    echo „”.WARNING_DELETE_INSTALL_PHP.””;

    }

    if (file_exists(„./forgot_password.php”))

    {

    echo „”.WARNING_DELETE_FORGOTPW_PHP.””;

    }

    if (!is_writable(„./products_pictures”) || !is_writable(„./templates_c”))

    {

    echo „”.WARNING_WRONG_CHMOD.””;

    }

    //show administrative mode link if logged in as administrator

    include(„./checklogin.php”);

    if (isset($_SESSION[„log”]) && isset($_SESSION[„pass”]))

    echo „„.ADMINISTRATE_LINK.”„;

    //show Smarty output

    $smarty->display($lang_list[$_SESSION[„current_language”]]->template_path.”index.tpl.html”);

    ?>

  • atp

    Niefajne jest to, że chodząc po podstronach jakiegoś serwisu z powyższym skryptem, na każdej stronie trzeba klikać „ok” ;)

  • Takie ostrzeżenie musi być, gdy się wykorzystuje jakiekolwiek technologie do przechowywani danych na urządzeniu, w tym Local Storage, czy inne.
    To, jak traktować IFRAME – to się liczy, jakby to była część strony. Jeśli jednak jakieś ciasteczko jest niezbędne – może ono zostać „zasadzone” bez ostrzeżenia.

  • Marcin

    mm