SlideShare a Scribd company logo
How Kris Writes Symfony Apps
@kriswallsmith
father artist bowhunter hacker
president widower gamer actor
tapdancer lover hater singer
writer founder yogi consultant
archer musician architect slacker
soccer player volunteer home
owner scotch drinker pianist…
assetic
Buzz
Spork
How Kris Writes Symfony Apps
Getting Started
composer create-project !
symfony/framework-standard-edition !
widgets-by-kris/ !
~2.4
+
+
+
+

"doctrine/orm": "~2.2,>=2.2.3",!
"doctrine/doctrine-bundle": "~1.2",!
"doctrine/mongodb-odm-bundle": "~3.0",!
"jms/di-extra-bundle": "~1.4",!
"jms/security-extra-bundle": "~1.5",!
"jms/serializer-bundle": "~1.0",
./app/console generate:bundle !
--namespace=Kris/Bundle/MainBundle
public function registerContainerConfiguration(LoaderInterface $loader)!
{!
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');!
!
// load local_*.yml or local.yml!
if (!
file_exists($file = __DIR__.'/config/local_'.$this->getEnvironment().'.yml')!
||!
file_exists($file = __DIR__.'/config/local.yml')!
) {!
$loader->load($file);!
}!
}
Model
Treat your model like a princess.
She gets her own wing
of the palace…
doctrine_mongodb:!
auto_generate_hydrator_classes: %kernel.debug%!
auto_generate_proxy_classes:
%kernel.debug%!
connections: { default: ~ }!
document_managers:!
default:!
connection: default!
database:
kris!
mappings:!
model:!
type:
annotation!
dir:
%src%/Kris/Model!
prefix: KrisModel!
alias: Model
// repo for src/Kris/Model/Widget.php!
$repo = $this->dm->getRepository('Model:User');
…doesn't do any work…
use KrisBundleMainBundleCanonicalizer;!
!

public function setUsername($username)!
{!
$this->username = $username;!
!

$canonicalizer = Canonicalizer::instance();!
$this->usernameCanonical = $canonicalizer->canonicalize($username);!
}
use KrisBundleMainBundleCanonicalizer;!
!

public function setUsername($username, Canonicalizer $canonicalizer)!
{!
$this->username = $username;!
$this->usernameCanonical = $canonicalizer->canonicalize($username);!
}
…and is unaware of the work
being done around her.
public function setUsername($username)!
{!
// a listener will update the!
// canonical username!
$this->username = $username;!
}
Anemic domain model 

is an anti-pattern?
Anemic???
“The fundamental horror of this anti-pattern is that it's
so contrary to the basic idea of object-oriented design;
which is to combine data and process together.”	

!

Martin Fowler
$cabinet->open();
Cabinets don’t open themselves.
$asset->getLastModified();
Mapping Layers
thin
thin controller

fat model
MVC
Is Symfony an MVC framework?
HTTP
Application Land

Controller

HTTP Land
The controller is thin 

because it maps from 

HTTP-land to application-land.
What about the model?
How Kris Writes Symfony Apps
How Kris Writes Symfony Apps
public function registerAction()!
{!
// ...!
$user->sendWelcomeEmail();!
// ...!
}
public function registerAction()!
{!
// ...!
$mailer->sendWelcomeEmail($user);!
// ...!
}
Persistence Land

Model

Application Land
The model maps from
application-land to persistence-land.
Persistence Land

Model

Application Land

Controller

HTTP Land
Who lives in application land?
Thin controller, thin model…


Fat service layer!
Application Events
Use them.
That happened.
/** @DIObserve("user.username_change") */!
public function onUsernameChange(UserEvent $event)!
{!
$user = $event->getUser();!
$dm
= $event->getDocumentManager();!
!

$dm->getRepository('Model:Widget')!
->updateDenormalizedUsernames($user);!
}
One event class per model
•
•
•

Event name constants	

Accepts object manager and object as arguments	

