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!
isotretinoin online: order isotretinoin from Canada to US – Accutane for sale
Leroymex
23 Jul 25 at 6:56 pm
Мы предлагаем оформление дипломов ВУЗов В киеве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 2394 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://uadiplom17.ru/]Где можно купить диплом[/url] — ответим быстро, без лишних формальностей.
FrancesPhype
23 Jul 25 at 7:01 pm
https://finasteridefromcanada.com/# cheap Propecia Canada
TheronSnipt
23 Jul 25 at 7:02 pm
Its like you learn my mind! You appear to know so much approximately this,
like you wrote the e book in it or something. I believe that you
simply could do with some p.c. to power the message house a bit, however other than that,
this is fantastic blog. A fantastic read. I will definitely be back.
Here is my web site :: extraslot
extraslot
23 Jul 25 at 7:06 pm
Сигналы, указывающие на потребность в наркологической помощи, часто игнорируются либо недооцениваются. Очень важно не пропустить тревожные симптомы, такие как:
Подробнее можно узнать тут – [url=https://narkologicheskaya-klinika-podolsk5.ru/]частная наркологическая клиника[/url]
AndrewHairl
23 Jul 25 at 7:07 pm
I think this is among the most significant information for me.
And i’m glad reading your article. But should remark on few general things, The web site style is ideal, the articles is really excellent :
D. Good job, cheers
Here is my webpage – Fort Lauderdale Senior Medical Center
Fort Lauderdale Senior Medical Center
23 Jul 25 at 7:09 pm
Читать полностью: Лунный посевной календарь на апрель: советы для садоводов и огородников
womansbeautyclub-322
23 Jul 25 at 7:11 pm
как потратить бонусы 1win [url=https://1win3069.ru]как потратить бонусы 1win[/url]
1win_jjkn
23 Jul 25 at 7:13 pm
Москва в ночь не спит, а наша команда вдобавок всегда на страже: закрытая центр лечения алкоголизма и наркомании клиника https://mcnl.ru открыта 24/7. Без очередей и лишних вопросов — приезд врача на дом, мягкий детокс под контролем, сверхскоростная капельница, психотерапия на дому, долговечное сопровождение. Тихо, скрытно, результативно — вернем вам трезвость без боли.
Timsothydet
23 Jul 25 at 7:19 pm
онлайн микрозайм кредит займ онлайн
nadejsfinans-239
23 Jul 25 at 7:21 pm
комплект свай [url=www.ostankino-svai.ru ]www.ostankino-svai.ru [/url] .
vintovie svai_evpr
23 Jul 25 at 7:21 pm
yapı kredi dijital hesap cüzdanı nasıl alınır
Hello, just wanted to tell you, I loved this post.
It was funny. Keep on posting!
yapı kredi dijital hesap cüzdanı nasıl alınır
23 Jul 25 at 7:23 pm
Оформиление дипломов ВУЗов В киеве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1800 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://spbrcom24.ru/]Где купить диплом о среднем образовании[/url] — ответим быстро, без лишних формальностей.
DavidLar
23 Jul 25 at 7:26 pm
Одним из наиболее привлекательных вариантов лечения является проведение капельницы от запоя на дому. Это решение избавляет пациента от необходимости посещать клинику, что важно для тех, кто не хочет привлекать лишнего внимания или испытывает трудности с передвижением. Кроме того, лечение на дому дает возможность получить помощь в комфортной обстановке, что снижает стресс и ускоряет восстановление.
Углубиться в тему – https://kapelnica-ot-zapoya-ekb55.ru/kapelnicza-ot-zapoya-v-stacionare-ekaterinburg/
Dennisfer
23 Jul 25 at 7:29 pm
Москва в ночь бодрствует, а наша команда вдобавок всегда на страже: эксклюзивная центр лечения алкоголизма клиника https://mcnl.ru открыта 24/7. Без записей и лишних вопросов — выезд нарколога на дом, безопасный детокс под седацией, сверхскоростная капельница, психотерапия на дому, бессрочное сопровождение. Тайно, скрытно, точно — вернем трезвость без страданий.
StephenGlona
23 Jul 25 at 7:30 pm
Приобрести диплом о высшем образовании!
Мы предлагаем дипломы психологов, юристов, экономистов и других профессий по доступным тарифам— [url=http://diplomt-v-chelyabinske.ru/]diplomt-v-chelyabinske.ru[/url]
Lazrnsn
23 Jul 25 at 7:30 pm
Hi, i believe that i noticed you visited my blog so i got here to go
back the choose?.I’m attempting to to find things
to improve my web site!I guess its adequate to use some
of your concepts!!
Visit my webpage: extraslot
extraslot
23 Jul 25 at 7:31 pm
whoah this weblog is fantastic i love reading your
posts. Stay up the good work! You already know, a lot of people are
looking around for this information, you can help them greatly.
finance.millvalley.com
23 Jul 25 at 7:37 pm
I absolutely love your blog.. Very nice colors & theme.
Did you develop this web site yourself? Please reply back as I’m planning to create my own blog and would like to find out where you got this from or what the theme is named.
Thank you!
My web-site xtraslot
xtraslot
23 Jul 25 at 7:38 pm
диплом купить о высшем образовании [url=http://www.arus-diplom6.ru]диплом купить о высшем образовании[/url] .
Priobresti diplom o visshem obrazovanii!_bsmi
23 Jul 25 at 7:42 pm
На этом этапе врач детально выясняет, как долго продолжается запой, какие симптомы наблюдаются, и имеются ли сопутствующие заболевания. Точный анализ информации помогает оперативно определить степень интоксикации и подобрать оптимальные методы детоксикации, что является ключом к предотвращению дальнейших осложнений.
Детальнее – [url=https://narcolog-na-dom-ryazan00.ru/]нарколог на дом вывод из запоя рязань[/url]
Douglasbup
23 Jul 25 at 7:45 pm
Попытка самостоятельно выйти из запоя или преодолеть тяжелое похмелье может привести к крайне негативным последствиям. Длительное употребление алкоголя или резкий отказ без врачебного контроля опасны развитием осложнений, таких как алкогольный психоз, инсульт, инфаркт, обезвоживание и острая сердечная недостаточность.
Ознакомиться с деталями – [url=https://narcolog-na-dom-sankt-peterburg000.ru/]нарколог на дом недорого[/url]
Migueleleft
23 Jul 25 at 7:45 pm
Мы предлагаем оформление дипломов ВУЗов по всей Украине — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 3410 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://spbrcom23.ru/]Куплю диплом Москва[/url] — ответим быстро, без лишних формальностей.
CindyReshy
23 Jul 25 at 7:48 pm
В подобных случаях самостоятельное лечение может привести к тяжёлым осложнениям, а промедление — стоить здоровья или даже жизни. Срочная наркологическая помощь — это шаг к безопасности и началу выздоровления.
Подробнее можно узнать тут – http://narkologicheskaya-pomoshch-lyubercy5.ru
Kevinamabe
23 Jul 25 at 7:48 pm
Врач-нарколог проводит комплексное обследование пациента, оценивая степень зависимости и общее состояние организма. В ходе первичного осмотра специалист не только определяет тяжесть алкогольной зависимости, но и выявляет сопутствующие патологии, которые могут повлиять на процесс лечения. Обследование включает лабораторные анализы, электрокардиограмму и другие необходимые диагностические процедуры. Врач тщательно изучает анамнез для выявления возможных противопоказаний к определенным методам терапии. Особое внимание уделяется психологическим аспектам, которые могли способствовать формированию зависимости, что помогает разработать эффективную программу лечения.
Исследовать вопрос подробнее – [url=https://vyvod-iz-zapoya-krasnoyarsk55.ru/]вывод из запоя круглосуточно в красноярске[/url]
MarcusDwecy
23 Jul 25 at 7:48 pm
Столица ночью не дремлет, а наша команда вдобавок всегда на страже: закрытая наркологическая клиника mcnl.ru ждёт 24/7. Без записей и документов — выезд врача по вашему звонку, мягкий детокс под контролем, экспресс- капельница, нейрокоррекция на месте, бессрочное сопровождение. Тайно, скрытно, результативно — вернём трезвость без боли.
IsmaelNek
23 Jul 25 at 7:49 pm
Somebody essentially assist to make severely posts I might
state. This is the very first time I frequented your website page and thus far?
I surprised with the analysis you made to
make this particular post extraordinary. Wonderful job!
http://helloqueen.pl
highlight
23 Jul 25 at 7:51 pm
Столица ночью бодрствует, а наша команда аналогично всегда на страже: эксклюзивная центр лечения алкоголизма и наркомании клиника https://mcnl.ru/ работает 24/7. Без предварительной регистрации и документов — вызов нарколога по вашему звонку, мягкий детокс в сне, экспресс- капельница, психологическая поддержка на месте, бессрочное сопровождение. Тихо, скрытно, точно — вернём трезвость без боли.
OLaneDrync
23 Jul 25 at 7:51 pm
Thanks for finally writing about > PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
< Liked it!
Conscious Consumerism
23 Jul 25 at 7:51 pm
Москва после заката не дремлет, а наша команда тоже всегда на страже: закрытая наркологическая клиника https://mcnl.ru/ работает 24/7. Без очередей и лишних вопросов — приезд специалиста по адресу, безопасный детокс в сне, ультрабыстрая капельница, нейрокоррекция на дому, пожизненное сопровождение. Тайно, скрытно, точно — вернем трезвость без страданий.
GichardMam
23 Jul 25 at 7:53 pm
Чем раньше начато лечение, тем выше вероятность полного восстановления здоровья без тяжёлых последствий для организма и психики. В клинике «Наркосфера» к каждому случаю подходят максимально внимательно и индивидуально.
Ознакомиться с деталями – [url=https://narkologicheskaya-klinika-balashiha5.ru/]наркологическая клиника стационар[/url]
Scottslugs
23 Jul 25 at 7:59 pm
Столица после заката не дремлет, а наша команда тоже всегда на страже: закрытая центр лечения алкоголизма клиника mcnl.ru работает 24/7. Без записей и формальностей — приезд нарколога по вашему звонку, щадящий детокс под контролем, ультрабыстрая капельница, психологическая поддержка на месте, долговечное сопровождение. Тихо, скрытно, эффективно — вернем трезвость без страданий.
IsmaelNek
23 Jul 25 at 8:10 pm
После основной терапии важно обеспечить поддержку пациента в период реабилитации. Реабилитационные программы в Краснодаре включают социальную адаптацию, восстановление навыков общения и трудоустройства. Это позволяет минимизировать риск рецидива и возвращения к употреблению алкоголя. Поддержка со стороны специалистов и близких — обязательное условие успешного результата. Более подробно о социальной реабилитации можно ознакомиться на сайте Федерального реабилитационного центра.
Исследовать вопрос подробнее – [url=https://lechenie-alkogolizma-krasnodar00.ru/]клиника лечения алкоголизма краснодарский край[/url]
WilliamVex
23 Jul 25 at 8:14 pm
Москва после заката не дремлет, а наша команда аналогично всегда на страже: эксклюзивная наркологическая клиника https://mcnl.ru работает 24/7. Без бюрократии и бумаг — вызов нарколога на дом, щадящий детокс в сне, экспресс- капельница, нейрокоррекция на дому, бессрочное сопровождение. Тихо, скрытно, точно — вернем трезвость без страданий.
EarnestAbent
23 Jul 25 at 8:17 pm
Мегаполис в ночь бодрствует, а наша команда вдобавок всегда на страже: закрытая центр лечения алкоголизма и наркомании клиника https://mcnl.ru открыта 24/7. Без бюрократии и формальностей — срочный приём доктора по адресу, щадящий детокс в сне, ультрабыстрая капельница, психологическая поддержка у вас, пожизненное сопровождение. Без шума, скрытно, эффективно — вернём трезвость без страданий.
IsmaelNek
23 Jul 25 at 8:19 pm
Оформиление дипломов ВУЗов В киеве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1826 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://spbrcom24.ru/]Диплом об образовании купить[/url] — ответим быстро, без лишних формальностей.
DavidLar
23 Jul 25 at 8:19 pm
Выездной формат позволяет избежать контактов с другими пациентами в клинике и очистить организм в привычной обстановке. Специалисты самостоятельно привозят весь необходимый набор медикаментов и расходных материалов.
Изучить вопрос глубже – [url=https://narkologicheskaya-klinika-ekaterinburg0.ru/]narkologicheskaya-klinika-ekaterinburg0.ru/[/url]
Patrickliage
23 Jul 25 at 8:20 pm
1win armenia [url=https://www.1win3075.ru]1win armenia[/url]
1win_qnsi
23 Jul 25 at 8:21 pm
Кодирование — это не просто медицинская манипуляция, а серьёзный шаг к восстановлению контроля над собственной жизнью и формированию устойчивой ремиссии.
Углубиться в тему – [url=https://kodirovanie-ot-alkogolizma-mytishchi5.ru/]anonimnoe-kodirovanie-ot-alkogolizma-cena[/url]
Michaelshuct
23 Jul 25 at 8:24 pm
amecapitals.com Отзывы AME Capitals – это надежный брокер, который заботится о своих клиентах.
DavidLex
23 Jul 25 at 8:26 pm
Isotretinoin From Canada: order isotretinoin from Canada to US – isotretinoin online
Leroymex
23 Jul 25 at 8:27 pm
Мегаполис ночью не дремлет, а наша команда тоже всегда на страже: эксклюзивная центр лечения алкоголизма клиника https://mcnl.ru доступна 24/7. Без записей и формальностей — выезд специалиста к вам, щадящий детокс под седацией, экспресс- капельница, нейрокоррекция на месте, пожизненное сопровождение. Тайно, скрытно, точно — вернем вам трезвость без боли.
OLaneDrync
23 Jul 25 at 8:33 pm
купить аттестат 11 в рубцовске [url=http://arus-diplom25.ru]купить аттестат 11 в рубцовске[/url] .
Diplomi_ufot
23 Jul 25 at 8:33 pm
What a information of un-ambiguity and preserveness of precious know-how regarding
unexpected feelings.
SEO for google maps
23 Jul 25 at 8:35 pm
Дизайн человека 36 28
33 Ворота Дизайн человека
27 Ворота Дизайн человека
29 Ворота Дизайн человека
33 Ворота Дизайн человека
63 Ворота Дизайн человека
57 Ворота Дизайн человека
61 Ворота Дизайн человека
62 Ворота Дизайн человека
37 Ворота Дизайн человека
25 Ворота Дизайн человека
11 Ворота Дизайн человека
Дизайнчеловека35
23 Jul 25 at 8:36 pm
мостбет сом [url=https://www.mostbet4082.ru]мостбет сом[/url]
mostbet_gfEi
23 Jul 25 at 8:39 pm
Национальный стандарт оказания наркологической помощи регламентирует состав препаратов, используемых при терапии, а также протоколы безопасности, которым следует выездной персонал.
Подробнее можно узнать тут – https://narcolog-na-dom-ekaterinburg55.ru/
WilliamHag
23 Jul 25 at 8:42 pm
Москва в ночь не дремлет, а наша команда вдобавок всегда на страже: эксклюзивная центр лечения алкоголизма и наркомании клиника mcnl.ru доступна 24/7. Без предварительной регистрации и лишних вопросов — вызов специалиста к вам, щадящий детокс в сне, экспресс- капельница, психологическая поддержка на месте, бессрочное сопровождение. Без шума, конфиденциально, точно — вернем трезвость без боли.
Dichaelwaw
23 Jul 25 at 8:46 pm
kraken marketplace
DavidFoogs
23 Jul 25 at 8:53 pm
flood sms usa
GerardobaR
23 Jul 25 at 8:54 pm