Do našeho e-shopu přidáme zamykání záznamů pro případ, kdyby jeden záznam potřebovalo upravovat více uživatelů najednou. Dále se naučíme pracovat s některými funkcemi pro datum a čas a naučíme se přihlásit se do aplikace pomocí Facebooku (OAuth protokol).
- https://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/TransactionJTA_Overview-Pessimistic_and_optimistic_locking.html - optimistické vs pesimistické zamykání (optimistic vs pessimistic lock)
- http://www.iso.org/iso/home/standards/iso8601.htm - ISO 8601 - Date and time format
- https://www.ietf.org/rfc/rfc0822.txt - RFC 822 - STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
- https://www.ietf.org/rfc/rfc850.txt - RFC 850 - Standard for Interchange of USENET Messages (obsolete)
- https://www.ietf.org/rfc/rfc1036.txt - RFC 1036 - Standard for Interchange of USENET Messages
- https://www.ietf.org/rfc/rfc1123.txt - RFC 1123 - Requirements for Internet Hosts -- Application and Support
- https://www.ietf.org/rfc/rfc2822.txt - RFC 2822 - Internet Message Format
- https://www.ietf.org/rfc/rfc3339.txt - RFC 3339 - Date and Time on the Internet: Timestamps
- http://dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html - výchozí inicializace datového typu timestamp v MySQL.
- http://php.net/manual/en/intro.datetime.php - úvod do práce s datem/časem v PHP.
- http://php.net/manual/en/function.date.php - funkce date.
- http://php.net/manual/en/function.date-default-timezone-set.php - nastavení default časové zóny
- http://php.net/manual/en/ref.datetime.php - funkce pro práci s datem/časem v PHP.
- http://php.net/manual/en/class.dateinterval.php - práce s intervaly data/času v PHP.
- http://php.net/manual/en/timezones.php - podporované časové zóny v PHP (naše je Europe/Prague)
- http://php.net/manual/en/datetime.add.php - sčítání data a času
- http://php.net/manual/en/function.date-create.php - vytvoření objektu data a času
- http://php.net/manual/en/function.date-interval-create-from-date-string.php - vytvoření intervalu (objekt pro sčítání k objektu data/času) z řetězce
- http://php.net/manual/en/function.time.php - aktuální čas
- Facebook PHP SDK: https://developers.facebook.com/docs/reference/php
- Facebook PHP SDK, přihlášení přes OAuth: https://developers.facebook.com/docs/php/howto/example_facebook_login
Vytvořte na serveru eso.vse.cz ve vaší MySQL databázi tabulku goods (zboží) a users (uživatelé). Oproti minulým příkladům má tabulka goods 3 nové sloupce pro optimické/pesimistické zamykání: last_updated_at, last_edit_starts_at a last_edit_starts_by_id.
Naplňte vytvořenou tabulku testovacími daty. Testovací data lze vygenerovat např. aplikací http://www.generatedata.com/
Pro práci s DB budeme opět používat třídu PDO, která je abstraktním objektem nad jakoukoli databází:
Nezapomeňte v souboru nastavit váš xname a heslo pro připojení do db!
Zkopírujte scripty z adresáře 09-data do vašeho adresáře na serveru eso.vse.cz.
Funkční aplikaci pak najdete na adrese:
https://eso.vse.cz/~xhraj18/ (použijte váš vlastní xname :)
Případy užití:
Poznámka: pro jednoduchost jsme zrušili přístup pro admina, vyžadujeme jen přihlášeného uživatele.
Část pro nepřihlášeného uživatele/databázová autentizace:
Část pro přihlášeného uživatele:
- new - přidání nového zboží do e-shopu.
- delete - smazání zboží z e-shopu.
- index - výpis zboží v e-shopu.
- buy - přidání zboží do košíku.
- cart - výpis zboží přidaného do košíku.
- remove - smazání zboží z košíku.
- signout - odhlášení uživatele.
Části pro přihlášeného uživatele relevantní pro toto cvičení:
- update optimistic - optimistic lock
- update pessimistic - pessimistic lock
-
Optimistic lock = optimistické zamykání - více uživatelů může začít měnit stejný záznam, ale předpokládáme, že nakonec se záznam nezmění. Při uložení zkontrolujeme čas poslední aktualizace a pokud se změnil od doby, kdy jsme začali záznam editovat (=záznam byl v mezičase upraven někým jiným), nepovolíme uložení. Není velký overkill pro systém. Má smysl v případě, pokud víme, že uživatelé začnou úpravu záznamu, ale většinou nakonec nic nezmění (záznamy se mění jen sporadicky). Viz soubor update optimistic.
-
Pessimistic lock = pesimistické zamykání - při začátku editace záznamu zamkneme záznam pro všechny ostatní uživatele. Ostatní uživatelé musí počkat, než dokončíme editaci. Velký overkill pro systém. Má smysl v případě, že většina pokusů o úpravu záznamu skončí jeho změnou (záznamy se aktualizují často). Viz soubor update pessimistic.
-
Otázky:
- Jaký způsob zamykání byste zvolili pro vaši semestrální práci (pokud již máte téma) a proč?
- Musíme zamykání záznamů použít vždy? Kdy ano a kdy ne?
- Jak se dá vyřešit v aplikaci konflikt v případě použití optimistického zámku? Jak se může aplikace zachovat?
- Ukázka optimistického zamykání update optimistic používá předání data a času poslední editace přes formulářové hidden pole last_updated_at. Tato data však mohou být při odeslání formuláře změněna/podstrčena uživatelem. Jak se jde proti tomu bránit? Má smysl to ošetřovat? Kdy ano/ne?
- Před voláním PHP funkcí pro datum a čas musíme nastavit časovou zónu, jinak PHP bude vyhazovat varování - buď funkcí date_default_timezone_set, nebo INI nastavením date.timezone (viz soubor .htaccess a nastavení php_value date.timezone 'Europe/Prague', případně globálně v souboru php.ini.
- Konstanty standardů a formátů pro datum a čas, viz http://php.net/manual/en/class.datetime.php, primární zdroje na standardy viz zdroje nahoře, popř. Google ;)
- DATE_ATOM - Atom (example: 2005-08-15T15:52:01+00:00), formát Y-m-d\TH:i:sP
- DATE_COOKIE - HTTP Cookies (example: Monday, 15-Aug-2005 15:52:01 UTC), formát l, d-M-Y H:i:s T
- DATE_ISO8601 - ISO-8601 (example: 2005-08-15T15:52:01+0000), formát Y-m-d\TH:i:sO
- DATE_RFC822 - RFC 822 (example: Mon, 15 Aug 05 15:52:01 +0000), formát D, d M y H:i:s O
- DATE_RFC850 - RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC), formát l, d-M-y H:i:s T
- DATE_RFC1036 - RFC 1036 (example: Mon, 15 Aug 05 15:52:01 +0000), formát D, d M y H:i:s O
- DATE_RFC1123 - RFC 1123 (example: Mon, 15 Aug 2005 15:52:01 +0000), formát D, d M Y H:i:s O
- DATE_RFC2822 - RFC 2822 (example: Mon, 15 Aug 2005 15:52:01 +0000), formát D, d M Y H:i:s O
- DATE_RFC3339 - RFC 3339 (example: 2005-08-15T15:52:01+00:00) - stejný formát jako ATOM
- DATE_RSS - RSS (example: Mon, 15 Aug 2005 15:52:01 +0000), formát D, d M Y H:i:s O
- DATE_W3C - World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00), formát Y-m-d\TH:i:sP
- ukázky použití funkcí pro datum a čas
- class DateTime
- Registrujeme naši aplikaci u Facebooku: Facebook/v levé záložce Developer/Manage Apps/zelené tlačítko Add a New App/typ Website/napsat název aplikace a vyplnit kontaktní údaje, (není to testovací aplikace)/tlačítko Skip Quick Start a získat klíče:
- app-id (id naší aplikace)
- app-secret (tajný klíč k naší aplikaci)
- Tyto klíče nastavíme v souborech 09-facebook/login.php a 09-facebook/fb-callback.php.
- Stáhneme si Facebook PHP SDK z https://github.com/facebook/facebook-php-sdk-v4/archive/5.0.0.zip a rozbalíme do web rootu naší aplikace, ukázka viz adresář 09-facebook.
- V našem scriptu si vyžádáme autoloader, který registruje potřebné soubory:
require_once __DIR__ . './facebook-php-sdk-v4-5.0.0/src/Facebook/autoload.php';
- Pošleme uživatele na Facebook pro autentizační klíč (pokud uživatel není do Facebooku přihlášen, musí se nejdříve přihlásit).
- Facebook si vyžádá souhlas s autentizací uživatele.
- Pokud uživatel souhlasil, Facebook zavolá nazpět námi předanou URL (callback URL) společně s tokenem (řetězcem s omezenou platností), který lze použít pro další komunikaci s Facebookem (získání dat o uživateli, apod.).
- Viz Facebook login a Facebook callback.
- Funkční ukázka k dispozici na http://eso.vse.cz/~xhraj18/09-facebook/login.php
- Upravte řešení optimistického zamykání záznamů v ukázkové aplikaci pro 9. cvičení tak, aby aplikace při zjištění konfliktu zobrazila změněná data a zeptala se uživatele, zda si je přeje přepsat daty svými.
- (Obtížnější) Přidejte do našeho e-shopu přihlášení pomocí Facebooku (nutno přes Graph API Facebooku získat email uživatele, viz https://developers.facebook.com/docs/reference/php).