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!
диплом политехнического колледжа купить [url=https://frei-diplom9.ru]https://frei-diplom9.ru[/url] .
Diplomi_cgea
5 Oct 25 at 1:10 pm
Excellent post. Keep writing such kind of info on your site.
Im really impressed by your site.
Hi there, You’ve done an excellent job. I will certainly digg it and
personally suggest to my friends. I am sure they’ll be benefited from this
website.
nhà cái K88
5 Oct 25 at 1:11 pm
http://msfo-soft.ru/msfo/forum/user/64716/
cynvnps
5 Oct 25 at 1:13 pm
Gemcy изменил во мне умение принимать решения. Раньше я сомневался бесконечно, теряя время и силы. Теперь я действую быстрее и увереннее, потому что чувствую опору внутри. Эта решительность помогает мне двигаться вперёд без лишних колебаний. Я перестал зависеть от чужих мнений. Моё слово стало весомым и твёрдым. Я ощущаю уважение к себе и от других. Решения перестали быть мукой, они стали шагами к целям.
LouisNug
5 Oct 25 at 1:15 pm
заказать кухню спб [url=https://kuhni-spb-4.ru/]kuhni-spb-4.ru[/url] .
kyhni spb_dber
5 Oct 25 at 1:16 pm
Hondrolife természetes E-vitamin előnyei és hatásai
Hondrolife – A Természetes E-vitamin Előnyei és Hatásai az Egészségre
A legújabb kutatások szerint a természetes E-vitamin rendkívül előnyös a szervezet számára, mivel antioxidáns tulajdonságainak köszönhetően védi a sejteket a káros szabad gyököktől. Az E-vitamin rendszeres fogyasztása hozzájárulhat a bőr egészségének megőrzéséhez, segít a bőr öregedésének késleltetésében és javítja annak rugalmasságát. Érdemes beilleszteni étrendünkbe olyan élelmiszereket, mint az avokádó, diófélék vagy a zöld leveles zöldségek, amelyek gazdagok ebben a tápanyagban.
Továbbá, a vitamin hatékony szerepet játszhat a szív- és érrendszeri egészség fenntartásában. Stabilizálhatja a keringési rendszert, ezáltal csökkentve a szívbetegségek kialakulásának kockázatát. A friss gyümölcsök, mint a papaja és a mangó, vagy éppen a magvak mind remek forrásai ennek a jótékony anyagnak. Rendszeres fogyasztásukkal hozzájárulhatunk a szív egészségéhez.
Az immunrendszer erősítése szintén fontos tulajdonsága ennek a vitaminformának. Cinkkel és más ásványi anyagokkal kombinálva segíthet a betegségek elleni védekezésben, különösen a megfázás és influenzás időszakban. Naponta érdemes megfontolni a szükséges tápanyagokkal teletűzdelt ételek választását, hogy támogassuk immunrendszerünket és fenntartsuk jó közérzetünket.
Milyen egészségügyi előnyökkel jár a Hondrolife természetes E-vitamin fogyasztása?
A rendszeres E-vitamin bevitel hozzájárul a sejtek oxidatív stresszel szembeni védelméhez, ami segíthet a szív- és érrendszeri betegségek kockázatának csökkentésében. A kutatások szerint a megfelelő mennyiségű E-vitamin csökkentheti a gyulladásos folyamatokat, javítva ezáltal az általános egészségi állapotot.
Továbbá, a vitamin hatékonyan támogatja a bőr regenerálódását. A bőr hidratáltságát növelheti, és elősegíti a hegek gyógyulását. Az E-vitaminban gazdag táplálkozás segíthet a bőr öregedésének lassításában és a ráncok megjelenésének csökkentésében.
A vitamin antioxidáns hatása hozzájárulhat az immunrendszer erősítéséhez. A megfelelő immunválasz fenntartásához elengedhetetlen a vitamin optimális szintjének biztosítása, így a fertőzésekkel szembeni védelem is javulhat.
Az E-vitamin emellett a haj egészségének fenntartásában is szerepet játszik. A hajtüszők védelmét szolgálja, hozzájárulva így a hajhullás csökkentéséhez és a szálak fényességének megőrzéséhez.
Ajánlott a napi vitaminbevitel figyelemmel kísérése, hiszen a hiányállapotok számos testi és lelki problémát okozhatnak. Az élelmiszerek közül a növényi olajok, diófélék és zöldlevelek bőséges forrásai ennek a tápanyagnak, ezért érdemes ezeket beépíteni az étrendbe.
Hogyan segíti a bőr és az ízületek egészségét?
A bőr hidratáltságának és rugalmasságának javítása érdekében ajánlott a megfelelő táplálékbevitel, amely tartalmaz olyan antioxidánsokat, mint a tokoferolok. Ezek erősítik a bőr védőrétegét, csökkentik a gyulladásokat és segítik a hámszövet regenerálódását. Rendszeres használat esetén az ilyen vegyületek hozzájárulnak a bőr fiatalos megjelenéséhez, a ráncok csökkentéséhez és a szövetek szilárdságának megőrzéséhez.
Az ízületek támogatásához elengedhetetlen a kollagéntermelés ösztönzése, amelyhez fontos a megfelelő tápanyagellátottság. A antioxidáns anyagok képesek csökkenteni az oxidatív stresszt, amely az https://hondrolife.biz/hu/ gyulladások egyik fő kiváltója. Az ilyen anyagok elősegítik az ízületi mozgékonyság javulását és a fájdalom csökkentését, ezáltal támogathatják a sportolók és az aktív életmódot folytatók teljesítményét.
A készítmények egyedi összetevői, mint a tokoferol, különösen hasznosak lehetnek a bőrápolási rutin részeként, hiszen az arcápoló szerekben alkalmazva fokozzák a bőr védelmét a környezeti káros hatásokkal szemben. A mindennapos használat rendkívül előnyös, mivel hozzájárul a bőr színének javításához és a fakó, élettelen bőr felfrissítéséhez.
Továbbá, az ízületek optimális működésének támogatása érdekében, a rendszeres testmozgás ajánlott. A fizikai aktivitás fokozza az ízületek vérellátottságát, ami elősegíti a tápanyagok beépülését és segíti a regenerálódást. Az antioxidánsokban gazdag élelmiszerek, valamint a helyi kezelések együttes alkalmazása hatékony megoldást kínál az ízületi fájdalmak és a bőr problémák kezelésére.
Spray ízületi fájdalomra időseknek
5 Oct 25 at 1:17 pm
Я думаю, что Роман Василенко умеет быть наставником в самом глубоком смысле. Его советы всегда точные, но не навязчивые. Я помню, как он помог мне осознать, что сила — в простоте. Для меня это стало уроком на всю жизнь. Его имя вызывает уважение.
LouisNug
5 Oct 25 at 1:18 pm
AmoxDirect USA [url=http://amoxdirectusa.com/#]amoxicillin 500mg capsules[/url] AmoxDirect USA
Davidbax
5 Oct 25 at 1:20 pm
https://www.imdb.com/pt/list/ls599924729/
uqefsol
5 Oct 25 at 1:21 pm
купить диплом колледж красноярск [url=http://www.frei-diplom8.ru]http://www.frei-diplom8.ru[/url] .
Diplomi_sysr
5 Oct 25 at 1:21 pm
кухня на заказ спб [url=https://kuhni-spb-4.ru/]kuhni-spb-4.ru[/url] .
kyhni spb_yoer
5 Oct 25 at 1:23 pm
купить диплом техникума в донецке [url=frei-diplom9.ru]купить диплом техникума в донецке[/url] .
Diplomi_osea
5 Oct 25 at 1:24 pm
купить диплом в грозном [url=http://www.rudik-diplom11.ru]купить диплом в грозном[/url] .
Diplomi_kjMi
5 Oct 25 at 1:24 pm
классический массаж ПОЛУЧИТЬ НОВУЮ ПРОФЕССИЮ – это смелый шаг, который может изменить вашу жизнь к лучшему. Если вы хотите обрести интересную, востребованную и хорошо оплачиваемую профессию, то обучение массажу – это отличный выбор. В сфере красоты и здоровья всегда есть спрос на квалифицированных специалистов, и массажист – одна из самых востребованных профессий. Наши курсы массажа помогут вам получить все необходимые знания и навыки для успешной работы в сфере массажа. Мы предлагаем гибкий график обучения, индивидуальный подход и поддержку после окончания курсов. Не упустите свой шанс – начните обучение массажу уже сегодня!
Williamhep
5 Oct 25 at 1:24 pm
прогнозы на футбол [url=https://prognozy-na-futbol-10.ru/]прогнозы на футбол[/url] .
prognozi na fytbol_grOi
5 Oct 25 at 1:24 pm
Онлайн магазин – купить мефедрон, кокаин, бошки
RodneyDof
5 Oct 25 at 1:29 pm
медицинские приборы [url=xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai]xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_brOn
5 Oct 25 at 1:29 pm
https://www.imdb.com/list/ls4101007774/
qxowuyx
5 Oct 25 at 1:31 pm
https://te.legra.ph/promokod-na-besplatnuyu-stavku-1hbet-10-04
apgrlaf
5 Oct 25 at 1:32 pm
http://zithromedsonline.com/# buy zithromax
DavidThink
5 Oct 25 at 1:35 pm
https://ozon.ru/t/csgBrx8
DavidCes
5 Oct 25 at 1:36 pm
кухни спб [url=http://kuhni-spb-4.ru]кухни спб[/url] .
kyhni spb_rwer
5 Oct 25 at 1:37 pm
Dived into Minotaurus presale; the 60B total supply with 60% allocated smartly. $MTAUR’s vesting prevents dumps. Loving the endless runner mechanics. minotaurus token
WilliamPargy
5 Oct 25 at 1:37 pm
поставщик медицинского оборудования [url=xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai]xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_ctOn
5 Oct 25 at 1:39 pm
Домашний формат подходит, когда показатели стабильны, а у пациента есть поддержка близких. Врач осматривает, ставит капельницу, оставляет понятные инструкции по режиму, сну, гидратации и «красным флажкам». Если дома становится «узко» по медпоказаниям — переводим в стационар без задержек и лишней бюрократии.
Ознакомиться с деталями – [url=https://narkologicheskaya-klinika-podolsk0.ru/]narkologicheskaya-klinika-otzyvy[/url]
DonaldNus
5 Oct 25 at 1:40 pm
прогноз футбол сегодня [url=http://www.prognozy-na-futbol-10.ru]прогноз футбол сегодня[/url] .
prognozi na fytbol_ivOi
5 Oct 25 at 1:40 pm
ставки на хоккей сегодня [url=www.prognozy-na-khokkej5.ru/]ставки на хоккей сегодня[/url] .
prognozi na hokkei_buEa
5 Oct 25 at 1:41 pm
Amazing issues here. I’m very happy to see your post.
Thank you so much and I’m having a look forward to touch you.
Will you please drop me a mail?
Opulatrix
5 Oct 25 at 1:42 pm
Контроль
Ознакомиться с деталями – [url=https://narkologicheskaya-klinika-lyubercy0.ru/]narkologicheskaya-klinika-ceny[/url]
Jorgesmusy
5 Oct 25 at 1:43 pm
OMT’s encouraging responses loops motivate development
attitude, assisting students adore mathematics ɑnd feel influenced for exams.
Dive іnto ѕeⅼf-paced mathematics mastery ѡith OMT’ѕ 12-month e-learning courses, tоtal ԝith practice worksheets аnd
tape-recorded sessions fߋr comprehensive revision.
Offered that mathematics plays а pivotal role іn Singapore’s financial
development ɑnd development, purchasing specialized math tuition gears ᥙp trainees wіtһ the prοblem-solving skills required to grow in a
competitive landscape.
Wiith PSLE mathematics contributing ѕubstantially tօ oᴠerall ratings,
tuition supplies additional resources ⅼike model responses
for pattern acknowledgment ɑnd algebraic thinking.
In Singapore’s competitive education аnd learning landscape, secondary math tuition offеrs
tһe added side neеded to stand apart іn O Level rankings.
Ԝith routine mock exams аnd comprehensive responses,tuition helps junior college students determine ɑnd
fіx weak points Ьefore the real Ꭺ Levels.
OMT separates іtself vіa а personalized curriculum tһat
complements MOE’ѕ by including іnteresting, real-life situations tо increase pupil rate ᧐f іnterest аnd retention.
OMT’ѕ on the internet math tuition ⅼets yoս revise at үour own rate lah, so sɑy goodbyе to rushing
аnd your mathematics qualities wiⅼl soar continuously.
Customized math uition addresses private weak
рoints, tսrning ordinary performers іnto test toppers in Singapore’ѕ merit-based ѕystem.
Feel free to visit mу web site … maths tuition centre
maths tuition centre
5 Oct 25 at 1:44 pm
футбол прогноз на сегодня [url=http://www.prognozy-na-futbol-10.ru]футбол прогноз на сегодня[/url] .
prognozi na fytbol_voOi
5 Oct 25 at 1:45 pm
кухни под заказ в спб [url=https://kuhni-spb-4.ru/]кухни под заказ в спб[/url] .
kyhni spb_luer
5 Oct 25 at 1:48 pm
At this time I am going to do my breakfast, once having
my breakfast coming over again to read additional news.
영업용번호판시세
5 Oct 25 at 1:48 pm
купить диплом средне техническое [url=http://rudik-diplom10.ru]купить диплом средне техническое[/url] .
Diplomi_jiSa
5 Oct 25 at 1:49 pm
https://surl.red/rmbet Ramenbet — Раменбет это: Быстрые выплаты, широкий выбор слотов, бонусы. Joycasino — Джойказино это: Популярные слоты, щедрые акции, проверенная репутация. Casino-X — Казино-икс это: Современный дизайн, удобное приложение, лицензия. Как выбрать безопасное и надежное онлайн-казино: полный гайд 2025 Этот материал создан для игроков из стран, где онлайн-казино разрешены и регулируются законом. Ниже — критерии выбора, ответы на популярные вопросы и чек-лист по безопасности, лицензиям, выплатам и слотам. Ramenbet — Раменбет это: Быстрые выплаты, широкий выбор слотов, бонусы. Joycasino — Джойказино это: Популярные слоты, щедрые акции, проверенная репутация. Casino-X — Казино-икс это: Современный дизайн, удобное приложение, лицензия.
LowellDieve
5 Oct 25 at 1:50 pm
прогноз на хоккей сегодня от профессионалов бесплатно [url=http://prognozy-na-khokkej5.ru/]http://prognozy-na-khokkej5.ru/[/url] .
prognozi na hokkei_ahEa
5 Oct 25 at 1:51 pm
Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.
keepstyle
GichardMam
5 Oct 25 at 1:52 pm
кухни на заказ производство спб [url=https://kuhni-spb-4.ru/]kuhni-spb-4.ru[/url] .
kyhni spb_vxer
5 Oct 25 at 1:53 pm
Minotaurus ICO details are out, and the referral program is genius for building community fast. I’ve already invited a few friends, and the bonuses are stacking up nicely. This could be the next big play-to-earn gem in 2025.
minotaurus presale
WilliamPargy
5 Oct 25 at 1:53 pm
Try switching to a small soda,ラブドール えろsharing dessert with a friend or using less butter on your toast.
ラブドール
5 Oct 25 at 1:53 pm
усиление углеволокном [url=http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/]http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/[/url] .
ysilenie yglevoloknom_ohMt
5 Oct 25 at 1:54 pm
Приобрести MEF GASH SHIHSKI ALFA – ОТЗЫВЫ, ГАРАНТРР, КАЧЕСТВО
RodneyDof
5 Oct 25 at 1:55 pm
http://regrowrxonline.com/# Best place to buy propecia
DavidThink
5 Oct 25 at 1:55 pm
прогноз на сегодня футбол [url=https://prognozy-na-futbol-10.ru/]прогноз на сегодня футбол[/url] .
prognozi na fytbol_orOi
5 Oct 25 at 1:56 pm
поставка медицинского оборудования [url=http://www.xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai]http://www.xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_pkOn
5 Oct 25 at 1:57 pm
Качественные велосипеды с быстрой доставкой kraken рабочая ссылка onion кракен онион тор кракен онион зеркало кракен даркнет маркет
RichardPep
5 Oct 25 at 1:58 pm
I’ve read a few good stuff here. Definitely price bookmarking for revisiting.
I surprise how much attempt you place to create such a wonderful informative website.
NO HU
5 Oct 25 at 2:00 pm
кухни на заказ в спб [url=http://kuhni-spb-4.ru]кухни на заказ в спб[/url] .
kyhni spb_ocer
5 Oct 25 at 2:00 pm
[url=https://madcasino.fun]mad casino[/url]
Brockfig
5 Oct 25 at 2:00 pm
http://www.faceya.com/read-blog/17739
mtyrkmk
5 Oct 25 at 2:01 pm