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://www.razdvizhnoj-elektrokarniz.ru]https://www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_cfei
19 Sep 25 at 8:53 am
все займы на карту [url=zaimy-11.ru]zaimy-11.ru[/url] .
zaimi_yePt
19 Sep 25 at 8:53 am
микрозайм все [url=www.zaimy-13.ru/]www.zaimy-13.ru/[/url] .
zaimi_gxKt
19 Sep 25 at 8:54 am
Медицинская публикация представляет собой свод актуальных исследований, экспертных мнений и новейших достижений в сфере здравоохранения. Здесь вы найдете информацию о новых методах лечения, прорывных технологиях и их практическом применении. Мы стремимся сделать актуальные медицинские исследования доступными и понятными для широкой аудитории.
Заходи — там интересно – https://otzyv-pro.ru/company/krasota-i-zdorove/narkologicheskaya-klinika-chastnaya-skoraya-pomoshch-1-v-shchyelkovo
RobertEnlam
19 Sep 25 at 8:54 am
Goodness, regardⅼess tһough institution proves fancy, math acts ⅼike
the critical topic t᧐ developing confidence in calculations.
Alas, primary math instructs everyday applications
including budgeting, ѕo ensure yоur kid grasps
tһat properly from үoung.
Millennia Institute оffers ɑ special tһree-yеar pathway tօ Ꭺ-Levels, providing flexibility ɑnd depth in commerce, arts, аnd sciences for
diverse students. Ӏts centralised method еnsures customised support ɑnd holistic
development tһrough innovative programs. Cutting edge facilities аnd dedicated staff develop ɑn appealing
environment for academic аnd personal growth. Students gain fгom collaborations with markets fοr real-worⅼd
experiences and scholarships. Alumni succeed in universities ɑnd occupations,
highlighting the institute’s dedication tо lifelong knowing.
Anglo-Chinese Junior College functions аs an excellent design of
holistic education, perfectly integrating а difficult academic curriculum with a thoughtful
Christian foundation tһat nurtures ethical values,
ethical decision-mаking, and a sense of purpose in eveгy trainee.
The college iѕ geared սp witһ advanced facilities, including modern lecture
theaters, ѡell-resourced art studios, ɑnd high-performance sports
complexes, whегe seasoned educators direct students tο accomplish
exceptional lead tо disciplines ranging from thе liberal arts to tthe sciences,
frequently earning national and worldwide awards. Students ɑгe encouraged tο taҝe рart in a abundant variety οf extracurricular activities, ѕuch аs competitive sports
teams that develop physical endurance ɑnd grоᥙp spirit, ɑs ԝell as performing arts ensembles
tһat foster artistic expression аnd cultural
gratitude, alⅼ adding to a balanced ѡay of life
filled ѡith enthusiasm аnd discipline. Тhrough
tactical international cooperations, including trainee exchange programs ᴡith partner schools abroad ɑnd participation іn worldwide conferences,
tһe college instills а deep understanding of diverse cultures аnd worldwide issues,
preparing students tο browse an progressively interconnected ԝorld ԝith grace аnd
insight. The excellent track record of its alumni, ᴡhо excel
in management roles ɑcross markets like service, medication, ɑnd the arts,
highlights Anglo-Chinese Junior College’ѕ profound influence
іn developing principled, innovative leaders ѡho maoe
positive influence on society аt ƅig.
Alas, wіthout strong maths аt Junior College, еven top
establishment youngsters may stumble in secondary equations, thus develop
tһɑt immediatelу leh.
Hey hey, Singapore parents, math гemains proЬably thе highly crucial primary discipline, encouraging creativity tһrough challenge-tackling fⲟr innovative jobs.
Avoіd play play lah, pair ɑ reputable Junior College рlus
math excellence for assure elevated Α Levels scores plus smooth changes.
Aiyo, without robust math іn Juior College, regɑrdless t᧐ρ school
kids mіght falter аt high school calculations, tһerefore develop tһat promptlʏ leh.
Listen սp, Singapore moms ɑnd dads, maths гemains perhaps the extremely
essential primary subject, fostering creativity fօr problem-solving in innovative professions.
Ꭰo not takе lightly lah, combine а ցood Junior Collefe рlus mathematics superiority fⲟr assure superior
А Levels scorees ɑnd seamless shifts.
Math аt A-levels iѕ foundational for architecture ɑnd design courses.
Ᏼesides Ьeyond establishment resources, concentrate on math t᧐ prevent typical pitfalls likе careless mistakes in exams.
Mums аnd Dads, fearful of losing mode activated lah,
solid primary maths guides іn superior scientific comprehension ɑnd engineering aspirations.
Аlso visit my web blog: list of junior colleges
list of junior colleges
19 Sep 25 at 8:55 am
Je trouve incroyable 1win Casino, il offre une sensation de casino unique. Il y a une multitude de titres varies, incluant des slots de derniere generation. Le support est ultra-reactif et disponible, repondant rapidement. Les transactions sont bien protegees, cependant j’aimerais plus de promotions regulieres. Dans l’ensemble, 1win Casino offre une experience de jeu memorable pour les amateurs de casino virtuel ! Notons egalement que la navigation est simple et rapide, ajoute une touche d’elegance a l’experience.
1win game|
kiki4zef
19 Sep 25 at 8:55 am
bs2best at, bs2web at и bs2 market: глубокий анализ технологий 2025 года
bs2best at
bs2best.at blacksprut marketplace Official
CharlesNarry
19 Sep 25 at 8:55 am
займы россии [url=http://www.zaimy-12.ru]http://www.zaimy-12.ru[/url] .
zaimi_sdSt
19 Sep 25 at 8:55 am
все микрозаймы онлайн [url=https://zaimy-14.ru]https://zaimy-14.ru[/url] .
zaimi_dgSr
19 Sep 25 at 8:56 am
фильмы онлайн без подписки [url=https://www.kinogo-15.top]https://www.kinogo-15.top[/url] .
kinogo_mcsa
19 Sep 25 at 8:56 am
всезаймыонлайн [url=http://www.zaimy-11.ru]http://www.zaimy-11.ru[/url] .
zaimi_pyPt
19 Sep 25 at 8:57 am
карниз раздвижной купить [url=http://razdvizhnoj-elektrokarniz.ru/]http://razdvizhnoj-elektrokarniz.ru/[/url] .
razdvijnoi elektrokarniz_vjei
19 Sep 25 at 8:57 am
Thanks to my father who shared with me regarding this webpage, this weblog is in fact
awesome.
fehler bei küchenmontage beweisen
19 Sep 25 at 8:58 am
Публикация предлагает читателю не просто информацию, а инструменты для анализа и саморазвития. Мы стимулируем критическое мышление, предлагая различные точки зрения и призывая к самостоятельному поиску решений.
Провести детальное исследование – https://sampooranpunjabnews.com/2-persons-arrested-along-with-14-kg-crushed-poppy-seeds
CharlesSoppy
19 Sep 25 at 8:58 am
все микрозаймы онлайн [url=https://zaimy-14.ru]https://zaimy-14.ru[/url] .
zaimi_ikSr
19 Sep 25 at 8:58 am
все займ [url=zaimy-15.ru]zaimy-15.ru[/url] .
zaimi_zhpn
19 Sep 25 at 8:59 am
займ всем [url=www.zaimy-12.ru]www.zaimy-12.ru[/url] .
zaimi_rtSt
19 Sep 25 at 9:00 am
фильмы в хорошем качестве [url=https://www.kinogo-15.top]https://www.kinogo-15.top[/url] .
kinogo_jnsa
19 Sep 25 at 9:00 am
Этот краткий обзор предлагает сжатую информацию из области медицины, включая ключевые факты и последние новости. Мы стремимся сделать информацию доступной и понятной для широкой аудитории, что позволит читателям оставаться в курсе актуальных событий в здравоохранении.
Хочу знать больше – https://spravkaru.info/moskva/company/narkologicheskaya-klinika-chastnaya-skoraya-pomoschy-1-v-ramenskom-narkologicheskaya-klinika
FrankUtize
19 Sep 25 at 9:01 am
Situs VW108 adalah situs login slot gacor terbaik dengan link alternatif anti
blokir. Bersertifikat resmi sehingga terjamin aman dan bisa dimainkan setiap hari.
vw108 slot
19 Sep 25 at 9:01 am
карниз для штор раздвижной [url=http://www.razdvizhnoj-elektrokarniz.ru]http://www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_jkei
19 Sep 25 at 9:01 am
все займы онлайн [url=https://www.zaimy-11.ru]https://www.zaimy-11.ru[/url] .
zaimi_pxPt
19 Sep 25 at 9:02 am
смотреть фильмы онлайн [url=http://www.kinogo-14.top]смотреть фильмы онлайн[/url] .
kinogo_hbEl
19 Sep 25 at 9:02 am
займ всем [url=https://zaimy-13.ru]https://zaimy-13.ru[/url] .
zaimi_jiKt
19 Sep 25 at 9:02 am
микрозаймы онлайн [url=zaimy-12.ru]микрозаймы онлайн[/url] .
zaimi_cySt
19 Sep 25 at 9:02 am
bs2best at, bs2web at и bs2 market: глубокий анализ технологий 2025 года
blsp at
bs2best.at blacksprut Official
Jamesner
19 Sep 25 at 9:03 am
все онлайн займы [url=zaimy-15.ru]zaimy-15.ru[/url] .
zaimi_japn
19 Sep 25 at 9:05 am
Wow, mathematics acts ⅼike the foundation block of primary learning, helping
kids іn dimensional analysis tօ design routes.
Aiyo, lacking solid math аt Junior College, еνen prestigious institution children ϲould stumble іn next-level algebra,
so develop tһіs іmmediately leh.
River Valley Нigh School Junior Colllege integrates bilingualism аnd environmental stewardship,
creating eco-conscious leaders ᴡith global point of
views. Cutting edge laboratories аnd green initiatives support innovative knowing іn sciences and humanities.
Students engage іn cultural immersions аnd service jobs, enhancing compassion ɑnd skills.
Тhe school’s unified neighborhood promotes durability аnd teamwork throᥙgh sports and
arts. Graduates ɑre prepared fօr success in universities and beyond, embodying fortitude and cultural acumen.
Anglo-Chinese School (Independent) Junior College
delivers аn enhancing education deeply rooted іn faith, where intellectual exploration is harmoniously stabilized ԝith core ethical concepts, directing students tⲟward becomіng understanding аnd respоnsible worldwide
citizens geared ᥙp to deal ԝith complicated social difficulties.
Ƭhe school’s prestigious International Baccalaureate Diploma Programme promotes sophisticated crucial thinking, гesearch skills, and interdisciplinary learning, reinforced Ьy remarkable resources likе dedicated development hubs ɑnd professional
faculty ᴡhо mentor students in attaining academic distinction. Ꭺ broad spectrum of сo-curricular
offerings, fгom innovative robotics ϲlubs tһat encourage technological imagination tߋ symphony orchestras tһаt refine musical skills, enables trainees to
fіnd and fine-tune their unique capabilities in a encouraging аnd revitalizing environment.
Ᏼy incorporating service learning initiatives, ѕuch as
neighborhood outreach projects ɑnd volunteer programs ƅoth in your area аnd worldwide, the college cultivates
a strong sense ᧐f social obligation, compassion, ɑnd active citizenship among its student body.
Graduates оf Anglo-Chinese School (Independent) Junior College аre incredjbly ᴡell-prepared for entry into elite universities aгound the world,
carrying with them ɑ distinguished tradition of academic
quality, personal stability, аnd a dedication to lifelong
learning ɑnd contribution.
Goodness, еven though institution remains atas, mathematics іs the
critical topic to developing confidence rеgarding numbers.
Oh no, primary mathemayics teaches everyday implementations ѕuch aѕ financial planning,
theгefore guardantee уօur youngster masters tһat right starting үoung age.
Aiyah, primary mathematics educates everyday implementations ѕuch as financial
planning, ѕo ensure yօur youngster gets this correctly begіnning eɑrly.
Folks, competitive mode οn lah, solid primary math leads
fⲟr improved science grasp ɑnd engineering goals.
Failing t᧐ do wеll in A-levels mіght mean retaking օr going
poly,bᥙt JC route iis faster if you score һigh.
Alas, lacking strong maths Ԁuring Junior College, гegardless
leading institution youngsters mіght struggle wіtһ next-level
algebra, tһerefore build tһаt promptly leh.
Ѕtoⲣ by my homepagе: next level math tutoring
next level math tutoring
19 Sep 25 at 9:06 am
фильмы про войну смотреть онлайн [url=https://kinogo-14.top]https://kinogo-14.top[/url] .
kinogo_hkEl
19 Sep 25 at 9:06 am
фильмы про войну смотреть онлайн [url=http://kinogo-15.top]фильмы про войну смотреть онлайн[/url] .
kinogo_tksa
19 Sep 25 at 9:06 am
займы всем [url=www.zaimy-13.ru/]www.zaimy-13.ru/[/url] .
zaimi_odKt
19 Sep 25 at 9:07 am
Howdy! I just would like to give you a huge thumbs up for your great info you’ve got right here on this post.
I will be returning to your web site for more soon.
kprslot99
19 Sep 25 at 9:07 am
Здравствуйте!
Виртуальный номер навсегда – это идеальное решение для тех, кто ценит стабильность и удобство. Купите постоянный виртуальный номер для смс и используйте его для регистрации, работы и переписки. Мы предоставляем качественные услуги с гарантией надежности. Постоянный виртуальный номер – это удобный инструмент для повседневного использования. Заказывайте у нас и оставайтесь на связи.
Полная информация по ссылке – https://andersonyugq53086.get-blogging.com/27279325/alles-wat-je-moet-weten-over-duitse-mobiele-nummers-een-complete-gids
купить виртуальный номер навсегда, купить виртуальный номер, виртуальный номер телефона
Виртуальные номера, купить виртуальный номер для смс навсегда, купить виртуальный номер навсегда
Удачи и комфорта в общении!
Nomersulge
19 Sep 25 at 9:08 am
фильмы про войну смотреть онлайн [url=www.kinogo-14.top/]www.kinogo-14.top/[/url] .
kinogo_miEl
19 Sep 25 at 9:09 am
все микрозаймы онлайн [url=www.zaimy-13.ru]www.zaimy-13.ru[/url] .
zaimi_ymKt
19 Sep 25 at 9:09 am
все займы рф [url=www.zaimy-15.ru/]www.zaimy-15.ru/[/url] .
zaimi_lqpn
19 Sep 25 at 9:10 am
Appreciation to my father who informed me about
this weblog, this weblog is in fact amazing.
web site
19 Sep 25 at 9:10 am
все микрозаймы на карту [url=www.zaimy-14.ru]www.zaimy-14.ru[/url] .
zaimi_qgSr
19 Sep 25 at 9:11 am
электрокарниз двухрядный [url=razdvizhnoj-elektrokarniz.ru]razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_jaei
19 Sep 25 at 9:12 am
Nice blog here! Also your site loads up fast!
What web host are you using? Can I get your affiliate
link to your host? I wish my site loaded up as fast as yours lol
รับทำบรรจุภัณฑ์หาดใหญ่
19 Sep 25 at 9:12 am
EverTrustMeds [url=https://evertrustmeds.com/#]Cialis 20mg price in USA[/url] EverTrustMeds
Michealstilm
19 Sep 25 at 9:12 am
микрозаймы онлайн [url=https://zaimy-12.ru/]микрозаймы онлайн[/url] .
zaimi_ccSt
19 Sep 25 at 9:13 am
все займ [url=https://zaimy-15.ru]https://zaimy-15.ru[/url] .
zaimi_kepn
19 Sep 25 at 9:15 am
В этой публикации мы предлагаем подробные объяснения по актуальным вопросам, чтобы помочь читателям глубже понять их. Четкость и структурированность материала сделают его удобным для усвоения и применения в повседневной жизни.
Полезно знать – https://www.encouragingblogs.com/2023/08/intitlewelcome-intextlogin-guide-to-html
Robertsnums
19 Sep 25 at 9:15 am
смотреть фильмы бесплатно [url=www.kinogo-15.top/]смотреть фильмы бесплатно[/url] .
kinogo_absa
19 Sep 25 at 9:15 am
: – Clear Meds Hub
DerekStops
19 Sep 25 at 9:15 am
I think this is one of the most significant info for me.
And i am glad reading your article. But should remark on few
general things, The web site style is great, the articles is really nice
: D. Good job, cheers
kprslot99
19 Sep 25 at 9:16 am
https://allmynursejobs.com/author/caxapok80light/
RonaldWep
19 Sep 25 at 9:18 am
смотреть боевики [url=www.kinogo-14.top/]смотреть боевики[/url] .
kinogo_zeEl
19 Sep 25 at 9:19 am
электрические карнизы купить [url=www.razdvizhnoj-elektrokarniz.ru/]www.razdvizhnoj-elektrokarniz.ru/[/url] .
razdvijnoi elektrokarniz_dzei
19 Sep 25 at 9:19 am