21
21
= Best Practice Class and Subdirectory Organization =
23
Suppose you were working on the application ##Derp##.
23
Suppose you were working on the application `Derp`.
25
25
phabricator/src/applications/derp/
27
If ##Derp## were as simple as possible, it would have one subdirectory:
27
If `Derp` were as simple as possible, it would have one subdirectory:
29
29
phabricator/src/applications/derp/controller/
31
containing the file ##DerpController.php## with the class
31
containing the file `DerpController.php` with the class
33
- ##DerpController##: minimally implements a ##processRequest()## method
33
- `DerpController`: minimally implements a `processRequest()` method
34
34
which returns some @{class:AphrontResponse} object. The class would probably
35
35
extend @{class:PhabricatorController}.
37
If ##Derp## were (relatively) complex, one could reasonably expect to see
37
If `Derp` were (relatively) complex, one could reasonably expect to see
38
38
the following directory layout:
40
40
phabricator/src/applications/derp/conduit/
54
54
phabricator/webroot/rsrc/js/application/derp/
55
55
phabricator/webroot/rsrc/css/application/derp/
57
These directories under ##phabricator/src/applications/derp/## represent
57
These directories under `phabricator/src/applications/derp/` represent
58
58
the basic set of class types from which most Phabrictor applications are
59
assembled. Each would contain a class file. For ##Derp##, these classes could be
59
assembled. Each would contain a class file. For `Derp`, these classes could be
62
- **DerpConstants**: constants used in the ##Derp## application.
62
- **DerpConstants**: constants used in the `Derp` application.
63
63
- **DerpController**: business logic providing functionality for a given
64
64
URI. Typically, controllers load data via Storage or Query classes, then
65
65
present the data to the user via one or more View classes.
66
66
- **DerpEditor**: business logic for workflows that change one or more
67
67
Storage objects. Editor classes are only necessary for particularly
68
68
complicated edits and should be used pragmatically versus Storage objects.
69
- **DerpException**: exceptions used in the ##Derp## application.
70
- **DerpQuery**: query one or more storage objects for pertinent ##Derp##
69
- **DerpException**: exceptions used in the `Derp` application.
70
- **DerpQuery**: query one or more storage objects for pertinent `Derp`
71
71
application data. @{class:PhabricatorOffsetPagedQuery} is particularly
72
72
handy for pagination and works well with @{class:AphrontPagerView}.
73
73
- **DerpReplyHandler**: business logic from any configured email interactions
74
users can have with the ##Derp## application.
75
- **DerpStorage**: storage objects for the ##Derp## application. Typically
74
users can have with the `Derp` application.
75
- **DerpStorage**: storage objects for the `Derp` application. Typically
76
76
there is a base class which extends @{class:PhabricatorLiskDAO} to configure
77
77
application-wide storage settings like the application (thus database) name.
78
78
Reading more about the @{class:LiskDAO} is highly recommended.
79
- **DerpView**: view objects for the ##Derp## application. Typically these
79
- **DerpView**: view objects for the `Derp` application. Typically these
80
80
extend @{class:AphrontView}.
81
- **DerpConduitAPIMethod**: provides any and all ##Derp## application
81
- **DerpConduitAPIMethod**: provides any and all `Derp` application
82
82
functionality that is accessible over Conduit.
84
However, it is likely that ##Derp## is even more complex, and rather than
84
However, it is likely that `Derp` is even more complex, and rather than
85
85
containing one class, each directory has several classes. A typical example
86
86
happens around the CRUD of an object:
88
88
- **DerpBaseController**: typically extends @{class:PhabricatorController},
89
implements ##buildStandardPageResponse## with the ##Derp## application name
90
and other ##Derp##-specific meta-data, and contains any controller-specific
91
functionality used throughout the ##Derp## application.
92
- **DerpDeleteController**: typically extends ##DerpBaseController## and
93
presents a confirmation dialogue to the user about deleting a ##Derp##.
94
- **DerpEditController**: typically extends ##DerpBaseController## and
95
presents a form to create and edit ##Derps##. Most likely uses
96
@{class:AphrontFormView} and various ##AphrontFormXControl## classes such as
89
implements `buildStandardPageResponse` with the `Derp` application name
90
and other `Derp`-specific meta-data, and contains any controller-specific
91
functionality used throughout the `Derp` application.
92
- **DerpDeleteController**: typically extends `DerpBaseController` and
93
presents a confirmation dialogue to the user about deleting a `Derp`.
94
- **DerpEditController**: typically extends `DerpBaseController` and
95
presents a form to create and edit `Derps`. Most likely uses
96
@{class:AphrontFormView} and various `AphrontFormXControl` classes such as
97
97
@{class:AphrontFormTextControl} to create the form.
98
- **DerpListController**: typically extends ##DerpBaseController## and displays
99
a set of one or more ##Derps##. Might use @{class:AphrontTableView} to create
100
a table of ##Derps##.
101
- **DerpViewController**: typically extends ##DerpBaseController## and displays
98
- **DerpListController**: typically extends `DerpBaseController` and displays
99
a set of one or more `Derps`. Might use @{class:AphrontTableView} to create
101
- **DerpViewController**: typically extends `DerpBaseController` and displays
104
Some especially awesome directories might have a ##__tests__## subdirectory
104
Some especially awesome directories might have a `__tests__` subdirectory
105
105
containing all pertinent unit test code for the class.