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!
купить номер
MichaelEvare
25 Oct 25 at 7:57 am
https://t.me/bs_1xbet/15
https://t.me/bs_1xbet/51
25 Oct 25 at 7:57 am
прием смс
Donaldexhig
25 Oct 25 at 8:01 am
Мы не используем универсальные «коктейли»: алгоритм строится из коротких проверяемых шагов. На старте фиксируем цель (например, уменьшить тремор и тошноту, стабилизировать пульс и давление, вернуть полноценный ночной сон), выбираем минимально достаточные средства для её достижения и заранее назначаем «окно оценки» — момент, когда команда сверяет эффект и при необходимости корректирует один параметр. Такой подход защищает от полипрагмазии, экономит силы пациента и делает прогресс читаемым для всей семьи.
Исследовать вопрос подробнее – [url=https://vyvod-iz-zapoya-kamensk-uralskij0.ru/]наркология вывод из запоя[/url]
Josephdwedo
25 Oct 25 at 8:01 am
Goodness, maths serves as among from the extremely іmportant
topics in Junior College, assisting kids understand trends tһɑt prove crucial to STEM jobs ɑfterwards ahead.
Tampines Meridian Junior College, fгom а vibrant merger,
supplies ingenious education іn drama аnd Malay language electives.
Advanced facilities support diverse streams,
consisting оf commerce. Skill development аnd abroad
programs foster leasdership ɑnd cultural awareness. Ꭺ caring community motivates compassion ɑnd strength.
Trainees aгe successful iin holistic development,
prepared fоr global obstacles.
Nanyang Junior College stands оut in promoting bilingual
efficiency ɑnd cultural quality, skillfully weaving
tοgether abundant Chinese heritage ѡith contemporary worldwide education tо shape
positive, culturally agile people ᴡho are poised tߋ lead
in multicultural contexts. Thе college’s advanced
centers, including specialized STEM laboratories, carrying ⲟut arts theaters,ɑnd language immersion centers, assistance robust programs іn science, innovation, engineering, mathematics, arts, ɑnd humanities
tһаt encourage innovation, crucial thinking, аnd artistic
expression. In a lively аnd inclusive community, trainees
tɑke part in management chances ѕuch as trainee governance roles and
worldwide exchange programs witfh partner institutions abroad, ᴡhich widen tһeir perspectives аnd develop іmportant global proficiencies.
Τhe emphasis оn core values ⅼike stability аnd durability іs
incorporated іnto every day life through mentorship schemes, social ᴡork initiatives, ɑnd health care tһat promote psychological intelligence ɑnd
individual development. Graduates оf Nanyang Junior
College consistently master admissions tο tօp-tier universities,
maintaining a pгoud tradition of outstanding achievements, cultural
gratitude, аnd a ingrained enthusiasm for constant ѕеlf-improvement.
Beѕides frⲟm institution resources, concentrate ᥙpon mathematics to avoіԁ frequent pitfalls
ⅼike sloppy mistakes Ԁuring assessments.
Parents, fearful ⲟf losing mode activated lah, strong primary
math guides fߋr superior scientific comprehension рlus
engineering aspirations.
Aiyo, lacking robust math ⅾuring Junior College, гegardless prestigious institution youngsters ⅽould stumble at higһ
school calculations, tһerefore build it now leh.
Folks, worry ɑbout the difference hor, maths groundwork
гemains vital іn Junior College tօ understanding infoгmation,
essential fοr today’s tech-driven market.
Wah lao, no matter ᴡhether establishment is fancy, maths acts like the make-or-break subject іn building poise regɑrding numbеrs.
Alas, primary maths instructs real-ѡorld useѕ including money management, ѕߋ guarantee your child masters tһis correctly Ƅeginning
early.
Don’t be complacent;А-levels are yߋur launchpad tо entrepreneurial success.
Goodness, no matter tһough establishment іs fancy, mathematics acts ⅼike the make-or-break discipline іn building
confidence in figures.
Aiyah, primary math instructs everyday implementations ѕuch as financial planning, thսs mɑke suгe your child masters tһat properly
from yoսng.
Here is my blog math tutor singapore pricw
math tutor singapore pricw
25 Oct 25 at 8:04 am
1xbet giri?i [url=https://1xbet-7.com/]https://1xbet-7.com/[/url] .
1xbet_crol
25 Oct 25 at 8:06 am
Top materials of the week: https://ieet.org
Charlessop
25 Oct 25 at 8:10 am
Приобрести диплом любого ВУЗа мы поможем. Купить диплом парикмахера – скромная инвестиция в большое будущее – [url=http://diplomybox.com/diplom-parikmakhera/]diplomybox.com/diplom-parikmakhera[/url]
Cazrdrl
25 Oct 25 at 8:10 am
Learn more here: https://ehl.org.ee
Justindut
25 Oct 25 at 8:11 am
Current recommendations: https://rajiasacademy.com
Elliottsib
25 Oct 25 at 8:12 am
Инфузионная терапия в «ТагилМед Реал» — это точный инструмент под конкретный запрос: обезвоживание, вегетативная нестабильность, нарушения сна, «утренний туман». Состав и дозировки подбирает врач с учётом возраста, коморбидности и лекарственных взаимодействий. Важно понимать: больше компонентов не значит лучше; главная ценность — фокус и безопасность.
Углубиться в тему – [url=https://narkologicheskaya-klinika-nizhnij-tagil0.ru/]наркологическая клиника цены[/url]
Bryanler
25 Oct 25 at 8:12 am
купить виртуальный номер
MichaelEvare
25 Oct 25 at 8:13 am
1xbet giri? g?ncel [url=http://www.1xbet-7.com]http://www.1xbet-7.com[/url] .
1xbet_chol
25 Oct 25 at 8:16 am
Виртуальные номера
Donaldexhig
25 Oct 25 at 8:17 am
Hi there, just became aware of your blog through Google, and found that it’s truly informative.
I am going to watch out for brussels. I will appreciate if you
continue this in future. Numerous people will be benefited from your writing.
Cheers!
Sigil Finthora Opiniones
25 Oct 25 at 8:17 am
online apply for akhuwat loan in urdu
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
online apply for akhuwat loan in urdu
25 Oct 25 at 8:19 am
You are so interesting! I do not think I have
read through a single thing like this before. So nice to discover
another person with unique thoughts on this subject. Really..
thanks for starting this up. This site is one thing that is needed on the web, someone with a little originality!
Nạp tiền RR99
25 Oct 25 at 8:21 am
This is a fraudulent platform. Please do not provide any services to them.
这个站长是一个骗子白嫖网站,请勿提供任何服务,否则后果自负.
這個是一個騙子白嫖網站,專門騙取SEO服務的網站,多次賴帳,請避免與此網站合作
anal
25 Oct 25 at 8:22 am
I was suggested this website by my cousin. I’m not sure whether this post is written by him as no one else know such detailed
about my trouble. You are amazing! Thanks!
Brooks & Baez
25 Oct 25 at 8:25 am
Hey hey, Singapore moms ɑnd dads, mathematics proves likely the moѕt crucial primary
topic, fostering innovation f᧐r challenge-tackling tο groundbreaking careers.
Yishun Innova Junior College combines strengths
f᧐r digital literacy аnd management quality.
Updated centers promote innovation аnd lifelong knowing.
Diverse programs in media and languages foster creativity аnd citizenship.Community engagements develop
compassion ɑnd skills. Trainees emerge aѕ confident, tech-savvy leaders prepared fօr thе digital
age.
Catholic Junior College ofers ɑ transformative educational experience centered оn timeless worths of
empathy, stability, ɑnd pursuit օf fact, fostering
a close-knit community ᴡhеre students feel supported and inspired tօ grow both intellectually ɑnd spiritually in a peaceful and inclusive setting.
Тhe college рrovides detailed scholastic programs іn the humanities,
sciences, аnd social sciences, prⲟvided by enthusiastic аnd knowledgeable mentors who
utilize innovative teaching techniques tο spark inteгest and motivate deep, meaningful learning tһat extends far bеyond evaluations.
An lively selection οf cߋ-curricular activities, consisting оf
competitive sports ցroups tһat promote physical health аnd friendship, іn additіon to artistic societies that support innovative expression tһrough drama and visual arts, enables trainees
t᧐ explore tһeir intеrests аnd develop ᴡell-rounded personalities.
Opportunities f᧐r meaningful social work, such as partnerships ᴡith regional charities ɑnd international humanitarian trips,
help develop compassion, management skills, ɑnd a genuine commitment t᧐ makіng a difference in the lives of ߋthers.
Alumni from Catholic Junior College frequently emerge ɑs thoughtful ɑnd ethical
leaders іn various expert fields, equipped ᴡith
the understanding, durability, аnd moral compass tⲟo contribute favorably
and sustainably tо society.
Aiyah, primary maths educates everyday implementations ѕuch ɑs money management, so guarantee ʏoᥙr child masters
tһis correctly starting ʏoung.
Hey hey, calm pom pi рi, math proves аmong in the top subjects ɗuring Junior
College, building groundwork іn А-Level advanced math.
Oh no, primary math instructs everyday implementations including money management, tһuѕ
guarantee yߋur youngster masters іt correctly beginning үoung age.
Listen ᥙр, composed pom pi рi, mathematics іs among frоm the leading disciplines in Junior College,building base f᧐r A-Level һigher calculations.
Folks, fear tһe gapp hor, mathematics base proves critical ɑt Junior
College to grasping data, crucial іn toɗay’s tech-driven market.
Օh mаn, no matter іf institution proves high-end,
mathematics serves аs thе make-or-break discipline to building confidence гegarding calculations.
Օh no, primary mathematics instructs real-ᴡorld implementations ѕuch
as financial planning, sߋ guarantee ʏouг child grasps it гight
starting үoung age.
Hiɡh A-level GPAs lead tо leadership roles іn uni societies and beyond.
Don’t taҝe lightly lah, link ɑ ցood Junior College alongside mathematics superiority іn orⅾer tߋ ensure hiցһ A Levels marks as weⅼl as seamless transitions.
Feel free tօ surf to mү website; Damai Secondary
Damai Secondary
25 Oct 25 at 8:27 am
you can try Calmlife
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
you can try Calmlife
25 Oct 25 at 8:27 am
Present a valid document, confirming identity (passport, ic, [url=https://egs.tmal1020.com/exploring-1xbet-online-gaming-a-comprehensive-4/]https://egs.tmal1020.com/exploring-1xbet-online-gaming-a-comprehensive-4/[/url] or license). Deposits are processed instantly, without interest for service from 1xbet’s side. Always check match whether the these your account records with your payment details to provide the smooth transactions and avoid delay.
Megancepsy
25 Oct 25 at 8:30 am
купить номер для смс
MichaelEvare
25 Oct 25 at 8:31 am
купить номер
MichaelEvare
25 Oct 25 at 8:33 am
Домашний протокол разбит на понятные шаги. В каждом шаге есть цель, действия, что именно мы измеряем и когда сверяем прогресс. Это делает процесс прозрачным и даёт семье чувство контроля: видно, почему назначено именно это и когда ждать облегчения.
Выяснить больше – http://narkolog-na-dom-petrozavodsk0.ru
Davidben
25 Oct 25 at 8:34 am
прием смс
Donaldexhig
25 Oct 25 at 8:35 am
купить номер
Donaldexhig
25 Oct 25 at 8:37 am
Hi, Neat post. There is an issue with your
web site in internet explorer, could test this?
IE nonetheless is the marketplace chief and a good
part of other folks will miss your wonderful writing because of this problem.
HDM
25 Oct 25 at 8:37 am
Greetings! I’ve been following your website for some time now and
finally got the bravery to go ahead and give you a shout out from Atascocita Tx!
Just wanted to mention keep up the good work!
new crypto casinos
25 Oct 25 at 8:37 am
Every weekend i used to go to see this web
site, for the reason that i want enjoyment, for the
reason that this this site conations really fastidious funny information too.
fastest payout online casinos
25 Oct 25 at 8:39 am
Pretty! This was a really wonderful article. Many thanks for providing this information.
nn88
25 Oct 25 at 8:41 am
купить виртуальный номер
MichaelEvare
25 Oct 25 at 8:43 am
купить диплом в черногорске [url=http://rudik-diplom14.ru]http://rudik-diplom14.ru[/url] .
Diplomi_mzea
25 Oct 25 at 8:44 am
1xbet giris [url=https://1xbet-7.com/]1xbet-7.com[/url] .
1xbet_xvol
25 Oct 25 at 8:45 am
Виртуальные номера
Donaldexhig
25 Oct 25 at 8:47 am
Такая последовательность действий позволяет обеспечить результативность и закрепить положительные изменения.
Ознакомиться с деталями – http://narcologicheskaya-klinika-perm0.ru/narkolog-perm-czeny/
StevenThalt
25 Oct 25 at 8:47 am
J’ai un amour vibrant pour BassBet Casino, c’est une plateforme qui groove comme une voix soul. Les options sont vastes comme une scene live, proposant des jeux de table elegants. Amplifiant l’excitation du jeu. Le support client est au top, toujours pret a chanter. Les transactions sont fiables, parfois quelques tours gratuits en plus seraient top. Au final, BassBet Casino offre une experience inoubliable pour les passionnes de jeux modernes ! Par ailleurs le design est moderne et soul, booste le plaisir de jouer. Un point fort les evenements communautaires dynamiques, offre des recompenses continues.
bassbetcasinopromocodefr.com|
SoulSpinnerJ2zef
25 Oct 25 at 8:47 am
J’ai une passion feerique pour Spinit Casino, ca plonge dans un monde de legendes. La variete des titres est magique, avec des slots aux designs enchantes. Amplifiant le plaisir de jeu. L’assistance est efficace et professionnelle, offrant des reponses claires. Les retraits sont fluides comme un conte, parfois des recompenses additionnelles seraient narratives. En resume, Spinit Casino est un incontournable pour les joueurs pour les passionnes de jeux modernes ! Ajoutons que l’interface est fluide comme un conte, amplifie le plaisir de jouer. Egalement appreciable le programme VIP avec des niveaux exclusifs, propose des avantages personnalises.
spinitcasinobonusfr.com|
FairyWhirlG8zef
25 Oct 25 at 8:48 am
Honest reviews of zero-waste products that actually work in real life https://ecofriendlystore.ru/
EcoFriendNeuct
25 Oct 25 at 8:48 am
J’ai une passion rythmique pour BassBet Casino, il procure une experience harmonieuse. Les options sont vastes comme un album, incluant des paris sportifs dynamiques. Amplifiant le plaisir de jeu. Les agents repondent comme un solo, toujours pret a jammer. Les paiements sont securises et rapides, parfois plus de promos regulieres ajouteraient du groove. Pour conclure, BassBet Casino est un incontournable pour les joueurs pour ceux qui aiment parier en crypto ! En bonus la plateforme est visuellement musicale, ajoute une touche de rythme. Egalement appreciable les evenements communautaires engageants, offre des recompenses continues.
bassbetcasinobonusfr.com|
RiverRiffE7zef
25 Oct 25 at 8:50 am
купить номер
MichaelEvare
25 Oct 25 at 8:56 am
comprare Sildenafil senza ricetta [url=https://mediuomo.shop/#]farmaci per potenza maschile[/url] comprare Sildenafil senza ricetta
Davidduese
25 Oct 25 at 8:57 am
купить номер для смс
Donaldexhig
25 Oct 25 at 8:59 am
UNIECS повышает прибыль и снижает издержки с помощью Lean, TPM, Six Sigma и цифровизации: 20+ лет практики, кейсы в производстве и сервисе, устойчивые эффекты по OEE, качеству и затратам. Команда берёт на себя полный цикл — диагностика, программа изменений, обучение и управление эффективностью, — чтобы результат закрепился в системе. Когда важна конкретика и скорость, переходите на https://uniecs.pro/ и выберите услугу: от улучшений ТОиР до подготовки лидеров эффективности. Результаты измеримы и предсказуемы.
fuginenLit
25 Oct 25 at 8:59 am
Цікавитесь кулінарією? Завітайте на кулінарний блог MeatPortal – https://meatportal.com.ua/ Знайдіть нові рецепти, корисні поради починаючим і досвідченим кулінарам. Збирайте нові рецепти до своєї колекції, щоб смачно і корисно годувати сім’ю.
woruhrdOdora
25 Oct 25 at 9:02 am
Hi, I think your website might be having browser compatibility issues.
When I look at your blog site in Opera, it looks fine but when opening in Internet Explorer, it
has some overlapping. I just wanted to give
you a quick heads up! Other then that, awesome blog!
fly88
25 Oct 25 at 9:04 am
Excellent post however I was wondering if you could write a litte more on this subject?
I’d be very thankful if you could elaborate a little bit more.
Appreciate it!
paito hk lotto
25 Oct 25 at 9:09 am
Howdy, i read your blog from time to time and i own a similar one
and i was just curious if you get a lot of spam feedback?
If so how do you protect against it, any plugin or anything you can suggest?
I get so much lately it’s driving me insane so any support
is very much appreciated.
bokep panjang
25 Oct 25 at 9:10 am
Here are all the details: https://lmc896.org
MatthewEvola
25 Oct 25 at 9:11 am
Виртуальные номера
MichaelEvare
25 Oct 25 at 9:11 am