Simple accessors
$event = new UserEvent($dm, $user);!
$dispatcher->dispatch(UserEvent::CREATE, $event);
$event = new UserUserEvent($dm, $user, $otherUser);!
$dispatcher->dispatch(UserEvent::FOLLOW, $event);
preFlush
public function preFlush(ManagerEventArgs $event)!
{!
$dm = $event->getObjectManager();!
$uow = $dm->getUnitOfWork();!
!
foreach ($uow->getIdentityMap() as $class => $docs) {!
if (is_a($class, 'KrisModelUser')) {!
foreach ($docs as $doc) {!
$this->processUserFlush($dm, $doc);!
}!
} elseif (is_a($class, 'KrisModelWidget')) {!
foreach ($docs as $doc) {!
$this->processWidgetFlush($dm, $doc);!
}!
}!
}!
}
/** @DIObserve("user.create") */!
public function onUserCreate(UserEvent $event)!
{!
$user = $event->getUser();!
!

$activity = new Activity();!
$activity->setActor($user);!
$activity->setVerb('register');!
$activity->setCreatedAt($user->getCreatedAt());!
!

$this->dm->persist($activity);!
}
/** @DIObserve("user.follow_user") */!
public function onFollowUser(UserUserEvent $event)!
{!
$event->getUser()!
->getStats()!
->incrementFollowedUsers(1);!
$event->getOtherUser()!
->getStats()!
->incrementFollowers(1);!
}
Decouple your application by
delegating work to clean, concise,
single-purpose event listeners.
Contextual Configuration
Save your future self a headache
# @MainBundle/Resources/config/widget.yml!
services:!
widget_twiddler:!
class: KrisBundleMainBundleWidgetTwiddler!
arguments:!
- @event_dispatcher!
- @?logger
JMSDiExtraBundle
/** @DIService("widget_twiddler") */!
class Twiddler!
{!
/** @DIInjectParams */!
public function __construct(!
EventDispatcherInterface $dispatcher,!
LoggerInterface $logger = null)!
{!
// ...!
}!
}
services:!
# aliases for auto-wiring!
container: @service_container!
dm: @doctrine_mongodb.odm.document_manager!
doctrine: @doctrine_mongodb!
dispatcher: @event_dispatcher!
security: @security.context
require.js
How Kris Writes Symfony Apps
<script src="{{ asset('js/lib/require.js') }}"></script>!
<script>!
require.config({!
baseUrl: "{{ asset('js') }}",!
paths: {!
"jquery": "//ajax.googleapis.com/.../jquery.min",!
"underscore": "lib/underscore",!
"backbone": "lib/backbone"!
},!
shim: {!
"jquery": { exports: "jQuery" },!
"underscore": { exports: "_" },!
"backbone": {!
deps: [ "jquery", "underscore" ],!
exports: "Backbone"!
}!
}!
})!
require([ "main" ])!
</script>
// web/js/model/user.js!
define(!
[ "underscore", "backbone" ],!
function(_, Backbone) {!
var tmpl = _.template("<%- first %> <%- last %>")!
return Backbone.Model.extend({!
name: function() {!
return tmpl({!
first: this.get("first_name"),!
last: this.get("last_name")!
})!
}!
})!
}!
)
{% block head %}!
<script>!
require(!
[ "view/user", "model/user" ],!
function(UserView, User) {!
var view = new UserView({!
model: new User({{ user|serialize|raw }}),!
el: document.getElementById("user")!
})!
}!
)!
</script>!
{% endblock %}
Dependencies
•
•
•

model: backbone, underscore	

view: backbone, jquery	

template: model, view
{% javascripts!
"js/lib/jquery.js" "js/lib/underscore.js"!
"js/lib/backbone.js" "js/model/user.js"!
"js/view/user.js"!
filter="?uglifyjs2" output="js/packed/user.js" %}!
<script src="{{ asset_url }}"></script>!
{% endjavascripts %}!
!

<script>!
var view = new UserView({!
model: new User({{ user|serialize|raw }}),!
el: document.getElementById("user")!
})!
</script>
Unused dependencies
naturally slough off
JMSSerializerBundle
{% block head %}!
<script>!
require(!
[ "view/user", "model/user" ],!
function(UserView, User) {!
var view = new UserView({!
model: new User({{ user|serialize|raw }}),!
el: document.getElementById("user")!
})!
}!
)!
</script>!
{% endblock %}
/** @ExclusionPolicy("ALL") */!
class User!
{!
private $id;!
!

/** @Expose */!
private $firstName;!
!

/** @Expose */!
private $lastName;!
}
Miscellaneous
When to create a new bundle
•
•
•

