drupal

Symfony „vs” Drupal

Először is szeretném felhívni a figyelmet, hogy a címben jelzett versus idézőjelben van. A cikk pont arról szól, hogy az miért is van úgy írva.

Egy kedves ismerősömmel éppen a szegedi Networkshop 2017 konferenciáról visszafelé tartottunk Budapestre. Valamiről beszélgetni kellett, és igencsak jó téma került elő. A Symfony keretrendszerről kezdtünk beszélgetni, nem ismerte, de lelkes érdeklődő volt, sok-sok kérdéssel. Elmondtam neki mindent töviről hegyire. Elmondtam, hogy ez egy keretrendszer, ami azt jelenti, hogy telepítés után nem tud még semmit, magunknak kell megírni amit szeretnénk. Szóba került a Drupal is, tudja, hogy abban is otthon vagyok. Azt is elmondtam, hogy az meg egy tartalomkezelő, tehát már telepítés után is bőven van hova kattintgatni.

… És akkor feltette a nagy kérdést:

Hogyan lehet a Drupalt és a Symfonyt együtt használni, lehet-e egyáltalán keverni ezeket?

Már majdnem mondtam a standard választ, hogy hát az egyiket lehet telepíteni a másik alkönyvtárába, és akkor bizonyos URL-eket az egyik, a többit meg a másik fogja kiszolgálni. Persze ez nagyon messze van attól, hogy igazán egyszerre használjuk a kettőt. Ezt a fajta egymás mellett élést bármelyik két webes rendszerrel meg lehet tenni, teszem azt akár egy Rails-es alkalmazás és egy java SpringBoot-os alkalmazással is.

De …

… a Symfony és a Drupal ennél sokkal mélyebb integrációja is lehetséges, legalábbis akkor, ha Drupal alatt D8-at értünk. Kedves olvasó, van már ötleted, hogy mire akarok kilyukadni? Ha nincs, akkor mutatom a következő elképzelt „beszélgetést”:

– Hé, Te Symfony! Van ötleted, hogy a felhasználó milyen tartalmat kér most éppen rajtunk számon? Nesze, itt egy Request objektum, benne van az URL, a sütik, a böngésző típusa, és még vagy 28 millió másik dolog.

– Nekem aztán fogalmam sincs, itt egy 404-es Response objektum. Csak most, csak neked, nagy szeretettel.

– Hé, Te Drupal8! Neked csak van valami ötleted, hogy mit akarhat a user, ugye? Itt a Request objektum, tessék.

– Passz, fogalmam sincs. Tőlem is kapsz egy friss – ropogós, 404 Response-t.

– Na, te házilag barkácsolt FityfirityCMS, te már biztosan tudni fogod, hogy mit kér a user.

