SlideShare une entreprise Scribd logo
1  sur  87
Télécharger pour lire hors ligne
Matters of State
Using Symfony’s Event Dispatcher to 

turn your application into a simple state machine
Photo by jeff_golden
Bon anniversaire Symfony!
About me
• Portland
• twitter.com/kriswallsmith
• github.com/kriswallsmith
• kriswallsmith.net
React
Nicolas Raymond
var HelloWorld = React.createClass({
render: function() {
return (
<div>Hello World</div>
)
}
})
var HelloWorld = React.createClass({
render: function() {
return (
<div>Hello World</div>
)
}
})
JSX
Just the view
(there is no MVC to violate)
One-way data flow
(everything flows from state)
Virtual DOM
(DOM changesets)
“React thinks of UIs as simple state machines. By
thinking of a UI as being in various states and rendering
those states, it's easy to keep your UI consistent.”
https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#components-are-just-state-machines
var Analytics = React.createClass({
getInitialState: function() {
return { clicks: 0 }
},
incrementClicks: function() {
var clicks = this.state.clicks;
this.setState({ clicks: ++clicks });
},
render: function() {
var clicks = this.state.clicks;
return (
<button onClick={this.incrementClicks}>
{clicks} click{clicks == 1 ? '' : 's'}
</button>
)
}
})
var Analytics = React.createClass({
getInitialState: function() {
return { clicks: 0 }
},
incrementClicks: function() {
var clicks = this.state.clicks;
this.setState({ clicks: ++clicks });
},
render: function() {
var clicks = this.state.clicks;
return (
<button onClick={this.incrementClicks}>
{clicks} click{clicks == 1 ? '' : 's'}
</button>
)
}
})
<button id="click_button">
0 click(s)
</button>
$('#my_button').click(function() {
var $btn = $(this);
var clicks = $btn.text().match(/d+/)[0];
var text = clicks + ' click';
if (clicks != 1) text += 's';
$btn.text(text);
})
$('#my_button').click(function() {
var $btn = $(this);
var clicks = $btn.text().match(/d+/)[0];
var text = clicks + ' click';
if (clicks != 1) text += 's';
$btn.text(text);
})
oops…
var Analytics = React.createClass({
getInitialState: function() {
return { clicks: 0 }
},
incrementClicks: function() {
var clicks = this.state.clicks;
this.setState({ clicks: ++clicks });
},
render: function() {
var clicks = this.state.clicks;
return (
<button onClick={this.incrementClicks}>
{clicks} click{clicks == 1 ? '' : 's'}
</button>
)
}
})
Paradigm shift
Imperative vs. Declarative Photo by
Imperative programming
(code that explains how
to reach your goal)
Declarative programming
(code that describes
what your goal is)
Take the next right
• Depress the gas pedal and increase your speed to 10mph
• Engage your right turn signal
• As you approach the intersection, remove your foot from the gas
pedal and gently apply the brake
• Check for pedestrians crossing the intersection
• Check your mirrors and blind spot for bicyclists
• Lift your foot from the brake and slowly increase speed by
depressing the gas pedal
• Turn the steering wheel to the right
Take the next right
• Depress the gas pedal and increase your speed to 10mph
• Engage your right turn signal
• As you approach the intersection, remove your foot from the gas
pedal and gently apply the brake
• Check for pedestrians crossing the intersection
• Check your mirrors and blind spot for bicyclists
• Lift your foot from the brake and slowly increase speed by
depressing the gas pedal
• Turn the steering wheel to the right
declarative
Take the next right
• Depress the gas pedal and increase your speed to 10mph
• Engage your right turn signal
• As you approach the intersection, remove your foot from the gas
pedal and gently apply the brake
• Check for pedestrians crossing the intersection
• Check your mirrors and blind spot for bicyclists
• Lift your foot from the brake and slowly increase speed by
depressing the gas pedal
• Turn the steering wheel to the right
imperative
$('#my_button').click(function() {
var $btn = $(this);
var clicks = $btn.text().match(/d+/)[0];
var text = clicks + ' click';
if (clicks != 1) text += 's';
$btn.text(text);
})
var Analytics = React.createClass({
getInitialState: function() {
return { clicks: 0 }
},
incrementClicks: function() {
var clicks = this.state.clicks;
this.setState({ clicks: ++clicks });
},
render: function() {
var clicks = this.state.clicks;
return (
<button onClick={this.incrementClicks}>
{clicks} click{clicks == 1 ? '' : 's'}
</button>
)
}
})
How vs. What
SELECT * FROM users WHERE username="kriswallsmith";
PHP controllers
public function registerAction(Request $request)
{
$form = $this->createForm('user');
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
$message = Swift_Message::newInstance()
->setTo($user->getEmail())
->setSubject('Welcome!')
->setBody($this->renderView(
'AppBundle:Email:welcome.html.twig',
['user' => $user]
));
$mailer = $this->get('mailer');
$mailer->send($message);
$em = $this->get('doctrine')->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('home');
}
return $this->render(
'AppBundle:User:register.html.twig',
['form' => $form->createView()]
);
}
public function registerAction(Request $request)
{
$form = $this->createForm('user');
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
$mailer = $this->get('app.mailer');
$mailer->sendWelcomeEmail($user);
$em = $this->get('doctrine')->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('home');
}
return $this->render(
'AppBundle:User:register.html.twig',
['form' => $form->createView()]
);
}
public function registerAction(Request $request)
{
$form = $this->createForm('user');
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
$mailer = $this->get('app.mailer');
$mailer->sendWelcomeEmail($user);
$em = $this->get('doctrine')->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('home');
}
return $this->render(
'AppBundle:User:register.html.twig',
['form' => $form->createView()]
);
}
declarative!
Why stop there?
public function registerAction(Request $request)
{
$form = $this->createForm('user');
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->get('doctrine')->getManager();
$em->persist($form->getData());
$em->flush();
return $this->redirectToRoute('home');
}
return $this->render(
'AppBundle:User:register.html.twig',
['form' => $form->createView()]
);
}
Excuse me Kris,