Anything reusable	

Lots of classes relating to one feature	

Integration with a third party
{% include 'MainBundle:Account/Widget:sidebar.html.twig' %}
{% include 'AccountBundle:Widget:sidebar.html.twig' %}
Access Control
The Symfony ACL is for
arbitrary permissions
How Kris Writes Symfony Apps
Encapsulate access logic in
custom voter classes
/** @DIService(public=false) @DITag("security.voter") */!
class WidgetVoter implements VoterInterface!
{!
public function supportsAttribute($attribute)!
{!
return 'OWNER' === $attribute;!
}!
!
public function supportsClass($class)!
{!
return is_a($class, 'KrisModelWidget');!
}!
!
public function vote(TokenInterface $token, $widget, array $attributes)!
{!
// ...!
}!
}
public function vote(TokenInterface $token, $widget, array $attributes)!
{!
$result = VoterInterface::ACCESS_ABSTAIN;!
if (!$this->supportsClass(get_class($widget))) {!
return $result;!
}!
!
foreach ($attributes as $attribute) {!
if (!$this->supportsAttribute($attribute)) {!
continue;!
}!
!
$result = VoterInterface::ACCESS_DENIED;!
if ($token->getUser() === $widget->getUser()) {!
return VoterInterface::ACCESS_GRANTED;!
}!
}!
!
return $result;!
}
JMSSecurityExtraBundle
/** @SecureParam(name="widget", permissions="OWNER") */!
public function editAction(Widget $widget)!
{!
// ...!
}
{% if is_granted('OWNER', widget) %}!
{# ... #}!
{% endif %}
No query builders
outside of repositories
class WidgetRepository extends DocumentRepository!
{!
public function findByUser(User $user)!
{!
return $this->createQueryBuilder()!
->field('userId')->equals($user->getId())!
->getQuery()!
->execute();!
}!
!
public function updateDenormalizedUsernames(User $user)!
{!
$this->createQueryBuilder()!
->update()!
->multiple()!
->field('userId')->equals($user->getId())!
->field('userName')->set($user->getUsername())!
->getQuery()!
->execute();!
}!
}
Eager ID creation
public function __construct()!
{!
$this->id = (string) new MongoId();!
}
public function __construct()!
{!
$this->id = (string) new MongoId();!
$this->createdAt = new DateTime();!
$this->widgets = new ArrayCollection();!
}
Remember your
clone constructor
$foo = new Foo();!
$bar = clone $foo;
public function __clone()!
{!
$this->id = (string) new MongoId();!
$this->createdAt = new DateTime();!
$this->widgets = new ArrayCollection(!
$this->widgets->toArray()!
);!
}
public function __construct()!
{!
$this->id = (string) new MongoId();!
$this->createdAt = new DateTime();!
$this->widgets = new ArrayCollection();!
}!
!

public function __clone()!
{!
$this->id = (string) new MongoId();!
$this->createdAt = new DateTime();!
$this->widgets = new ArrayCollection(!
$this->widgets->toArray()!
);!
}
Save space on field names
/** @ODMString(name="u") */!
private $username;!
!

/** @ODMString(name="uc") @ODMUniqueIndex */!
private $usernameCanonical;
Only flush from the controller
public function theAction(Widget $widget)!
{!
$this->get('widget_twiddler')!
->skeedaddle($widget);!
$this->flush();!
}
No proxy objects
/** @ODMReferenceOne(targetDocument="User") */!
private $user;
public function getUser()!
{!
if ($this->userId && !$this->user) {!
throw new UninitializedReferenceException('user');!
}!
!

return $this->user;!
}
Questions?
@kriswallsmith.net

https://joind.in/10371

Thank You!
Ad

More Related Content

What's hot (20)

jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
chandrashekher786
 
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Dotan Dimet
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn't
Cosimo Streppone
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
Constantin Titarenko
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
Rebecca Murphey
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
Rebecca Murphey
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
Aleix Vergés
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
Remy Sharp
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
Remy Sharp
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 
jQuery
jQueryjQuery
jQuery
Mohammed Arif
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
Simon Willison
 
Mojolicious
MojoliciousMojolicious
Mojolicious
Marcos Rebelo
 
Remy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQueryRemy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQuery
deimos
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
taggg
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
deimos
 
HTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymoreHTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymore
Remy Sharp
 
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
Kris Wallsmith
 
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
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
Ryan Weaver
 
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Dotan Dimet
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn't
Cosimo Streppone
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
Rebecca Murphey
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
Aleix Vergés
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
Remy Sharp
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
Remy Sharp
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 
Remy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQueryRemy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQuery
deimos
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
taggg
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
deimos
 
HTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymoreHTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymore
Remy Sharp
 
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
Kris Wallsmith
 
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
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
Ryan Weaver
 

Similar to How Kris Writes Symfony Apps (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
DrupalCon jQuery
DrupalCon jQueryDrupalCon jQuery
DrupalCon jQuery
Nathan Smith
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
Massimiliano Arione
 
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Puppet
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus Bundles
Albert Jessurum
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mate
Codemotion
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
Kris Wallsmith
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
Clinton Dreisbach
 
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to PluginDrupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Acquia
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First Widget
Chris Wilcoxson
 
KISSY 的昨天、今天与明天
KISSY 的昨天、今天与明天KISSY 的昨天、今天与明天
KISSY 的昨天、今天与明天
tblanlan
 
kissy-past-now-future
kissy-past-now-futurekissy-past-now-future
kissy-past-now-future
yiming he
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
Lindsay Holmwood
 
A re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbaiA re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbai
Praveen Puglia
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
Bastian Feder
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
Alessandro Nadalin
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
Michael Girouard
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Puppet
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus Bundles
Albert Jessurum
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mate
Codemotion
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
Kris Wallsmith
 
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to PluginDrupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Acquia
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First Widget
Chris Wilcoxson
 
KISSY 的昨天、今天与明天
KISSY 的昨天、今天与明天KISSY 的昨天、今天与明天
KISSY 的昨天、今天与明天
tblanlan
 
kissy-past-now-future
kissy-past-now-futurekissy-past-now-future
kissy-past-now-future
yiming he
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
Lindsay Holmwood
 
A re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbaiA re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbai
Praveen Puglia
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
Bastian Feder
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
Alessandro Nadalin
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
Ad

More from Kris Wallsmith (11)

Unleash the Power of Symfony Messenger
Unleash the  Power  of Symfony MessengerUnleash the  Power  of Symfony Messenger
Unleash the Power of Symfony Messenger
Kris Wallsmith
 
The View From Inside
The View From InsideThe View From Inside
The View From Inside
Kris Wallsmith
 
Assetic (Zendcon)
Assetic (Zendcon)Assetic (Zendcon)
Assetic (Zendcon)
Kris Wallsmith
 
Assetic (OSCON)
Assetic (OSCON)Assetic (OSCON)
Assetic (OSCON)
Kris Wallsmith
 
Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)
Kris Wallsmith
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
A Practical Introduction to Symfony2
A Practical Introduction to Symfony2A Practical Introduction to Symfony2
A Practical Introduction to Symfony2
Kris Wallsmith
 
Symfony 2
Symfony 2Symfony 2
Symfony 2
Kris Wallsmith
 
Symfony in the Cloud
Symfony in the CloudSymfony in the Cloud
Symfony in the Cloud
Kris Wallsmith
 
Unleash the Power of Symfony Messenger
Unleash the  Power  of Symfony MessengerUnleash the  Power  of Symfony Messenger
Unleash the Power of Symfony Messenger
Kris Wallsmith
 
Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)
Kris Wallsmith
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
A Practical Introduction to Symfony2
A Practical Introduction to Symfony2A Practical Introduction to Symfony2
A Practical Introduction to Symfony2
Kris Wallsmith
 
Ad

Recently uploaded (20)

How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 

How Kris Writes Symfony Apps