2. April 20, 2013 Flow package best practices
About me
• Pankaj Lele
• Live in Goa, India
• Lelesys Founder
Director and CTO (10+
years)
• @pankajlele
Pankaj Lele - pankaj@lelesys.com 2
Saturday 20 April 13 / CW:
3. April 20, 2013 Flow package best practices
My Flow experience
• Large scale enterprise project
• Full agile development with 7 teams, 3
countries, 20+ developers
• Start with FLOW3 1.0 Nov. 2011
• First public version March 2012
Pankaj Lele - pankaj@lelesys.com 3
Saturday 20 April 13 / CW:
4. April 20, 2013 Flow package best practices
45 best practices for ...
• Efficiency
• Assuring quality
• Avoiding common errors
• Flexibility
Pankaj Lele - pankaj@lelesys.com 4
Saturday 20 April 13 / CW:
5. April 20, 2013 Flow package best practices
Best practices
Architecture Coding
Pankaj Lele - pankaj@lelesys.com 5
Saturday 20 April 13 / CW:
6. April 20, 2013 Flow package best practices
A deep thinking architect ...
Pankaj Lele - pankaj@lelesys.com 6
Saturday 20 April 13 / CW:
7. April 20, 2013 Flow package best practices
Architecture
#1
• Good to define full class design with
UML
Pankaj Lele - pankaj@lelesys.com 7
Saturday 20 April 13 / CW:
8. April 20, 2013 Flow package best practices
Architecture
#1
ArgoUML
(all platforms)
Pankaj Lele - pankaj@lelesys.com 8
Saturday 20 April 13 / CW:
9. April 20, 2013 Flow package best practices
Architecture
#2
• Avoid unnecessary bi-directional
associations in your domain model
Pankaj Lele - pankaj@lelesys.com 9
Saturday 20 April 13 / CW:
10. April 20, 2013 Flow package best practices
Architecture
#3
• Always good to define interfaces
• defaults - Objects.yaml
• ReflectionService
Pankaj Lele - pankaj@lelesys.com 10
Saturday 20 April 13 / CW:
11. April 20, 2013 Flow package best practices
Architecture
#3
For example, PaymentHandlerInterface
Pankaj Lele - pankaj@lelesys.com 11
Saturday 20 April 13 / CW:
12. April 20, 2013 Flow package best practices
Architecture
#4
• Avoid defining static functions
• PhpUnit limitations for mocks
Pankaj Lele - pankaj@lelesys.com 12
Saturday 20 April 13 / CW:
13. April 20, 2013 Flow package best practices
Architecture
#5
• Good to define domain services
Pankaj Lele - pankaj@lelesys.com 13
Saturday 20 April 13 / CW:
14. April 20, 2013 Flow package best practices
Architecture
#5
Pankaj Lele - pankaj@lelesys.com 14
Saturday 20 April 13 / CW:
15. April 20, 2013 Flow package best practices
Architecture
#6
• Good to use doctrine inheritance
mapping if possible
Pankaj Lele - pankaj@lelesys.com 15
Saturday 20 April 13 / CW:
16. April 20, 2013 Flow package best practices
Architecture
#6
BAD
class Media {
/**
* The title of media
* @var string
*/
protected $title;
/**
* The type one of 'audio' or 'video'
* @var string
*/
protected $type;
}
Pankaj Lele - pankaj@lelesys.com 16
Saturday 20 April 13 / CW:
17. April 20, 2013 Flow package best practices
Architecture
#6
BAD
class Media {
/**
* The title of media
* @var string
*/
protected $title;
/**
* The type one of 'audio' or 'video'
* @var string
*/
protected $type;
}
Pankaj Lele - pankaj@lelesys.com 16
Saturday 20 April 13 / CW:
18. April 20, 2013 Flow package best practices
Architecture
#6
GOOD
class Audio extends
class AbstractMedia {
AbstractMedia {
/**
}
* The title of media
* @var string
class Video extends
*/
AbstractMedia {
protected $title;
}
}
Pankaj Lele - pankaj@lelesys.com 17
Saturday 20 April 13 / CW:
19. April 20, 2013 Flow package best practices
Architecture
#6
GOOD
class Audio extends
class AbstractMedia {
AbstractMedia {
/**
}
* The title of media
* @var string
class Video extends
*/
AbstractMedia {
protected $title;
}
}
Pankaj Lele - pankaj@lelesys.com 17
Saturday 20 April 13 / CW:
20. April 20, 2013 Flow package best practices
Architecture
#7
• Good to define class constants
• no need to remember values
Pankaj Lele - pankaj@lelesys.com 18
Saturday 20 April 13 / CW:
21. April 20, 2013 Flow package best practices
Architecture
#7
GOOD
class ElectronicAddress {
const TYPE_AIM = 'Aim';
const TYPE_EMAIL = 'Email';
const TYPE_ICQ = 'Icq';
const TYPE_JABBER = 'Jabber';
}
$electronicAddress = new ElectronicAddress();
$electronicAddress->setType(ElectronicAddress::TYPE_EMAIL);
Pankaj Lele - pankaj@lelesys.com 19
Saturday 20 April 13 / CW:
22. April 20, 2013 Flow package best practices
Architecture
#7
GOOD
class ElectronicAddress {
const TYPE_AIM = 'Aim';
const TYPE_EMAIL = 'Email';
const TYPE_ICQ = 'Icq';
const TYPE_JABBER = 'Jabber';
}
$electronicAddress = new ElectronicAddress();
$electronicAddress->setType(ElectronicAddress::TYPE_EMAIL);
Pankaj Lele - pankaj@lelesys.com 19
Saturday 20 April 13 / CW:
23. April 20, 2013 Flow package best practices
Best practices
Architecture Coding
Pankaj Lele - pankaj@lelesys.com 20
Saturday 20 April 13 / CW:
24. April 20, 2013 Flow package best practices
Post-kickstart
Pankaj Lele - pankaj@lelesys.com 21
Saturday 20 April 13 / CW:
25. April 20, 2013 Flow package best practices
Coding:
Post-kickstart #8
• Good to define methods addX(),
removeX() and getXs() for collections
• example: TYPO3PartyDomainModel
AbstractParty
Pankaj Lele - pankaj@lelesys.com 22
Saturday 20 April 13 / CW:
26. April 20, 2013 Flow package best practices
Coding:
Post-kickstart #9
• Always good to initialize collections
in entity class constructor
• recommended by Doctrine
Pankaj Lele - pankaj@lelesys.com 23
Saturday 20 April 13 / CW:
27. April 20, 2013 Flow package best practices
Coding:
Post-kickstart #10
• Always annotate properties with
validators right away after kickstart
Pankaj Lele - pankaj@lelesys.com 24
Saturday 20 April 13 / CW:
28. April 20, 2013 Flow package best practices
Coding:
Post-kickstart #11
• Always remove unused controller
actions created by kick-starter
Pankaj Lele - pankaj@lelesys.com 25
Saturday 20 April 13 / CW:
29. April 20, 2013 Flow package best practices
Debugging
Pankaj Lele - pankaj@lelesys.com 26
Saturday 20 April 13 / CW:
30. April 20, 2013 Flow package best practices
Coding:
Debugging #12
• Always use TYPO3Flow
var_dump() for debugging variables
• no more memory full errors
• object information
Pankaj Lele - pankaj@lelesys.com 27
Saturday 20 April 13 / CW:
31. April 20, 2013 Flow package best practices
Coding:
Debugging #12
Pankaj Lele - pankaj@lelesys.com 28
Saturday 20 April 13 / CW:
32. April 20, 2013 Flow package best practices
Coding:
Debugging #13
• Best to use package debug/toolbar
• queries executed
• functions called
Pankaj Lele - pankaj@lelesys.com 29
Saturday 20 April 13 / CW:
33. April 20, 2013 Flow package best practices
Composer
Pankaj Lele - pankaj@lelesys.com 30
Saturday 20 April 13 / CW:
34. April 20, 2013 Flow package best practices
Coding:
Composer #14
• Always maintain composer.json right
away
• document what you used
• ext-zip or ext-imagick
Pankaj Lele - pankaj@lelesys.com 31
Saturday 20 April 13 / CW:
35. April 20, 2013 Flow package best practices
Configuration
Pankaj Lele - pankaj@lelesys.com 32
Saturday 20 April 13 / CW:
36. April 20, 2013 Flow package best practices
Coding:
Configuration #15
• Good to set defaultLocale setting
• application’s default language
• helps formatting numbers and
currencies automatically
Pankaj Lele - pankaj@lelesys.com 33
Saturday 20 April 13 / CW:
37. April 20, 2013 Flow package best practices
Coding:
Configuration #16
• Always run ./flow
configuration:validate to check
whether package *.yaml files are valid
Pankaj Lele - pankaj@lelesys.com 34
Saturday 20 April 13 / CW:
38. April 20, 2013 Flow package best practices
Coding:
Configuration #17
• Always crosscheck package
configuration using ./flow
configuration:show
Pankaj Lele - pankaj@lelesys.com 35
Saturday 20 April 13 / CW:
39. April 20, 2013 Flow package best practices
MVC
Pankaj Lele - pankaj@lelesys.com 36
Saturday 20 April 13 / CW:
40. April 20, 2013 Flow package best practices
Coding:
MVC #18
• Always map all GET/POST variables as
action arguments
Pankaj Lele - pankaj@lelesys.com 37
Saturday 20 April 13 / CW:
41. April 20, 2013 Flow package best practices
Coding:
MVC #18
BAD
/**
* Create action
*
* @return void
*/
public function createAction() {
$newVideo = $this->request->getHttpRequest()->getArgument('newVideo');
// ....
}
Pankaj Lele - pankaj@lelesys.com 38
Saturday 20 April 13 / CW:
42. April 20, 2013 Flow package best practices
Coding:
MVC #18
Good
/**
* Create action
*
* @param Video $newVideo The video
* @return void
*/
public function createAction(Video $newVideo) {
// ....
}
Pankaj Lele - pankaj@lelesys.com 39
Saturday 20 April 13 / CW:
43. April 20, 2013 Flow package best practices
Coding:
MVC #19
• Good to have an AbstractController
• assign logged in user to the view
• inject common dependencies
Pankaj Lele - pankaj@lelesys.com 40
Saturday 20 April 13 / CW:
44. April 20, 2013 Flow package best practices
Coding:
MVC #20
• Avoid exit() call inside controller action
• StopActionException() is what you
want
Pankaj Lele - pankaj@lelesys.com 41
Saturday 20 April 13 / CW:
45. April 20, 2013 Flow package best practices
Coding:
MVC #21
• Good to use StandAloneView
• render e-mail templates
Pankaj Lele - pankaj@lelesys.com 42
Saturday 20 April 13 / CW:
46. April 20, 2013 Flow package best practices
Session
Pankaj Lele - pankaj@lelesys.com 43
Saturday 20 April 13 / CW:
47. April 20, 2013 Flow package best practices
Coding:
Session #22
• Avoid using direct session API
• encapsulate
• session scoped class
• example: ShoppingCart
Pankaj Lele - pankaj@lelesys.com 44
Saturday 20 April 13 / CW:
48. April 20, 2013 Flow package best practices
Dependency Injection
Pankaj Lele - pankaj@lelesys.com 45
Saturday 20 April 13 / CW:
49. April 20, 2013 Flow package best practices
Coding:
Dependency #23
Injection
• Always inject interfaces
• proper factory object is used
• change implementation via Objects.yaml
Pankaj Lele - pankaj@lelesys.com 46
Saturday 20 April 13 / CW:
50. April 20, 2013 Flow package best practices
Coding:
Dependency #24
Injection
If you really want to ...
• inject TYPO3FlowSessionSessionInterface
• current active session
• inject TYPO3FlowSessionSession
• completely new session
Pankaj Lele - pankaj@lelesys.com 47
Saturday 20 April 13 / CW:
51. April 20, 2013 Flow package best practices
Persistence
Pankaj Lele - pankaj@lelesys.com 48
Saturday 20 April 13 / CW:
52. April 20, 2013 Flow package best practices
Coding:
Persistence
#25
• Frequently call ./flow
doctrine:validate
• after kickstart + modifications
• after each change in domain model
Pankaj Lele - pankaj@lelesys.com 49
Saturday 20 April 13 / CW:
53. April 20, 2013 Flow package best practices
Coding:
Persistence
#26
• Always use doctrine migrations for
database update
• doctrine:update/create not good
for serious projects
Pankaj Lele - pankaj@lelesys.com 50
Saturday 20 April 13 / CW:
54. April 20, 2013 Flow package best practices
Coding:
Persistence
#27
• Always test “down” doctrine
migrations
• good for change rollback
Pankaj Lele - pankaj@lelesys.com 51
Saturday 20 April 13 / CW:
55. April 20, 2013 Flow package best practices
Coding:
Persistence
#28
• Always separate out doctrine
migrations of respective packages
Pankaj Lele - pankaj@lelesys.com 52
Saturday 20 April 13 / CW:
56. April 20, 2013 Flow package best practices
Coding:
Persistence
#29
• Good to use doctrine migrations also for
migrating data
• $this->connection
Pankaj Lele - pankaj@lelesys.com 53
Saturday 20 April 13 / CW:
57. April 20, 2013 Flow package best practices
Coding:
Persistence
#30
• Good do not mention any collation or
use utf8_unicode_ci in doctrine
migrations
• my.cnf "collation-server"
Pankaj Lele - pankaj@lelesys.com 54
Saturday 20 April 13 / CW:
58. April 20, 2013 Flow package best practices
Coding:
Persistence
#31
• Do not delete/modify doctrine
migration files once committed
• always generate new migration on
each domain model change
Pankaj Lele - pankaj@lelesys.com 55
Saturday 20 April 13 / CW:
60. April 20, 2013 Flow package best practices
Coding:
Persistence
#33
• Good to use DQL at some places
• aggregations
• joins
• avoid nested foreach loops
• warning: QOM based widgets
Pankaj Lele - pankaj@lelesys.com 57
Saturday 20 April 13 / CW:
61. April 20, 2013 Flow package best practices
Resources
Pankaj Lele - pankaj@lelesys.com 58
Saturday 20 April 13 / CW:
62. April 20, 2013 Flow package best practices
Coding:
Resources
#34
• If needed, good to write files in /Data
• Persistent
• Temporary
• UtilityEnvironment
Pankaj Lele - pankaj@lelesys.com 59
Saturday 20 April 13 / CW:
63. April 20, 2013 Flow package best practices
Development Environment
Pankaj Lele - pankaj@lelesys.com 60
Saturday 20 April 13 / CW:
64. April 20, 2013 Flow package best practices
Coding:
Development #35
Environment
• Good to ignore directories in your
favorite IDE
• Data/Temporary, Logs, Persistent
• speeds up the IDE
• proxy classes ignored
Pankaj Lele - pankaj@lelesys.com 61
Saturday 20 April 13 / CW:
65. April 20, 2013 Flow package best practices
Coding:
Development #36
Environment
• Good to freeze packages not changed
so often
• freeze framework packages
• ./flow package:freeze
Pankaj Lele - pankaj@lelesys.com 62
Saturday 20 April 13 / CW:
66. April 20, 2013 Flow package best practices
Error Proofing
Pankaj Lele - pankaj@lelesys.com 63
Saturday 20 April 13 / CW:
68. April 20, 2013 Flow package best practices
Error Handling
Pankaj Lele - pankaj@lelesys.com 65
Saturday 20 April 13 / CW:
69. April 20, 2013 Flow package best practices
Coding:
Error handling
#38
• Always throw exceptions from domain
services
• catch in controllers
• better error reporting to the user
Pankaj Lele - pankaj@lelesys.com 66
Saturday 20 April 13 / CW:
70. April 20, 2013 Flow package best practices
Utilities
Pankaj Lele - pankaj@lelesys.com 67
Saturday 20 April 13 / CW:
71. April 20, 2013 Flow package best practices
Coding:
Utilities
#39
• Always look for available TYPO3Flow
Utility
• get things done the way framework likes
• environment, files, algorithms, array
Pankaj Lele - pankaj@lelesys.com 68
Saturday 20 April 13 / CW:
72. April 20, 2013 Flow package best practices
Bootstrap
Pankaj Lele - pankaj@lelesys.com 69
Saturday 20 April 13 / CW:
73. April 20, 2013 Flow package best practices
Coding:
Bootstrap
#40
• Good to rely on FLOW_* constants
• paths
Pankaj Lele - pankaj@lelesys.com 70
Saturday 20 April 13 / CW:
74. April 20, 2013 Flow package best practices
Troubleshooting
Pankaj Lele - pankaj@lelesys.com 71
Saturday 20 April 13 / CW:
75. April 20, 2013 Flow package best practices
Coding:
Troubleshooting
#41
• Always find exact database error
• SHOW INNODB STATUS
Pankaj Lele - pankaj@lelesys.com 72
Saturday 20 April 13 / CW:
76. April 20, 2013 Flow package best practices
Testing
Pankaj Lele - pankaj@lelesys.com 73
Saturday 20 April 13 / CW:
77. April 20, 2013 Flow package best practices
Coding:
Testing
#42
• Unit tests which test business logic
• usually test domain services
• persistence mocked
Pankaj Lele - pankaj@lelesys.com 74
Saturday 20 April 13 / CW:
78. April 20, 2013 Flow package best practices
Coding:
Testing
#43
• Functional tests which test user
stories
• test controllers
• virtual browser
• in-memory persistence
Pankaj Lele - pankaj@lelesys.com 75
Saturday 20 April 13 / CW:
79. April 20, 2013 Flow package best practices
Performance
Pankaj Lele - pankaj@lelesys.com 76
Saturday 20 April 13 / CW:
80. April 20, 2013 Flow package best practices
Coding:
Performance
#44
• Good to analyze performance
• sandstorm/plumber
• xhprof just profiler
• inclusive/exclusive timing
• no code changes
Pankaj Lele - pankaj@lelesys.com 77
Saturday 20 April 13 / CW:
81. April 20, 2013 Flow package best practices
Coding:
Performance
#45
• Always good to cache stuff
• caching framework
• front-ends
• backends
Pankaj Lele - pankaj@lelesys.com 78
Saturday 20 April 13 / CW:
82. April 20, 2013 Flow package best practices
Thank you!
Pankaj Lele - pankaj@lelesys.com 79
Saturday 20 April 13 / CW:
83. April 20, 2013 Flow package best practices
Questions?
Pankaj Lele - pankaj@lelesys.com 80
Saturday 20 April 13 / CW: