PHP hook, building hooks in your application
Introduction
One of the real challenges in building any type of framework, core or application is making it possible for the developers to hook into the business logic at specific points. Since PHP is not event based, nor it works with interrupts you have to come up an alternative.
The test case
Lets assume we are the main developers of a webshop framework. Programmers can use our framework to build complete webshops. Programmers can manage the orders that are placed on the webshop with the order class. The order class is part of our framework and we don’t want it to be extended by any programmer. However we don’t want to limit to programmers in their possibilities to hook into the orders process.
For example programmers should be able to send an email to the webshopowner if an order changes from one specific delivery status to another. This functionality is not part of the default behavior in our framework and is custom for the progammers webshop implementation.
Like said before, PHP doesn’t provide interrupts or real events so we need to come up with another way to implement hooks into our application. Lets take a look at the observer pattern.
Implementing the Observer pattern
The observer pattern is a design-pattern that describes a way for objects to be notified to specific state-changes in objects of the application.
For the first implementation we can use SPL. The SPL provides in two simple objects:
SPLSubject
- attach (new observer to attach)
- detach (existing observer to detach)
- notify (notify all observers)
SPLObserver
- update (Called from the subject (i.e. when it’s value has changed).
iOrderRef = $iOrderRef;
// Get order information from the database or an other resources
$this->iStatus = Order::STATUS_SHIPPED;
}
/**
* Attach an observer
*
* @param SplObserver $oObserver
* @return void
*/
public function attach(SplObserver $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (isset($this->aObservers[$sHash])) {
throw new Exception('Observer is already attached');
}
$this->aObservers[$sHash] = $oObserver;
}
/**
* Detach observer
*
* @param SplObserver $oObserver
* @return void
*/
public function detach(SplObserver $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (!isset($this->aObservers[$sHash])) {
throw new Exception('Observer not attached');
}
unset($this->aObservers[$sHash]);
}
/**
* Notify the attached observers
*
* @param string $sEvent, name of the event
* @param mixed $mData, optional data that is not directly available for the observers
* @return void
*/
public function notify()
{
foreach ($this->aObservers as $oObserver) {
try {
$oObserver->update($this);
} catch(Exception $e) {
}
}
}
/**
* Add an order
*
* @param array $aOrder
* @return void
*/
public function delete()
{
$this->notify();
}
/**
* Return the order reference number
*
* @return int
*/
public function getRef()
{
return $this->iOrderRef;
}
/**
* Return the current order status
*
* @return int
*/
public function getStatus()
{
return $this->iStatus;
}
/**
* Update the order status
*/
public function updateStatus($iStatus)
{
$this->notify();
// ...
$this->iStatus = $iStatus;
// ...
$this->notify();
}
}
/**
* Order status handler, observer that sends an email to secretary
* if the status of an order changes from shipped to delivered, so the
* secratary can make a phone call to our customer to ask for his opinion about the service
*
* @package Shop
*/
class OrderStatusHandler implements SplObserver
{
/**
* Previous orderstatus
* @var int
*/
protected $iPreviousOrderStatus;
/**
* Current orderstatus
* @var int
*/
protected $iCurrentOrderStatus;
/**
* Update, called by the observable object order
*
* @param Observable_Interface $oSubject
* @param string $sEvent
* @param mixed $mData
* @return void
*/
public function update(SplSubject $oSubject)
{
if(!$oSubject instanceof Order) {
return;
}
if(is_null($this->iPreviousOrderStatus)) {
$this->iPreviousOrderStatus = $oSubject->getStatus();
} else {
$this->iCurrentOrderStatus = $oSubject->getStatus();
if($this->iPreviousOrderStatus === Order::STATUS_SHIPPED && $this->iCurrentOrderStatus === Order::STATUS_DELIVERED) {
$sSubject = sprintf('Order number %d is shipped', $oSubject->getRef());
//mail('secratary@example.com', 'Order number %d is shipped', 'Text');
echo 'Mail sended to the secratary to help her remember to call our customer for a survey.';
}
}
}
}
$oOrder = new Order(26012011);
$oOrder->attach(new OrderStatusHandler());
$oOrder->updateStatus(Order::STATUS_DELIVERED);
$oOrder->delete();
?>
There are several problems with the implementation above. To most important disadvantage is that we have only one update method in our observer. In this update method we don’t know when and why we are getting notified, just that something happened. We should keep track of everything that happens in the subject. (Or use debug_backtrace… just joking, don’t even think about using it that way ever!).
Taking it a step further, events
Lets take a look at the next example, we will extend the Observer implementation with some an additional parameter for the eventname that occured.
Finishing up, optional data
iOrderRef = $iOrderRef;
// Get order information from the database or something else...
$this->iStatus = Order::STATUS_SHIPPED;
}
/**
* Attach an observer
*
* @param Observer_Interface $oObserver
* @return void
*/
public function attachObserver(Observer_Interface $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (isset($this->aObservers[$sHash])) {
throw new Exception('Observer is already attached');
}
$this->aObservers[$sHash] = $oObserver;
}
/**
* Detach observer
*
* @param Observer_Interface $oObserver
* @return void
*/
public function detachObserver(Observer_Interface $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (!isset($this->aObservers[$sHash])) {
throw new Exception('Observer not attached');
}
unset($this->aObservers[$sHash]);
}
/**
* Notify the attached observers
*
* @param string $sEvent, name of the event
* @param mixed $mData, optional data that is not directly available for the observers
* @return void
*/
public function notifyObserver($sEvent, $mData=null)
{
foreach ($this->aObservers as $oObserver) {
try {
$oObserver->update($this, $sEvent, $mData);
} catch(Exception $e) {
}
}
}
/**
* Add an order
*
* @param array $aOrder
* @return void
*/
public function add($aOrder = array())
{
$this->notifyObserver('onAdd');
}
/**
* Return the order reference number
*
* @return int
*/
public function getRef()
{
return $this->iOrderRef;
}
/**
* Return the current order status
*
* @return int
*/
public function getStatus()
{
return $this->iStatus;
}
/**
* Update the order status
*/
public function updateStatus($iStatus)
{
$this->notifyObserver('onBeforeUpdateStatus');
// ...
$this->iStatus = $iStatus;
// ...
$this->notifyObserver('onAfterUpdateStatus');
}
}
/**
* Order status handler, observer that sends an email to secretary
* if the status of an order changes from shipped to delivered, so the
* secratary can make a phone call to our customer to ask for his opinion about the service
*
* @package Shop
*/
class OrderStatusHandler implements Observer_Interface
{
protected $iPreviousOrderStatus;
protected $iCurrentOrderStatus;
/**
* Update, called by the observable object order
*
* @param Observable_Interface $oObservable
* @param string $sEvent
* @param mixed $mData
* @return void
*/
public function update(Observable_Interface $oObservable, $sEvent, $mData=null)
{
if(!$oObservable instanceof Order) {
return;
}
switch($sEvent) {
case 'onBeforeUpdateStatus':
$this->iPreviousOrderStatus = $oObservable->getStatus();
return;
case 'onAfterUpdateStatus':
$this->iCurrentOrderStatus = $oObservable->getStatus();
if($this->iPreviousOrderStatus === Order::STATUS_SHIPPED && $this->iCurrentOrderStatus === Order::STATUS_DELIVERED) {
$sSubject = sprintf('Order number %d is shipped', $oObservable->getRef());
//mail('secratary@example.com', 'Order number %d is shipped', 'Text');
echo 'Mail sended to the secratary to help her remember to call our customer for a survey.';
}
}
}
}
$oOrder = new Order(26012011);
$oOrder->attachObserver(new OrderStatusHandler());
$oOrder->updateStatus(Order::STATUS_DELIVERED);
$oOrder->add();
?>
Now we are able to take action on different events that occur.
Disadvantages
Although this implementation works quite well there are some drawbacks. One of those drawbacks is that we need to dispatch an event in our framework, if we don’t programmers can’t hook into our application. Triggering events everywhere give us a small performance penalty however I do think this way of working gives the programmers a nice way to hook into your application on those spots that you want them to hook in.
Just for the record
Notice that this code is just an example and can still use some improvements, for example: each observer is initialized even it will maybe never be notified, therefore I suggest to make use of lazy in some cases for loading the objects. There are other systems to hook into an application, more to follow!
kraken market Kraken market – это шумный восточный базар, перенесенный в виртуальную реальность. Здесь можно найти всё, что угодно, от редких артефактов до запрещённых веществ. Однако, не стоит терять голову от разнообразия предложений и низких цен. Внимательно изучайте отзывы о продавцах, проверяйте информацию о товарах и не стесняйтесь задавать вопросы. Только так вы сможете совершить выгодную и безопасную сделку, избежав разочарований и проблем с законом. Будьте мудрыми и предусмотрительными, и Kraken market откроет перед вами свои сокровища.
Kevinmoots
29 Oct 25 at 5:39 am
кракен vk4
kraken обмен
Henryamerb
29 Oct 25 at 5:41 am
купить диплом университета [url=www.rudik-diplom14.ru/]купить диплом университета[/url] .
Diplomi_pkea
29 Oct 25 at 5:42 am
глубокий комлексный аудит сайта [url=www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_kgPi
29 Oct 25 at 5:46 am
dreambelieveachieve.shop – Perfect name for a site that spreads optimism and motivation daily.
Sunni Roppolo
29 Oct 25 at 5:46 am
кракен ссылка
kraken darknet market
Henryamerb
29 Oct 25 at 5:47 am
We are a group of volunteers and opening a new scheme
in our community. Your website provided us with valuable info to work on. You have done an impressive job
and our entire community will be thankful to you.
casino på nett
29 Oct 25 at 5:47 am
Oh dear, minus solid maths in Junior College, no matter leading institution kids mіght stumble at
next-level calculations, tһսs cultivate that promptly leh.
Anglo-Chinese Junior College stands аs a beacon ᧐f balanced education,
blending extensive academics ᴡith а supporting Christian principles tһat inspires moral stability
ɑnd individual development. Тhe college’s cutting edge facilities аnd skilled faculty assistance impressive efficiency іn bоth
arts ɑnd sciences, ԝith students ߋften accomplishing toρ awards.
Thгough its emphasis on sports and carrying оut
arts, trainees establish discipline, sociability, ɑnd
ɑn enthusiasm for quality ƅeyond the class. International partnerships and exchange opportnities
enhance tһe learning experience,fostering global awareness аnd cultural appreciation.
Alumni flourish іn diverse fields, testimony to the college’ѕ function in forming principled leaders prepared tо
contribute favorably tⲟ society.
Anglo-Chinese Junior College functions аs an excellent design of holistic education, flawlessly integrating а
challenging scholastic curriculum ᴡith а compassionate Christian structure that nurtures ethical worths, ethical decision-mаking,
and a sense оf purpose in every trainee. Thе college is
geared up with cutting-edge facilities, consisting оf contemporary lecture theaters, well-resourced art studios, ɑnd һigh-performance sports complexes,
ѡhere experienced teachers assist students t᧐ accomplish exceptional lead tο disciplines ranging fгom the
humanities to thе sciences, οften erning national аnd international awards.
Students аrе encouraged tο takе part in a abundant range of aftеr-school activities, ѕuch аѕ competitive sports teams tһat construct
physical endurance and team spirit, ɑⅼong with performing arts ensembles tһаt cultivate creative expression аnd cultural appreciation, ɑll contributing
tо а balanced lifestyle filled ԝith passion and discipline.
Through tactical worldwide collaborations, consisting ᧐f student exchange programs ѡith partner
schools abroad ɑnd participation in international conferences, tһe college instills ɑ
deep understanding of varied cultures аnd global
concerns, preparing learners tօ browse an increasingly interconnected
wⲟrld with grace and insight. Тhe remarkable performance history of іts alumni,
wһo excel іn leadership functions ɑcross markets ⅼike business,
medication, ɑnd the arts, highlights Anglo-Chinese Junior College’ѕ extensive impact
іn developing principled, innovative leaders ᴡho make
favorable effect on society ɑt biɡ.
Oh dear, ѡithout strong mathematics аt Junior College, no matter tߋp school youngsters ϲould struggle witһ
higһ school equations, thеrefore build it noᴡ leh.
Listen ᥙp, Singapore moms ɑnd dads, math proves ⅼikely the
most importɑnt primary topic, promoting imagination fօr рroblem-solving fоr groundbreaking careers.
Ɗon’t play play lah, link а excellent Junior College ѡith math superiority fօr assure
elevated A Levels scores аs well аs smooth transitions.
Օh dear, lacking strong maths at Junior College, evеn prestigious establishment youngsters could falter at secondary equations, tһerefore build іt now
leh.
Ꮤithout solid Α-levels, alternative paths аre longeг and harder.
Ɗo not play pay lah, pair ɑ excellent Junior College ѡith math proficiency
in order to ensure higһ A Levels marks аnd seamless shifts.
Mums and Dads,worry about the disparity hor, mathematics base гemains essential
Ԁuring Junior College іn comprehending data, crucial
inn current online market.
Check օut mү webpage – math Tuition fоr ib students (ethiofarmers.com)
ethiofarmers.com
29 Oct 25 at 5:47 am
acheter Kamagra en ligne: VitaHomme – Kamagra livraison rapide en France
RobertJuike
29 Oct 25 at 5:48 am
Давно работаю с чемиком. https://tuningclass.ru В-общем среднестаьистический вечер пятницы обычного одинокого ITшного инженера 😉
Aaronbamib
29 Oct 25 at 5:49 am
Hurrah, that’s what I was exploring for, what a data! present here
at this web site, thanks admin of this web site.
See details
29 Oct 25 at 5:52 am
Wow, this article is fastidious, my younger sister
is analyzing these things, thus I am going to let know
her.
비아그라 판매하는곳
29 Oct 25 at 5:52 am
I’ll right away grab your rss as I can not find your email subscription hyperlink or newsletter
service. Do you’ve any? Kindly permit me recognize so that I may just subscribe.
Thanks.
stripchat unlimited coins mod apk
29 Oct 25 at 5:53 am
раскрутка сайта франция [url=https://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/]https://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/[/url] .
optimizaciya i seo prodvijenie saitov moskva_idPi
29 Oct 25 at 5:53 am
It is in point of fact a nice and helpful piece of information.
I am glad that you just shared this useful
info with us. Please keep us up to date like this.
Thanks for sharing.
Blue Medical Spa
29 Oct 25 at 5:54 am
Mighty Dogg Roofing
Reimer Drive North 13768
Maple Grove, MN 55311 United Ѕtates
(763) 280-5115
Comprehensive Gutter Cleaning Programs
Comprehensive Gutter Cleaning Programs
29 Oct 25 at 5:54 am
brwon-stake.com – Bookmarked this immediately, planning to revisit for updates and inspiration.
Clifford Farrauto
29 Oct 25 at 5:55 am
кракен Россия
кракен сайт
Henryamerb
29 Oct 25 at 5:55 am
кракен android
kraken darknet market
Henryamerb
29 Oct 25 at 5:55 am
seo partner [url=http://www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]http://www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_ufPi
29 Oct 25 at 5:57 am
кракен маркет
кракен обмен
Henryamerb
29 Oct 25 at 6:00 am
5415015.cc – Mobile version looks perfect; no glitches, fast scrolling, crisp text.
Ezequiel Behne
29 Oct 25 at 6:00 am
Sildenafil générique: Kamagra 100mg prix France – Sildenafil générique
RobertJuike
29 Oct 25 at 6:02 am
digital маркетинг блог [url=https://www.statyi-o-marketinge7.ru]https://www.statyi-o-marketinge7.ru[/url] .
stati o marketinge _ilkl
29 Oct 25 at 6:02 am
профессиональное продвижение сайтов [url=www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/]профессиональное продвижение сайтов[/url] .
optimizaciya i seo prodvijenie saitov moskva_vuPi
29 Oct 25 at 6:02 am
getmyfunsocks.com – Pages loaded fast, images appeared sharp, and formatting stayed consistent.
Mina Tingey
29 Oct 25 at 6:03 am
Do you have a spam issue on this blog; I also am a blogger, and I was curious
about your situation; we have developed some nice methods
and we are looking to swap techniques with others, be sure to shoot me an email if interested.
turkey visa for australian
29 Oct 25 at 6:04 am
Домашний формат удобен, если нет признаков угрозы жизни и дома можно обеспечить спокойную обстановку. Врач приезжает без опознавательных знаков, начинает с очной оценки рисков и допуска к инфузионной терапии, сверяет принятые ранее препараты и аллергии, объясняет план действий и ожидаемую динамику. Далее запускается капельница: мягкая коррекция жидкости и электролитов, поддержка печени, симптом-контроль тревоги, тошноты, головной боли и тремора. На руки выдаются понятные рекомендации на 24–48 часов: питьевой режим, питание, сон, признаки тревоги и алгоритм связи с дежурным врачом.
Изучить вопрос глубже – [url=https://vyvod-iz-zapoya-moskva8.ru/]narkolog-vyvod-iz-zapoya[/url]
Danielkew
29 Oct 25 at 6:04 am
I always emailed this blog post page to all my friends, since if like to read it afterward my links will too.
Futuro Token
29 Oct 25 at 6:06 am
блог интернет-маркетинга [url=https://statyi-o-marketinge7.ru]https://statyi-o-marketinge7.ru[/url] .
stati o marketinge _xjkl
29 Oct 25 at 6:06 am
кракен ios
кракен даркнет маркет
Henryamerb
29 Oct 25 at 6:06 am
Listen, Singapore’ѕ education is demanding, so
apart beyߋnd a famous Junior College, emphasize math foundation іn order to prevent falling
аfter іn country-wide assessments.
Hwa Chong Institution Junior College іs renowned for its integrated
program tһat flalessly combines scholastic rigor with
character development, producing international scholars ɑnd leaders.
Firѕt-rate centers and skilled faculty assistance excellence іn research, entrepreneurship, and
bilingualism. Trainees tаke advantage ⲟf extensive international exchanges
аnd competitors, expanding viewpoints ɑnd honing skills.
Ƭhе organization’ѕ focus on development and service cultivates durability ɑnd
ethical values. Alumni networks оpen doors to tоp universities
аnd influential careers worldwide.
Hwa Chong Institution Junior College іs celebrated for
its seamless integrated program tһɑt masterfully combines extensive academic obstacles ᴡith profound
character development, cultivating а brand-new generation of international scholars
and ethical leaders ᴡho arе geared up to taкe on
complicated global issues. The organization boasts fіrst-rate infrastructure, including innovative research centers, bilingual libraries,
аnd innovation incubators, whee extremely qualified professors guide students
tοwards quality in fields ⅼike scientific research study, entrepreneurial ventures, аnd cultural гesearch studies.
Trainees acquire indispensable experiences tһrough comprehensive worldwide
exchange programs, worldwide competitions іn mathematics and sciences, and collaborative projects that expand tһeir horizons and fine-tune their analytical and interpersonal skills.
Βy emphaszing development tһrough efforts like student-led
startups and innovation workshops, tߋgether with service-oriented activities tһat
promote social obligation, tһe college constructs resilience, flexibility, ɑnd a strong moral foundation іn its learners.
The vast alumni network ᧐f Hwa Chong Institution Junior College оpens paths to elite universities аnd prominent professions
аroᥙnd the ԝorld, underscoring the school’ѕ
enduring legacy of promoting intellectual prowess аnd principled
leadership.
Parents, worry ɑbout the difference hor, math groundwork гemains essential at Junior College in comprehending іnformation, vital ѡithin today’s
tech-driven market.
Goodness, еven if institution is fancy, math is the mɑke-or-break topic fоr building confidence гegarding calculations.
Mums аnd Dads, worry about the gap hor, maths groundwork proves
critical іn Junior College fⲟr comprehending іnformation, crucial іn today’s digital market.
Goodness, no matter іf establishment remains fancy, maths serves as the critical
subject tⲟ developing confidence reցarding figures.
Oh no, primary maths educates practical ᥙses including financial planning, therefߋre maкe sure
your kid masters this properly from young.
Eh eh, composed pom ρi pi, mathematics remаins
among in the higheѕt subjects іn Junior College, establishing base f᧐r А-Level advanced math.
Kiasu revision ɡroups for Math can turn average students into tօp scorers.
Folks, dread tһe disparity hor, math foundation proves vital ɗuring Junior College fοr
grasping figures, essential іn current tech-driven economy.
Wah lao, гegardless wһether establishment proves fancy, math serves ɑs
the mаke-or-break subject tо cultivates poise гegarding numЬers.
Hɑve а look at my blog :: Meridian Secondary School
Meridian Secondary School
29 Oct 25 at 6:06 am
В данной обзорной статье представлены интригующие факты, которые не оставят вас равнодушными. Мы критикуем и анализируем события, которые изменили наше восприятие мира. Узнайте, что стоит за новыми открытиями и как они могут изменить ваше восприятие реальности.
Смотрите также… – https://www.lostscent.com/parfum-ne-zaman-ve-nasil-kullanilmali
StanleyGap
29 Oct 25 at 6:07 am
VitaHomme: Sildenafil générique – Sildenafil générique
RobertJuike
29 Oct 25 at 6:08 am
оптимизация сайта франция цена [url=http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/]http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/[/url] .
optimizaciya i seo prodvijenie saitov moskva_yaPi
29 Oct 25 at 6:09 am
«НеоТрезвие СПБ» работает в парадигме доказательной наркологии. Мы используем медикаментозные и психотерапевтические подходы, а также их комбинации. Выбор зависит от клинического запроса, сопутствующих диагнозов и предпочтений пациента. Ниже — сравнительная таблица, которая отражает практический смысл каждого направления.
Исследовать вопрос подробнее – https://kodirovanie-ot-alkogolizma-v-spb16.ru/kodirovanie-ot-alkogolizma-v-sankt-peterburge-czeny
Seymourphott
29 Oct 25 at 6:11 am
seo бесплатно [url=https://kursy-seo-11.ru/]seo бесплатно[/url] .
kyrsi seo_enEl
29 Oct 25 at 6:12 am
http://vitahomme.com/# Vita Homme
Davidjealp
29 Oct 25 at 6:14 am
kraken вход
кракен онлайн
Henryamerb
29 Oct 25 at 6:14 am
заказать анализ сайта [url=http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]заказать анализ сайта[/url] .
optimizaciya i seo prodvijenie saitov moskva_rtPi
29 Oct 25 at 6:14 am
[url=https://mirkeramiki.org/]гинеколог эндокринолог[/url]
OSELboype
29 Oct 25 at 6:15 am
kraken vk4
кракен даркнет маркет
Henryamerb
29 Oct 25 at 6:15 am
Kamagra 100mg prix France: Kamagra 100mg prix France – Kamagra oral jelly France
RobertJuike
29 Oct 25 at 6:16 am
купить диплом в иваново [url=https://rudik-diplom14.ru]купить диплом в иваново[/url] .
Diplomi_wlea
29 Oct 25 at 6:17 am
seo и реклама блог [url=http://statyi-o-marketinge7.ru/]http://statyi-o-marketinge7.ru/[/url] .
stati o marketinge _hukl
29 Oct 25 at 6:17 am
gotqlb.cc – Color palette felt calming, nothing distracting, just focused, thoughtful design.
Anibal Klingler
29 Oct 25 at 6:17 am
seo partner program [url=https://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/]optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_kePi
29 Oct 25 at 6:19 am
kraken официальный
kraken обмен
Henryamerb
29 Oct 25 at 6:20 am
Эта публикация погружает вас в мир увлекательных фактов и удивительных открытий. Мы расскажем о ключевых событиях, которые изменили ход истории, и приоткроем завесу над научными достижениями, которые вдохновили миллионы. Узнайте, чему может научить нас прошлое и как применить эти знания в будущем.
Всё, что нужно знать – https://sanierungsplanb.de/finance-illustration-04
Vincentorbit
29 Oct 25 at 6:21 am
+905325600307 fetoden dolayi ulkeyi terk etti
FIRAT ENGİN LUXRAINE.COM UZERI PARA AKLIYOR
29 Oct 25 at 6:21 am