– Háááát biza`, ötletem az nekem sincs.

– Na jó, Laravel, utoljára téged még megkérdezlek! Neked már tényleg tudnod kéne, mi a fenét akarhat a user.

– Nekem van egy tippem, tessék itt egy Response. Van benne minden, HTTP fejlécek, tartalom, és még sok egyéb jóság. A változatosság kedvéért ez pont nem 404.

PSR-7

Amire utalni próbálok az a PSR-7 ereje. Arról van szó ugyanis, hogy okos emberek kitalálták, hogy legyen egy standard interfész, ami leír egy HTTP kérést és egy HTTP választ. És bármelyik rendszer, ami ezeket az interfészeket implementálja, az tud egymással érdemben kommunikálni, és el tudják dönteni egymás között például azt is, hogy egy adott kérést kinek kellene kiszolgálni. Erre volt egy példa, a fenti kis szösszenet.

Symfony HttpFoundation

A PSR-7 csak egy interface. A Symfony HttpFoundation pedig egy implementációja. Bár nem muszáj ezt használni, bárki újraimplementálhatja a PSR-7-et, csak éppen túl sok értelme nincs. Aki a saját kis keretrendszerét, tartalomkezelőjét, vagy akármilyen egyéb kis szkriptecskéjét úgy építi fel, hogy az a Symfony HttpFoundation-t használja a HTTP kérések és válaszok kezelésére, az alkalmas lesz becsatlakozni és együtt dolgozni minden olyan rendszerrel, ami hasonlóan tesz.

Nincs vége

A beszélgetésünk előtt is ismertem a PSR-7-et és a Symfony HttpFoundation-t, de ez a beszélgetés döbbentett rá ezek igazi erejére és hasznosságára. Ugyanis a történet nem áll meg ott, hogy URL alapján eldöntjük, hogy kinek kell kiszolgálni a kérést. A kooperáció ennél sokkal-sokkal komplexebb is lehet. El tudok képzelni például olyat, hogy a tartalmat a Drupal állítja elő, de az autentikációt a Symfony végzi. Majd az elkészült végleges Response válaszhoz, a saját kis fityfirity alkalmazásunk még hozzá tesz egy extra HTTP fejlécet, amiben a teljes tartalmat egy titkos kulccsal még aláírja. Mi is hallottunk már a HTTPS-ről, de tegyük most fel, hogy az nem elég, annál többet akarunk. És az egész elé még bedobunk egy gyors user sapce reverse proxy-t, amivel gyönyörűen felturbózzuk az alkalmazásunk sebességét. És mindezt okosan, tartalom és user függő módon, nem vagyunk kénytelenek kizárólag az URL-re és az időre hagyatkozni a gyorstárazható-e vagy sem kérdés eldöntésekor.

Összegezve tehát a PSR-7 szabvány és annak implementációja, a HttpFoundation segítségével képesek vagyunk arra, hogy egymástól független, akár egymásról nem is tudó alkalmazások összedolgozzanak azon, hogy a felhasználó által indított HTTP kérésre megszülessen egy válasz. A lehetőségek tárháza ezzel igencsak kitárul. Annak oka, hogy ez nincsen széles körben kihasználva, véleményem szerint mindössze azért van, mert a keretrendszerek és tartalomkezelő rendszerek önmagukban is elég eszközkészletet adnak ahhoz, az átlagos igényeket kielégítsék. De biztosan van olyan eset, amikor erre szükség lehet. Nekem például eszembe is jutott egy alkalmazási lehetőség, amire a Sztakiban biztosan lenne igény. De ez már egy másik mese.

További olvasnivaló:

MTA Sztaki: 1 év

Pontosan 1 évvel ezelőtt, 2013. április 22.-én kezdtem dolgozni az MTA Sztaki-ban. Magam sem gondoltam volna, hogy eddig húzom egy helyen :) De maradtam, mert jól érzem magam. Az elmúlt egy év sok különböző érdekes feladatot és számomra még ismeretlen technológiát tartogatott, így bőven volt kihívás és szakmai előrelépés is. Egyszóval mozgalmas év volt.

Jelenleg is keresünk tapasztalt vagy tanulni képes PHP és Java fejlesztőket, Drupal-os projekt is bőven. Részletekért Héder Michályt vagy Rigó Ernőt keressétek.

Drupal hétvége 2013

Bizony, lassan megint elérkezünk az évnek abba a szakaszába, amikor egy egész hétvégét a Drupalnak lehet szentelni. Idén november 16.-án és 17.-én kerül megrendezésre a konferencia. A tavalyi BME épület szerintem nagyon jól bevált, örülök hogy idén is ott lesz. Még nem végleges az program, de biztosan sok előadás fog szólni a készülő D8-ról, így aki érdekel mit hoz a közeljövő Drupal fronton, annak mindenképpen érdemes eljönni.

Drupal futtatása parancssorból (azaz CLI-ből)

Miért is akarjunk mi parancssorból Drupal-t futtatni? Például akkor hasznos ha egy import szkirptet írunk, ami nagyon sokáig is futhat. Vagy ha a futás kimenete olyan információ, amit aztán a linux parancssorból vagy egy bash scriptben akarunk felhasználni.

Oké, van nekünk Batch API-nk a hosszú futásokhoz, meg Drush is van a CLI-hez. De azért nézzük meg , mit tudunk kezdeni egy egyszerű php fájllal.

Először is érdemes belepillantani a Drupal index.php-ba, a cron.php-va, ha még nem tettük meg. Kiderül, hogy ezek faék egyszerű fájlok, így aztán innen fogunk puskázni.

Első naiv próbálkozás

Legyen a cli.php fájl tartalma ez:

<?php
define
('DRUPAL_ROOT', getcwd());
include_once
DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
?>

Futtassuk így:
# php cli.php

Rögtön kapunk is egy csomó hibát, mert nem létezik a REMOTE_ADDR kulcs egy tömbben. Ez a tömb nem lehet más, csak a $_SERVER. Érthető is, hiszen nem böngészőből hívjuk meg a scriptet. Javítsuk ezt a hibát azzal, hogy pótoljuk ezt az értéket.

<?php
$_SERVER
['REMOTE_ADDR'] = '127.0.0.1';
?>

Tegyünk egy kis óvintézkedést, és állítsuk le a szkript futását, ha nem parancssorból futtatjuk. Ezt így tehetjük meg:

<?php
if (php_sapi_name() !== 'cli') {
  exit(
1);
}
?>

Ezzel teljesen kizárjuk a webszervert, így a legtöbb biztonsági kockázatnak elejét vettük.

A teljes kód

Nos nagyjából ennyi, a teljes kód mindössze ennyi:

<?php
define
('DRUPAL_ROOT', getcwd());

if (
php_sapi_name() !== 'cli') {
  exit(
1);
}

$_SERVER['REMOTE_ADDR'] = '127.0.0.1';

include_once
DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
?>

Ezután bármit megtehetünk a kis php szkriptben. Például meghívhatunk egy hook-ot minden modulban így:

<?php
 module_invoke_all
('xmlrpc');
?>

Vagy bármely modul egy tetszőleges függvényét így:

<?php
 import_modulom_import_fuggvenye
();
?>

Fontos, hogy kinek a nevében fut!

Egy dologra viszont oda kell figyelni: a php-t futtató szerver felhasználó. Debian/Ubuntu rendszereken www-data az alapbeállítás, de szervertől függően ez bármi lehet. A fájlkezelés miatt fontos, ugyanis a fájlokat tartalmazó könyvtárban (pl.: sites/default/files) minden fájlnak a webszerver a tulajdonosa, ezzel lehet írni-olvasni a fájlokat. Ha mi egy másik felhasználó nevében futtatjuk a ki import php szkriptünket, ami mondjuk képeket is importál, akkor bizony az új vagy módosított fájloknak más lesz a tulajdonosa. És ez baj, mert akkor később a web-ről már nem tudjuk módosítani, vagy akár törölni ezeket.

Ezerféle módon megoldhatjuk ezt a problémát, a két legegyszerűbbet mutatom be.
Legjobb megoldás, ha a php-t a megfelelő felhasználó nevében futtatjuk. Ha pl. www-data nevében fut az Apache vagy másik webszerver, akkor így:

# sudo -u www-data php cli.php

Erre viszont nincs mindig lehetőség. Egyszerű, de nagyszerű megoldás az is, ha a cli.php futása után egyszerűen átadjuk a megfelelő felhasználónak a files könyvtár tartalmát:

# chown -R www-data sites/default/files

Ez az egész ötlet nekem egy importálás miatt kellett, és nagyon jól bevált. Remélem másnak is hasznos lesz.

Diff3 – az „elfelejtett” csodafegyver konfigurációs fájlok frissítésére

Nem tudom Ti hogy vagytok vele, de nekem bizony majd minden napra jut valamilyen használt eszköznek a verzió frissítése. Ez legtöbbször Drupal-t jelent, de van amikor Awstats-ot, phpMyAdmin-t, valami webmail scriptet, stb …

Namármost ezeknek a programoknak közös jellemzőjük, hogy van hozzájuk egy configurációs minta fájl, amit még a telepítéskor át kell nevezni és tesre kell szabni.

Frissítéskor a testreszabott, beállított konfig fájlokat természetesen nem írjuk felül, ezek érintetlenül maradnak. Igen ám, de az eredeti alapértelmezett konfigurációs fájlok néha megváltoznak, általában egy-egy új opcióval bővülnek, vagy csak a kommenteket egészítik ki a fejlesztők.

Szóval engem mindig is zavart, hogy a régi telepítések config fájljai nem követik az új verziók frissítéseit. Annyira zavart, hogy el is kezdtem megoldást keresni. És ahogy ez lenni szokott az open source világában, hamar kiderült, hogy másokban már sokkal korábban felmerült ez a probléma, sőt már réges régen meg is oldották. A programot ami segíteni fog nekünk elhárítani ezt a problémát, úgy hívják hogy diff3. A használati útmutatója (man page) teljesen világos, én most csak a fenti esetre kihegyezve mutatom be a paraméterezését.

A diff3 használata konfig fájlok összehasonlítására

Először ellenőrizzük, hogy nincs-e ütközés a módosításokban:

diff3 -x REGI_TESTRESZABOTT REGI_DEFAULT UJ_DEFAULT

-x paraméter után három fájlnevet vár, a régi testreszabott konfig fájl, a régi eredeti konfig fájl és az új eredeti fájl. Ha üres a parancs kimenete, akkor kell örülni, akkor nincs ütközés.

A fenti három fájl segítségével hozzuk létre az új konfig fájlt, amely tartalmazza mind a mi módosításainkat, mind pedig fejlesztők módosításait.

diff3 -m REGI_TESTRESZABOTT REGI_DEFAULT UJ_DEFAULT > UJ_TESTRESZABOTT

Ha az első lépésben volt ütközés, akkor az -m kapcsoló elvégzi a migrálást.

Ezek után én még egy sima diff-el ellenőrizni szoktam, hogy minden rendben ment-e, mondjuk így:

diff -y --suppress-common-lines UJ_DEFAULT UJ_TESTRESZABOTT

A kimenetből jól látszik, hogy az új konfigurációs fájlba átvezette a diff3 a régi változtatásokat.

The Drupal way

Az imént leírtak a default.settings.php és a settings.php-re vonatkoztak. De ugyanezt a módszert szoktam használni a .htaccess fájl és a robots.txt frissen tartására is.

Persze csak kis verzió ugrásnál, pl. 7.0-ról 7.1-re, főverzió ugrásnál, pl. 6.0-ról 7.0-ra, ennél azért több munkára lesz szükség :)

Másra is használható

Természetesen másra is használható a diff3: ha egy fájlt két külön irányba módosítanak, mert mondjuk ketten dolgoznak ugyanazon a forráskódon, akkor a diff3 egyszerűen összefésüli a módosításokat. Már amennyiben nincs közvetlen ütközés a módosítások között.

Oldalak

Feliratkozás RSS - drupal csatornájára