but what about the email?
Photo by
Event Dispatcher
Photo by rhodesj
The Event Dispatcher component provides
tools that allow your application components
to communicate with each other by
dispatching events and listening to them.
symfony.com
public function addListener(
$eventName,
$listener,
$priority = 0
);
public function dispatch(
$eventName,
Event $event = null
);
$dispatcher->dispatch('user.create');
$dispatcher->dispatch(
'user.create',
new UserEvent($user)
);
$dispatcher->dispatch(
UserEvents::CREATE,
new UserEvent($user)
);
$dispatcher->addListener(
UserEvents::CREATE,
function(UserEvent $event) {
echo "Welcome, {$event->getUserName()}!";
}
);
$dispatcher->addListener(
UserEvents::CREATE,
[$listener, 'onUserCreate']
);
Something just happened
or is about to happen
Photo by Simon Law
Reactive Listeners
class UserListener
{
public function onUserCreate(UserEvent $event)
{
$user = $event->getUser();
$this->mailer->sendWelcomeEmail($user);
}
}
class ActivityFeedListener
{
public function onUserCreate(UserEvent $event)
{
$user = $event->getUser();
$this->feed->logRegistration($user);
}
}
class ActivityFeedListener
{
public function onFollow(UserUserEvent $event)
{
$user = $event->getUser();
$otherUser = $event->getOtherUser();
$this->feed->logFollow($user, $otherUser);
}
}
Testable
Reusable
Readable
State Events
Where do they come from?
Option 1: Controller dispatch
public function registerAction(Request $request)
{
$form = $this->createForm('user');
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
$dispatcher = $this->get('event_dispatcher');
$dispatcher->dispatch(UserEvents::CREATE, new UserEvent($user));
$em = $this->get('doctrine')->getManager();
$em->persist();
$em->flush();
return $this->redirectToRoute('home');
}
return $this->render(
'AppBundle:Register:register.html.twig',
['form' => $form->createView()]
);
}
Option 2: Service dispatch
class UserManager
{
public function persistUser(User $user)
{
$this->em->persist($user);
$this->dispatcher->dispatch(
UserEvents::CREATE,
new UserEvent($user)
);
}
}
Option 3: Flush dispatch
class FlushListener
{
public function preFlush(PreFlushEventArgs $event)
{
$em = $event->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getIdentityMap() as $class => $objects) {
if (User::class === $class) {
foreach ($objects as $user) {
if ($uow->isScheduledForInsert($user)) {
$this->dispatcher->dispatch(
UserEvents::CREATE,
new UserEvent($user)
);
}
}
}
}
}
}
a simple state machine
Cool, but…
That flush listener is ugly…
…and imperative!
What if…
Photo by Jared Cherup
What if…
/** @OnCreate(UserEvents::CREATE) */
class User
{
}
/** @OnChange(UserEvents::CHANGE) */
class User
{
}
/** @OnDestroy(UserEvents::DESTROY) */
class User
{
}
/**
* @OnCreate(UserEvents::CREATE)
* @OnUpdate(UserEvents::UPDATE)
* @OnDestroy(UserEvents::DESTROY)
*/
class User
{
}
Property events
class User
{
/** @OnChange(UserEvents::USERNAME_CHANGE) */
private $username;
}
class User
{
/**
* @OnAdd(UserEvents::FAVORITE)
* @OnRemove(UserEvents::UNFAVORITE)
*/
private $favorites;
}
Conditional events
class User
{
/**
* @OnAdd(
* UserEvents::FIRST_FAVORITE,
* unless="old_value()"
* )
*/
private $favorites;
}
Custom event objects
class User
{
/**
* @OnAdd(
* UserEvents::FOLLOW,
* class=UserUserEvent::class,
* arguments="[object, added_value()]"
* )
*/
private $follows;
}
Event dependencies
class User
{
/**
* @OnAdd(
* UserEvents::FOLLOW,
* before=ActivityEvents::CREATE
* )
*/
private $follows;
}
kriswallsmith/state-events
(coming soon)
Merci!

