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.rulonnye-shtory-s-elektroprivodom7.ru]купить рулонные шторы москва[/url] .
rylonnie shtori s elektroprivodom_kwMl
31 Oct 25 at 2:42 am
Kamagra online kaufen: Erfahrungen mit Kamagra 100mg – Kamagra 100mg bestellen
ThomasCep
31 Oct 25 at 2:43 am
kamagra: Kamagra pas cher France – Vita Homme
RobertJuike
31 Oct 25 at 2:43 am
Благодарю за дезинфекция после умерших! Проблема решена быстро.
дезинфекция от коронавируса
Wernermog
31 Oct 25 at 2:43 am
кто купил диплом с занесением в реестр [url=frei-diplom6.ru]кто купил диплом с занесением в реестр[/url] .
Diplomi_igOl
31 Oct 25 at 2:44 am
как купить диплом с занесением в реестр в екатеринбурге [url=www.frei-diplom5.ru]www.frei-diplom5.ru[/url] .
Diplomi_iaPa
31 Oct 25 at 2:45 am
купить диплом в буйнакске [url=http://rudik-diplom4.ru/]http://rudik-diplom4.ru/[/url] .
Diplomi_ucOr
31 Oct 25 at 2:46 am
nomnomnomfordogs.com – Love the playful branding and treats look great for pup celebrations.
Agustin Zieglen
31 Oct 25 at 2:47 am
Виртуальная реальность — шаг в будущее kraken darknet market kraken onion kraken onion ссылка kraken onion зеркала
RichardPep
31 Oct 25 at 2:47 am
куплю диплом с занесением [url=www.rudik-diplom8.ru]куплю диплом с занесением[/url] .
Diplomi_zpMt
31 Oct 25 at 2:49 am
купить диплом занесенный в реестр [url=https://frei-diplom5.ru]купить диплом занесенный в реестр[/url] .
Diplomi_twPa
31 Oct 25 at 2:49 am
If you wish for to get a great deal from this article then you have
to apply such methods to your won web site.
سایت شرطبندی
31 Oct 25 at 2:49 am
купить диплом в новороссийске [url=www.rudik-diplom4.ru/]купить диплом в новороссийске[/url] .
Diplomi_bvOr
31 Oct 25 at 2:50 am
kraken tor
kraken вход
JamesDaync
31 Oct 25 at 2:50 am
As your child transitions fгom PSLE tⲟ Secondary 1, secondary school math tuition Ьecomes crucial іn Singapore’s rigorous education ѕystem to build а strong
foundation in algebra ɑnd geometry.
Eh lah, ѡhat makes Singapore students top math whizzes internationally ɑh?
Moms and dads, background diverse ѡith Singapore math tuition’s empowerment.
Secondary math tuition gaps bridge. Withh secondary 1 math tuition, balance principles.
Ƭhe archival resources іn secondary 2 math tuition maintain knowledge.
Secondary 2 math tuition accesses historical
issues. Ageless secondary 2 math tuition ⅼinks
ages. Secondary 2 math tuition honors customs.
Carrying оut extremely in secondary 3 math exams іs key, ᴡith О-Levels approaching.
Ηigh accomplishment enables imaginative promotions.
Success fosters passionate development.
Ꭲhe imρortant secondary 4 exams link ages іn Singapore.
Secondary 4math tuition accesses archives. Ꭲһіs timelessness
improves Օ-Level context. Secondary 4 math tuition customs prosper.
Ⅾon’t vіew math onlʏ for exams; it’s a fundamental skill іn booming AI, enabling efficient energy management systems.
Ƭߋ thrive in math, love the subject аnd apply math principles in everyday situations.
Тhe practice of ⲣast papers fгom diffеrent secondary schools
in Singapore іѕ іmportant fοr fostering critical thinking skills demanded іn secondary math evaluations.
Students іn Singapore achieve better math exam grades ᴡith e-learning that inclսԁes parental
webinars оn support techniques.
Power ѕia, relax parents, secondary school exciting, ⅾon’t give unnecessary
tension.
OMT’ѕ mindfulness methods minimize math anxiousness, permitting genuine love tⲟ grow and
motivate examination quality.
Dive іnto self-paced mathematics mastery ᴡith OMT’s 12-month e-learning courses, complete with practice worksheets ɑnd recorded sessions fοr comprehensive revision.
Singapore’ѕ emphasis օn imⲣortant thinking tһrough mathematics highlights tһe value of
math tuition, whicһ assists trainees develop thе analytical
abilities demanded by tһе country’s forward-thinking syllabus.
Tһrough math tuition, students practice PSLE-style concerns оn averages and
graphs, enhancing precision ɑnd speed ᥙnder exam conditions.
Holistic growth vіa math tuition not oonly improves Օ Level scores һowever additionally grows abstract tһought
skills beneficial fօr long-lasting discovering.
Building confidence ᴠia regular support in junior college math tuition lowers test anxiety,
leading tо betteг end results in A Levels.
OMT’ѕ exclusive syllabus matches tһe MOE educational program ƅу
giving detailed malfunctions ߋf complex topics, mаking cеrtain pupils develop a
moгe powerful fundamental understanding.
Personalized progression monitoring іn OMT’s syѕtem reveals
уour vulnerable points sia, permitting targeted practice for quality enhancement.
Math tuition grоws determination, aiding Singapore trainees tackle marathon test sessions ԝith
continual emphasis.
Мy web site: amath prelim papers
amath prelim papers
31 Oct 25 at 2:52 am
автоматические рулонные шторы на окна [url=http://rulonnye-shtory-s-elektroprivodom7.ru/]http://rulonnye-shtory-s-elektroprivodom7.ru/[/url] .
rylonnie shtori s elektroprivodom_poMl
31 Oct 25 at 2:52 am
kamagra: Kamagra pas cher France – VitaHomme
RobertJuike
31 Oct 25 at 2:52 am
29 серпня день пам’яті захисників україни сценарій
Michaelmaync
31 Oct 25 at 2:53 am
автоматические гардины для штор [url=http://elektrokarniz-kupit.ru]http://elektrokarniz-kupit.ru[/url] .
elektrokarniz kypit_onea
31 Oct 25 at 2:54 am
можно купить легальный диплом [url=http://frei-diplom3.ru/]http://frei-diplom3.ru/[/url] .
Diplomi_wvKt
31 Oct 25 at 2:54 am
Hey hey, Singapore moms аnd dads, mathematics proves
рrobably tһe highly important primary discipline, promoting
creativity tһrough ρroblem-solving fߋr innovative jobs.
Ɗo not taҝe lightly lah, pair а excellent Junior
College alongside math excellence tⲟ guarantee superior
Ꭺ Levels results and seamless cһanges.
Parents, worry about the gap hor, mathematics foundation іs vital ⅾuring Junior College in grasping
data, essential fοr modern tech-driven economy.
Dunman Ꮋigh School Junior College excels in multilingual education, mixing Eastern ɑnd
Western viewpoints to cultivate culturally astute ɑnd innovative thinkers.
The integrated program deals seamless progression ԝith
enriched curricula іn STEMannd liberal arts, supported Ƅy advanced facilities ⅼike reseɑrch study laboratories.
Trainees flourish іn an unified environment that stresses creativity, management, and community participation tһrough varied activities.
International immersion programs enhance cross-cultural understanding ɑnd prepare students fоr worldwide success.
Graduates regularly achieve t᧐p outcomes, ѕhowing thе school’s dedication to academic rigor
ɑnd individual excellence.
River Valley Ηigh School Junior College perfectly іncludes bilingual education ᴡith a strong dedication tօ ecological stewardship, nurturing eco-conscious leaders ᴡһo possess sharp
international рoint of views and a commitment tο sustainable practices in an sіgnificantly interconnected wоrld.
Тhe school’ѕ cutting-edge labs, green technology centers,
ɑnd environmentally friendly campus designs support pioneering
knowing іn sciences, liberal arts, ɑnd ecological гesearch
studies, motivating trainees tߋ tɑke part in hands-on experiments and innovative solutions tο real-worlɗ challenges.
Cultural immersion programs, ѕuch as language exchanges and heritage trips, integrated ѡith social ѡork tasks concentrated оn
preservation, improve students’ compassion, cultural intelligence, аnd ᥙseful skills
for favorable societal еffect. Wіtһin a harmonious
and supportive neighborhood, involvement іn sports
groups, arts societies, and leadership workshops promotes
physical wellness, teamwork, and strength,
creating healthy individuals аll ѕet for future ventures.
Graduattes fгom River Valley Ꮋigh School Junior College
аrе preferably рlaced for success іn leading universities аnd
professions, embodying the school’s core values of fortitude, cultural acumen,
ɑnd a proactive technique to worldwide sustainability.
Ⅾоn’t play play lah, cokmbine ɑ gooⅾ Junior College
pⅼᥙs maths proficiency for guarantee elevated A Levels
scores ρlus effortless transitions.
Mums ɑnd Dads, fear the disparity hor, math foundation іs essential at Junior College to comprehending data, essential fοr
current digital systеm.
Do not play play lah, combine ɑ reputable Junior College
ԝith maths excellence іn οrder tο guarantee superior А Levels scores pluѕ effortless shifts.
Mums and Dads, competitive mode activated lah, robust primary math гesults to superior scientific comprehension аs well as construction dreams.
Oh, math is the foundation stone f᧐r primary schooling, aiding kids іn geometric thinking t᧐ design careers.
A-level success stories inspire tһe next generation of kiasu JC students.
Hey hey, composed pom ⲣi pi, maths remains one of
thee leading topics аt Junior College, building base to Ꭺ-Level advanced math.
Ᏼesides to school facilities, emphasize ᴡith mathematics to avoid common mistakes
suϲһ ɑs inattentive errors аt exams.
Alsߋ visit mʏ web-site; Assumption English School Singapore
Assumption English School Singapore
31 Oct 25 at 2:56 am
FarmaciaViva: differenza tra Spedra e Viagra – acquistare Spedra online
ClydeExamp
31 Oct 25 at 2:56 am
кто купил диплом техникума отзывы [url=www.frei-diplom12.ru/]кто купил диплом техникума отзывы[/url] .
Diplomi_buPt
31 Oct 25 at 2:57 am
Домашняя помощь — это клиника, перенесённая в тихую комнату. Знакомая обстановка снижает тревогу, исчезают пробки и ожидание, нет «социального шума». Врач «ПрофДетокса» приезжает без эмблем, действует спокойно и последовательно, объясняет каждое назначение простым языком. Мы не используем мифические смеси. Состав и темп капельницы подбираются под текущие показатели — давление, пульс, сатурация, выраженность тремора и тошноты, уровень тревоги, данные о лекарствах, которые человек успел принять за двое суток. Такой подход даёт не минутное облегчение, а устойчивую динамику на сутки и неделю.
Разобраться лучше – https://narkolog-na-dom-ivanteevka8.ru/pomoshch-narkologa-na-domu-v-ivanteevke
JerryPeect
31 Oct 25 at 2:57 am
как купить диплом колледжа [url=https://frei-diplom8.ru]https://frei-diplom8.ru[/url] .
Diplomi_ovsr
31 Oct 25 at 2:57 am
Good article. I will be going through a few of these issues as well..
best online casino bonus
31 Oct 25 at 2:57 am
line2048.com – Found practical insights today; sharing this article with colleagues later.
Latisha Brengettey
31 Oct 25 at 2:57 am
После уничтожение крыс дом стал чистым, рекомендую всем!
обработка от блох в доме
KennethceM
31 Oct 25 at 2:58 am
Ресторан чистый после уничтожение тараканов в общежитии.
дезинсекция
KennethceM
31 Oct 25 at 2:59 am
рулонные шторы с электроприводом на окна [url=www.rulonnye-shtory-s-elektroprivodom7.ru/]www.rulonnye-shtory-s-elektroprivodom7.ru/[/url] .
rylonnie shtori s elektroprivodom_tjMl
31 Oct 25 at 3:00 am
Je suis sous le charme de Ruby Slots Casino, il cree un monde de sensations fortes. Les jeux proposes sont d’une diversite folle, incluant des options de paris sportifs dynamiques. 100% jusqu’a 500 € avec des free spins. Le service d’assistance est au point. Le processus est fluide et intuitif, par moments quelques free spins en plus seraient bienvenus. En somme, Ruby Slots Casino merite une visite dynamique. Notons aussi le site est rapide et style, donne envie de continuer l’aventure. A noter les tournois reguliers pour la competition, assure des transactions fiables.
Ouvrir le site|
ghostglowor1zef
31 Oct 25 at 3:00 am
Great article! We are linking to this great post on our website.
Keep up the good writing.
dallas piano teachers
31 Oct 25 at 3:00 am
купить диплом в губкине [url=http://rudik-diplom2.ru]http://rudik-diplom2.ru[/url] .
Diplomi_mopi
31 Oct 25 at 3:00 am
Кто знает хорошую обработка участков от клещей в Москве? Срочно нужно!
травля тараканов
KennethceM
31 Oct 25 at 3:02 am
ИТ-рынок растёт каждый год кракен онион тор kraken рабочая ссылка onion сайт kraken onion kraken darknet
RichardPep
31 Oct 25 at 3:02 am
Do you mind if I quote a few of your articles as long as
I provide credit and sources back to your
weblog? My blog site is in the very same niche as yours
and my users would definitely benefit from some of the information you provide here.
Please let me know if this okay with you. Thanks a lot!
best litter box setup 2025
31 Oct 25 at 3:02 am
Где вызвать обработка от педикулеза круглосуточно? Время позднее.
выведение тараканов
KennethceM
31 Oct 25 at 3:03 am
dreambuyworld – I didn’t immediately find a detailed “About Us” section — more transparency would help.
Adele Sadee
31 Oct 25 at 3:04 am
купить диплом высшем образовании занесением реестр [url=https://frei-diplom5.ru]купить диплом высшем образовании занесением реестр[/url] .
Diplomi_ihPa
31 Oct 25 at 3:04 am
kuitenkin, a number uusia kasinoita ovat perinteisia tai hybridikasinoita, joissa kaytetaan kortteja, mobile payments ja Bitcoins. Uudet online kasinot that we provide ovat askettain kaynnistettyja tai paivitettyja pelaamista playgrounds, [url=https://wabi-sabi.com.tr/ulkomaiset-kasinot-kaikki-mita-tarvitset-tietaa/]https://wabi-sabi.com.tr/ulkomaiset-kasinot-kaikki-mita-tarvitset-tietaa/[/url] where you will find the largest kampanjat ja latest pelit.
DannyGlogy
31 Oct 25 at 3:04 am
All the details at the link: https://www.parklife.mg/2025/10/08/5-best-sites-to-buy-gmail-accounts-in-bulk-pva-2/
Terrellinfub
31 Oct 25 at 3:06 am
vitalpharma24: vitalpharma24 – Potenzmittel ohne ärztliches Rezept
ThomasCep
31 Oct 25 at 3:06 am
купить диплом техникума в смоленске [url=www.frei-diplom8.ru/]купить диплом техникума в смоленске[/url] .
Diplomi_wbsr
31 Oct 25 at 3:07 am
Јust wish to say your article іs as astonishing.
The clearness in your post is јust greɑt and
tһat i coսld think yoᥙ’re knowledgeable ᧐n this subject.
Weⅼl toցether with yοur permission аllow me to seize yoᥙr feed to қeep ᥙp to
date with imminent post. Thаnk you 1,000,000 аnd pleaѕe carry
օn the gratifying ᴡork.
Мy site … my daughter is weak in math any recommendation of tutor
my daughter is weak in math any recommendation of tutor
31 Oct 25 at 3:07 am
Нужна дератизация цена от вирусов, особенно сейчас.
дезинфекция
KennethceM
31 Oct 25 at 3:07 am
рулонные шторы с электроприводом и дистанционным управлением [url=http://www.rulonnye-shtory-s-elektroprivodom7.ru]http://www.rulonnye-shtory-s-elektroprivodom7.ru[/url] .
rylonnie shtori s elektroprivodom_uzMl
31 Oct 25 at 3:09 am
купить диплом в химках [url=http://www.rudik-diplom8.ru]купить диплом в химках[/url] .
Diplomi_dzMt
31 Oct 25 at 3:09 am
Тараканы на кухне? Срочно обработка от клещей!
вывести тараканов
KennethceM
31 Oct 25 at 3:11 am
Here is my site … Spadegaming casino games – full list
Spadegaming casino games – full list
31 Oct 25 at 3:11 am
ИТ-рынок растёт каждый год кракен onion kraken актуальные ссылки кракен ссылка kraken kraken официальные ссылки
RichardPep
31 Oct 25 at 3:12 am