Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/docs/developer/phabricator_code_layout.diviner b/src/docs/developer/phabricator_code_layout.diviner
index 09d944e529..356228cdd7 100644
--- a/src/docs/developer/phabricator_code_layout.diviner
+++ b/src/docs/developer/phabricator_code_layout.diviner
@@ -1,129 +1,115 @@
@title Phabricator Code Layout
@group developer
Guide to Phabricator code layout, including how URI mapping works through
-application class and subdirectory organization best practices.
+application class and subdirectory organization best practices.
= URI Mapping =
When a user visits a Phabricator URI, the Phabricator infrastructure parses
that URI with a regular expression to determine what controller class to load.
For now, that regular expression is hard-coded inside the
@{class:AphrontDefaultApplicationConfiguration} within the ##getURIMap##
method. Use the existing entries as examples for adding your own entries.
The Phabricator infrastructure knows where a given controller class lives on
-disk from a cache file the Arcanist phutil mapper generates. This mapping
+disk from a cache file the Arcanist phutil mapper generates. This mapping
should be updated whenever new classes or files are added:
arc liberate /path/to/phabricator/src
-Finally, a given controller class will map to an application which will have
+Finally, a given controller class will map to an application which will have
most of its code in standardized subdirectories and classes.
-= Best Practice Class and Subdirectory Organization =
+= Best Practice Class and Subdirectory Organization =
-Suppose you were working on the application ##Derp##.
+Suppose you were working on the application ##Derp##.
phabricator/src/applications/derp/
If ##Derp## were as simple as possible, it would have one subdirectory:
phabricator/src/applications/derp/controller/
containing the file ##DerpController.php## with the class
- - ##DerpController##: minimally implements a ##processRequest()## method
+ - ##DerpController##: minimally implements a ##processRequest()## method
which returns some @{class:AphrontResponse} object. The class would probably
extend @{class:PhabricatorController}.
-plus an auto-generated ##__init__.php## file.
-
-NOTE: ##__init.php__## files are generated and maintained via `arc lint`.
-
-If ##Derp## were (relatively) complex, one could reasonably expect to see
+If ##Derp## were (relatively) complex, one could reasonably expect to see
the following directory layout:
phabricator/src/applications/derp/constants/
phabricator/src/applications/derp/controller/
phabricator/src/applications/derp/editor/
phabricator/src/applications/derp/exception/
phabricator/src/applications/derp/query/
phabricator/src/applications/derp/replyhandler/
phabricator/src/applications/derp/storage/
phabricator/src/applications/derp/view/
phabricator/src/applications/conduit/method/derp/
-(The following two folders are also likely to be included for javascript and
-css respectively. However, static resources are largely outside the scope of
+(The following two folders are also likely to be included for JavaScript and
+CSS respectively. However, static resources are largely outside the scope of
this document. See @{article:Adding New CSS and JS}.)
- phabricator/webroot/rsc/js/application/derp/
- phabricator/webroot/rsc/css/application/derp/
+ phabricator/webroot/rsrc/js/application/derp/
+ phabricator/webroot/rsrc/css/application/derp/
-These directories under ##phabricator/src/applications/derp/## represent
-the basic set of class types from which most Phabrictor applications are
-assembled. Each would contain a class file and an ##__init__.php## file.
-For ##Derp##, these classes could be something like:
+These directories under ##phabricator/src/applications/derp/## represent
+the basic set of class types from which most Phabrictor applications are
+assembled. Each would contain a class file. For ##Derp##, these classes could be
+something like:
- **DerpConstants**: constants used in the ##Derp## application.
- **DerpController**: business logic providing functionality for a given
URI. Typically, controllers load data via Storage or Query classes, then
present the data to the user via one or more View classes.
- **DerpEditor**: business logic for workflows that change one or more
- Storage objects. Editor classes are only necessary for particularly
+ Storage objects. Editor classes are only necessary for particularly
complicated edits and should be used pragmatically versus Storage objects.
- **DerpException**: exceptions used in the ##Derp## application.
- **DerpQuery**: query one or more storage objects for pertinent ##Derp##
application data. @{class:PhabricatorOffsetPagedQuery} is particularly
handy for pagination and works well with @{class:AphrontPagerView}.
- **DerpReplyHandler**: business logic from any configured email interactions
users can have with the ##Derp## application.
- - **DerpStorage**: storage objects for the ##Derp## application. Typically
+ - **DerpStorage**: storage objects for the ##Derp## application. Typically
there is a base class which extends @{class:PhabricatorLiskDAO} to configure
application-wide storage settings like the application (thus database) name.
Reading more about the @{class:LiskDAO} is highly recommended.
- **DerpView**: view objects for the ##Derp## application. Typically these
extend @{class:AphrontView}.
- - **ConduitAPI_derp_Method**: provides any and all ##Derp## application
+ - **ConduitAPI_derp_Method**: provides any and all ##Derp## application
functionality that is accessible over Conduit.
-However, it is likely that ##Derp## is even more complex, and rather than
-containing a class and an ##__init__.php## file, each directory has
-subdirectories of its own. A typical example happens around the CRUD of an
-object:
-
- phbaricator/src/application/derp/controller/base/
- phabricator/src/application/derp/controller/delete/
- phabricator/src/application/derp/controller/edit/
- phabricator/src/application/derp/controller/list/
- phabricator/src/application/derp/controller/view/
-
-Which would then each contain a class and an ##__init__.php## file mapping to
-corresponding classes
+However, it is likely that ##Derp## is even more complex, and rather than
+containing one class, each directory has several classes. A typical example
+happens around the CRUD of an object:
- - **DerpBaseController**: typically extends @{class:PhabricatorController},
- implements ##buildStandardPageResponse## with the ##Derp## application name
+ - **DerpBaseController**: typically extends @{class:PhabricatorController},
+ implements ##buildStandardPageResponse## with the ##Derp## application name
and other ##Derp##-specific meta-data, and contains any controller-specific
functionality used throughout the ##Derp## application.
- - **DerpDeleteController**: typically extends ##DerpBaseController## and
+ - **DerpDeleteController**: typically extends ##DerpBaseController## and
presents a confirmation dialogue to the user about deleting a ##Derp##.
- - **DerpEditController**: typically extends ##DerpBaseController## and
+ - **DerpEditController**: typically extends ##DerpBaseController## and
presents a form to create and edit ##Derps##. Most likely uses
@{class:AphrontFormView} and various ##AphrontFormXControl## classes such as
@{class:AphrontFormTextControl} to create the form.
- **DerpListController**: typically extends ##DerpBaseController## and displays
a set of one or more ##Derps##. Might use @{class:AphrontTableView} to create
a table of ##Derps##.
- **DerpViewController**: typically extends ##DerpBaseController## and displays
a single ##Derp##.
-Some especially awesome directories might have a ##__tests__## subdirectory
+Some especially awesome directories might have a ##__tests__## subdirectory
containing all pertinent unit test code for the class.
= Next Steps =
- Learn about @{article:Adding New CSS and JS}; or
- learn about the @{class:LiskDAO}; or
- learn about @{article:Writing Unit Tests}; or
- learn how to contribute (see @{article:Contributor Introduction}).
diff --git a/src/docs/userguide/libraries.diviner b/src/docs/userguide/libraries.diviner
index 2d950d3f45..834b26fe1c 100644
--- a/src/docs/userguide/libraries.diviner
+++ b/src/docs/userguide/libraries.diviner
@@ -1,155 +1,154 @@
@title libphutil Libraries User Guide
@group userguide
Guide to creating and managing libphutil libraries.
= Overview =
libphutil includes a library system which organizes PHP classes and functions
into modules. Some extensions and customizations of Arcanist and Phabricator
require you to make code available to Phabricator by providing it in a libphutil
library.
For example, if you want to store files in some kind of custom storage engine,
you need to write a class which can interact with that engine and then tell
Phabricator to load it.
In general, you perform these one-time setup steps:
- Create a new directory.
- Use ##arc liberate## to initialize and name the library.
- Add a dependency on Phabricator if necessary.
- Add the library to your Phabricator config or ##.arcconfig## so it will be
loaded at runtime.
Then, to add new code, you do this:
- Write or update classes.
- Update the library metadata by running ##arc liberate## again.
= Creating a New Library =
To **create a new libphutil library**:
$ mkdir libcustom/
$ cd libcustom/
libcustom/ $ arc liberate src/
Now you'll get a prompt like this:
No library currently exists at that path...
The directory '/some/path/libcustom/src' does not exist.
Do you want to create it? [y/N] y
Creating new libphutil library in '/some/path/libcustom/src'.
Choose a name for the new library.
What do you want to name this library?
Choose a library name (in this case, "libcustom" would be appropriate) and it
you should get some details about the library initialization:
Writing '__phutil_library_init__.php' to
'/some/path/libcustom/src/__phutil_library_init__.php'...
Using library root at 'src'...
Mapping library...
Verifying library...
Finalizing library map...
OKAY Library updated.
This will write three files:
- ##src/.phutil_module_cache## This is a cache which makes "arc liberate"
faster when you run it to update the library. You can safely remove it at
any time. If you check your library into version control, you can add this
file to ignore rules (like .gitignore).
- ##src/__phutil_library_init__.php## This records the name of the library and
tells libphutil that a library exists here.
- ##src/__phutil_library_map__.php## This is a map of all the symbols
(functions and classes) in the library, which allows them to be autoloaded
at runtime and dependencies to be statically managed by "arc liberate".
= Linking with Phabricator =
If you aren't using this library with Phabricator (e.g., you are only using it
with Arcanist or are building something else on libphutil) you can skip this
step.
But, if you intend to use this library with Phabricator, you need to define its
dependency on Phabricator by creating a ##.arcconfig## file which points at
Phabricator. For example, you might write this file to
##libcustom/.arcconfig##:
{
"project_id" : "libcustom",
"phutil_libraries" : {
"phabricator" : "phabricator/src/"
}
}
For details on creating a ##.arcconfig##, see
@{article:Arcanist User Guide: Configuring a New Project}. In general, this
tells ##arc liberate## that it should look for symbols in Phabricator when
performing static analysis.
NOTE: If Phabricator isn't located next to your custom library, specify a
path which actually points to the ##phabricator/## directory.
You do not need to declare dependencies on ##arcanist## or ##libphutil##,
since ##arc liberate## automatically loads them.
Finally, edit your Phabricator config to tell it to load your library at
runtime, by adding it to ##load-libraries##:
...
'load-libraries' => array(
'libcustom' => 'libcustom/src/',
),
...
Now, Phabricator will be able to load classes from your custom library.
= Writing Classes =
To actually write classes, create a new module and put code in it:
libcustom/ $ mkdir src/example/
libcustom/ $ nano src/example/ExampleClass.php # Edit some code.
Now, run ##arc liberate## to regenerate the static resource map:
libcustom/ $ arc liberate src/
-This will automatically create and update ##__init__.php## files, and regenerate
-the static map of the library.
+This will automatically regenerate the static map of the library.
= What You Can Extend And Invoke =
libphutil, Arcanist and Phabricator are strict about extensibility of classes
and visibility of methods and properties. Most classes are marked ##final##, and
methods have the minimum required visibility (protected or private). The goal of
this strictness is to make it clear what you can safely extend, access, and
invoke, so your code will keep working as the upstream changes.
When developing libraries to work with libphutil, Arcanist and Phabricator, you
should respect method and property visibility and extend only classes marked
##@stable##. They are rendered with a large callout in the documentation (for
example: @{class@libphutil:AbstractDirectedGraph}). These classes are external
interfaces intended for extension.
If you want to extend a class but it is not marked ##@stable##, here are some
approaches you can take:
- Good: If possible, use composition rather than extension to build your
feature.
- Good: Check the documentation for a better way to accomplish what you're
trying to do.
- Good: Let us know what your use case is so we can make the class tree more
flexible or configurable, or point you at the right way to do whatever
you're trying to do, or explain why we don't let you do it.
- Discouraged: Send us a patch removing "final" (or turning "protected" or
"private" into "public"). We generally will not accept these patches, unless
there's a good reason that the current behavior is wrong.
- Discouraged: Create an ad-hoc local fork and remove "final" in your copy of
the code. This will make it more difficult for you to upgrade in the future.
- Discouraged: Use Reflection to violate visibility keywords.

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 14, 7:33 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
337289
Default Alt Text
(14 KB)

Event Timeline