Contenu connexe

Tendances

jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
Rebecca Murphey
 

Tendances (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event Sourcing
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5amsterdamjs - jQuery 1.5
amsterdamjs - jQuery 1.5
 
An Introduction to Jquery
An Introduction to JqueryAn Introduction to Jquery
An Introduction to Jquery
 
Special Events
Special EventsSpecial Events
Special Events
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 

En vedette

Sympal A Cmf Based On Symfony
Sympal   A Cmf Based On SymfonySympal   A Cmf Based On Symfony
Sympal A Cmf Based On Symfony
Jonathan Wage
 

En vedette (20)

Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js &amp; socket.io - SfLive Paris 2k13 - Wisembly
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Sobreescritura y extensión de validaciones, formularios y entidades
Sobreescritura y extensión de validaciones, formularios y entidadesSobreescritura y extensión de validaciones, formularios y entidades
Sobreescritura y extensión de validaciones, formularios y entidades
 
Cucumbers Have Layers - RubyConf 2015
Cucumbers Have Layers - RubyConf 2015Cucumbers Have Layers - RubyConf 2015
Cucumbers Have Layers - RubyConf 2015
 
Sympal A Cmf Based On Symfony
Sympal   A Cmf Based On SymfonySympal   A Cmf Based On Symfony
Sympal A Cmf Based On Symfony
 
Symfony in the Cloud
Symfony in the CloudSymfony in the Cloud
Symfony in the Cloud
 
When e-commerce meets Symfony
When e-commerce meets SymfonyWhen e-commerce meets Symfony
When e-commerce meets Symfony
 
міський проект «щаслива лапка»
міський проект «щаслива лапка»міський проект «щаслива лапка»
міський проект «щаслива лапка»
 
Symfony und Ember.js auf einer Seite #codetalks14
Symfony und Ember.js auf einer Seite #codetalks14Symfony und Ember.js auf einer Seite #codetalks14
Symfony und Ember.js auf einer Seite #codetalks14
 
Drupal8 for Symfony Developers
Drupal8 for Symfony DevelopersDrupal8 for Symfony Developers
Drupal8 for Symfony Developers
 
Refactorizando Pccomponentes.com con Symfony
Refactorizando Pccomponentes.com con SymfonyRefactorizando Pccomponentes.com con Symfony
Refactorizando Pccomponentes.com con Symfony
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
 
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017
 
Serverless Architecture
Serverless ArchitectureServerless Architecture
Serverless Architecture
 
Desarrollo código mantenible en WordPress utilizando Symfony
Desarrollo código mantenible en WordPress utilizando SymfonyDesarrollo código mantenible en WordPress utilizando Symfony
Desarrollo código mantenible en WordPress utilizando Symfony
 
Docker workshop
Docker workshopDocker workshop
Docker workshop
 

Similaire à Matters of State

Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
Spike Brehm
 

Similaire à Matters of State (20)

Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with React
 
Design strategies for AngularJS
Design strategies for AngularJSDesign strategies for AngularJS
Design strategies for AngularJS
 
Chekout demistified
Chekout demistifiedChekout demistified
Chekout demistified
 
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 
AngularJS, More Than Directives !
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
New Perspectives on Performance
New Perspectives on PerformanceNew Perspectives on Performance
New Perspectives on Performance
 
ActiveResource & REST
ActiveResource & RESTActiveResource & REST
ActiveResource & REST
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 

Plus de Kris Wallsmith

Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 

Plus de Kris Wallsmith (10)

The View From Inside
The View From InsideThe View From Inside
The View From Inside
 
Assetic (Zendcon)
Assetic (Zendcon)Assetic (Zendcon)
Assetic (Zendcon)
 
Assetic (OSCON)
Assetic (OSCON)Assetic (OSCON)
Assetic (OSCON)
 
Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
A Practical Introduction to Symfony2
A Practical Introduction to Symfony2A Practical Introduction to Symfony2
A Practical Introduction to Symfony2
 
Symfony 2
Symfony 2Symfony 2
Symfony 2
 

Dernier

💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
nirzagarg
 
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
nirzagarg
 
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Chandigarh Call girls 9053900678 Call girls in Chandigarh
 
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
Call Girls In Delhi Whatsup 9873940964 Enjoy Unlimited Pleasure
 

Dernier (20)

💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
💚😋 Salem Escort Service Call Girls, 9352852248 ₹5000 To 25K With AC💚😋
 
VVIP Pune Call Girls Sinhagad WhatSapp Number 8005736733 With Elite Staff And...
VVIP Pune Call Girls Sinhagad WhatSapp Number 8005736733 With Elite Staff And...VVIP Pune Call Girls Sinhagad WhatSapp Number 8005736733 With Elite Staff And...
VVIP Pune Call Girls Sinhagad WhatSapp Number 8005736733 With Elite Staff And...
 
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
 
Wadgaon Sheri $ Call Girls Pune 10k @ I'm VIP Independent Escorts Girls 80057...
Wadgaon Sheri $ Call Girls Pune 10k @ I'm VIP Independent Escorts Girls 80057...Wadgaon Sheri $ Call Girls Pune 10k @ I'm VIP Independent Escorts Girls 80057...
Wadgaon Sheri $ Call Girls Pune 10k @ I'm VIP Independent Escorts Girls 80057...
 
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
Hire↠Young Call Girls in Tilak nagar (Delhi) ☎️ 9205541914 ☎️ Independent Esc...
 
Pirangut | Call Girls Pune Phone No 8005736733 Elite Escort Service Available...
Pirangut | Call Girls Pune Phone No 8005736733 Elite Escort Service Available...Pirangut | Call Girls Pune Phone No 8005736733 Elite Escort Service Available...
Pirangut | Call Girls Pune Phone No 8005736733 Elite Escort Service Available...
 
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men  🔝mehsana🔝   Escorts...
➥🔝 7737669865 🔝▻ mehsana Call-girls in Women Seeking Men 🔝mehsana🔝 Escorts...
 
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls DubaiDubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
Dubai=Desi Dubai Call Girls O525547819 Outdoor Call Girls Dubai
 
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
VIP Model Call Girls NIBM ( Pune ) Call ON 8005736733 Starting From 5K to 25K...
 
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
 
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
Sarola * Female Escorts Service in Pune | 8005736733 Independent Escorts & Da...
 
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
Low Sexy Call Girls In Mohali 9053900678 🥵Have Save And Good Place 🥵
 
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
2nd Solid Symposium: Solid Pods vs Personal Knowledge Graphs
 
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Pollachi 7001035870 Whatsapp Number, 24/07 Booking
 
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
 
20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf
 
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Himatnagar 7001035870 Whatsapp Number, 24/07 Booking
 
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
Thalassery Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call G...
 
20240509 QFM015 Engineering Leadership Reading List April 2024.pdf
20240509 QFM015 Engineering Leadership Reading List April 2024.pdf20240509 QFM015 Engineering Leadership Reading List April 2024.pdf
20240509 QFM015 Engineering Leadership Reading List April 2024.pdf
 

Matters of State