Introduction
============
This framework is a very young project, started on 12/16/2010 because of the
lack of spring-alike frameworks for php. After 3 months of development, I think 
it's reaching the needed maturity level for production ;) Stay tuned for release
1.0 ;)

Please contact me if you have any comments, doubts, or any kind of feedback.
Send an email to: marcelog@gmail.com

Checkout the api (phpdoc) at: http://marcelog.github.com/Ding/php-doc/html/index.html

In the homepage, you can find the user manual: http://marcelog.github.com/Ding

Ding is also the winner of the 2011 Binpress programming contest :)

See this article for a complete application example: http://marcelog.github.com/articles/php_asterisk_listener_example_using_pami_and_ding.html.

--------------------------------------------------------------------------------
Ding supports some of JSR-330 and JSR-250 annotations, like @Configuration,
@Bean, @Required, @Resource, etc.
--------------------------------------------------------------------------------
Please see inside docs/examples for code samples. A good place to start are
the "basic", "aop", "quickstart", "doctrine", and "mvc" examples.

PAMI: docs/examples/pami (PHP Asterisk Manager Interface, at
https://github.com/marcelog/PAMI, is an oop implementation for asterisk manager
interface, designed to interact and manage asterisk in an event-driven fashion).

PAGI: docs/examples/pagi (PHP Asterisk Gateway Interface, at
https://github.com/marcelog/PAGI, is an oop implementation for asterisk gateway
interface, designed to make agi -telephony- applications very easy).
--------------------------------------------------------------------------------

Notes about the source:

* Expect changes and be patience, the work will get done.

* If you're wondering why the first comment of each source file is repeated,
it's because they're actually 2 different comments: one for the file, and one
for the class.
--------------------------------------------------------------------------------
Available via PEAR
------------------
You can now easily install Ding by issuing:
# pear channel-discover pearhub.org
# pear install pearhub/Ding-0.95.0
just replace 0.95.0 by the release version you'd like to install :)
See: http://www.pearhub.com/projects/Ding
--------------------------------------------------------------------------------
PHAR File
=========
Ding can also be used as a phar file. See docs/examples/basic-with-phar. To 
generate the phar you can use the task "package" from the phing build.xml file or
manually run resources/generatePhar.php from the top of the source directory.

You have to add the directory that contains the phar file to the include file
and you should be set.
--------------------------------------------------------------------------------
Supported bean definitions providers
====================================
* XML
* YAML
* Annotations (like JSR 250 and 330)
--------------------------------------------------------------------------------
Supported annotations
=====================
Remember that using annotations is completely optional. Not using them will
benefit performance. Annotations CAN be cached. Use the 'annotations' cache with
any of the implementations below ;)

* @Configuration and @Bean just like Java Configuration. So you dont even need
a beans.xml (@Scope, @InitMethod, @DestroyMethod) for this annotated bean
definitions.
* @Component (used in classes, supports same annotations as @Bean)
* @Required
* @Resource
* @Controller (When using the MVC through http).
* @RequestMapping (When using the MVC through http).
* @SignalHandler
* @ErrorHandler
* @ShutdownHandler
* @InitMethod(method=xxx)
* @DestroyMethod(method=xxx)
* @Aspect for classes and @ExceptionInterceptor/@MethodInterceptor for methods.
--------------------------------------------------------------------------------
CACHE
=====
Ding supports this cache implementations out of the box.
* APC.
* File.
* Zend Cache.
* Memcache through memcached php extension (needs libmemcached).
* DUMMY.

Each one of the implementations can be used for bean caching, beandefinition
caching, or proxy caching. Actually, caching beans is a little trickier in
the php world. In the java world, the application server is always "up & running",
whilst in php everything is created from scratch for every request. So it may
be better to not cache the bean itself, but everything else, like definintions
and proxies definitions.
--------------------------------------------------------------------------------
DI
==
* Import other beans.xml files anywhere inside your already existant files. This
let you split your beans among several configuration files.
* Setter injection (php evaluated code, arrays, values, and/or references to
 other beans).
* Constructor injection (php evaluated code, arrays, values, and/or references
 to other beans).
* Method injection (ala spring lookup-method) allows you to have singletons that
can deliver prototypes scoped beans.
* A bean can be: singleton or prototype (multiple instances).
* Can create beans by specifying a static method of the bean class itself.
* Can create beans by specifying another bean (and its method) as a factory.
* Properties for your beans.xml, like: ${log.dir}/alog.log. You can also have
the container setup any php options by specifying a property with the name 
"php." (i.e: php.date.timezone).
* Optional init-method will be called right after assembling a bean. (Can also
be specified via the @InitMethod(method=xxx) annotation).
* Optional destroy-method will be called when the container is shutting down.
(Can also be specified via the @DestroyMethod(method=xxx) annotation).

Aware Interfaces
================
IContainerAware: Whenever ding is going to instantiate a bean whose class
implements IContainerAware interface, it will inject the container instace to
this bean.

IBeanNameAware: Whenever ding is going to instantiate a bean whose class
implements IBeanNameAware interface, it will inject the bean name.

IAspectManagerAware: Whenever ding is going to instantiate a bean whose class
implements IAspectManagerAware interface, it will inject the current instance
of the aspect manager (giving the ability to inject pointcuts, aspects, and
general aop management).

IResourceLoaderAware: Whenever ding is going to instantiate a bean whose class
implements IResourceLoaderAware interface, it will inject the instance of the
resource loader in use, which is usually the container itself.

ILoggerAware: Whenever ding is going to instantiate a bean whose class
implements ILoggerAware interface, it will inject the instance of the
logger (log4php) in use by the container, so you can log there. The returned
logger will be of class __CLASS__ (where \ are replaced with .).

Extension points
================
You can easily hook in the bean lifecycle by just implementing one of:
 * Ding\Bean\Lifecycle\IBeforeDefinition
 * Ding\Bean\Lifecycle\IAfterDefinition
 * Ding\Bean\Lifecycle\IBeforeCreate
 * Ding\Bean\Lifecycle\IAfterCreate
 * Ding\Bean\Lifecycle\IBeforeAssemble
 * Ding\Bean\Lifecycle\IAfterAssemble
This will allow you to extend the container functionality as much as you like :)
--------------------------------------------------------------------------------
Events
======
The container natively supports events. This means that you can register beans
(either programatically or via the xml, yaml, or annotations drivers) and then
asynchronously trigger (dispatch) these events along some data object. The container
will then instantiate the needed beans (the listeners) and notify them. Please
see docs/examples/events for an example using xml, yaml, and annotations.
--------------------------------------------------------------------------------
AOP
===
Aspects work via an implementation of the interceptor pattern. There are 2
available interceptors, both of them available in xml, yaml, and annotation
drivers.

* Method: Use this one to be called before every method
 execution (use proceed() to continue the chained execution), resuming your
 own afterwards.

* Exception: Use this one to be called when an aspected
 method throws an exception.

--------------------------------------------------------------------------------
MVC
===
The mvc is work in progress, but you can sneak peek it in docs/examples/mvc. 
You will need a rewrite rule, like: 

url.rewrite-once = ( "^/(.*)" => "/example.php" ) // for lighttpd

Apache's mod_rewrite should be pretty much the same thing. The objective is
to send everything (literally) to 1 file, that is also the '/' of your
virtualhost.

The example is mapped to /Some/Mapped/Path/MyController/some (hint: try it with
?a=b). If you press the button, the form will be submitted and handled by another
action that will print the same data, but now for the post instead of the
initial get.

Also, if you want to trigger an exception to see the exception handler in
action, point your browser to: /Some/Mapped/Path/MyController/someException

To try a redirect (no view render, just headers sent), point your browser to 
/Some/Mapped/Path/MyController/redirect
This uses an http header 302.

To try an internal redirect (forward), point your browser to 
/Some/Mapped/Path/MyController/forward.
This will internally forward the request to another controller/action.

To try annotated controllers (see below), point your browser to 
/Some/Mapped/Path/MyAnnotatedController/an.

MVC Annotations
---------------

You can use @Controller and @RequestMapping in your classes and not declare
them in beans.xml file. see docs/examples/mvc/annotatedController

You can also use Twig to render the views. see docs/examples/mvc-twig
You can also use Smarty to render the views. see docs/examples/mvc-smarty
--------------------------------------------------------------------------------
TCPClient
=========
You can use the helper TCPClientHelper as just another bean. Via callbacks and
combining the helpers for error and signal handling, you can easily create a
very complete tcp client, using non blocking sockets. Available callbacks:
* Before the connection.
* As soon as the connection establishes
* If the connection failed because of a timeout.
* When data is available to be read.
* When the connection is closed by either one of the peers.

You can specify the connection timeout, the read timeout (both in milliseconds)
and the minimum needed bytes in the socket before considering it as available
data to be read.

see docs/examples/tcp for an example of use.

When using non blocking connects, be aware that php will call your error
handler with an "operation in progress" message that is completely normal but
it seems there is no way to disable it without interferring with other 
messages :(
--------------------------------------------------------------------------------
TCPServer
=========
You can use the helper TCPServerHelper as just another bean. Via callbacks and
combining the helpers for error and signal handling, you can easily create a
very complete tcp server, using non blocking sockets. Available callbacks:
* Before opening the socket.
* Before binding and listening the socket.
* As soon as a connection establishes or closes.
* When data is available to be read.
* When the connection is closed by either one of the peers.
* When there is a read timeout on any of the clients.

You can specify the connection timeout, the read timeout (both in milliseconds)
and the minimum needed bytes in the socket before considering it as available
data to be read.

see docs/examples/tcp for an example of use.
--------------------------------------------------------------------------------
ErrorHandling
=============
You can configure the optional bean ErrorHandler using the class
Ding\Helpers\ErrorHandler\ErrorHandlerHelper to quickly implement an error
handler for your app, see the examples.

@ErrorHandler
=============
Annotate a class with this annotation will have the same result has declaring
a bean in beans.xml.

--------------------------------------------------------------------------------
SignalHandling
==============
You can configure the optional bean SignalHandler using the class
Ding\Helpers\SignalHandler\SignalHandlerHelper to quickly implement a signal
handler for your app, see the examples. You will need declare(ticks=1) as the
first line of your script.

@SignalHandler
=============
Annotate a class with this annotation will have the same result has declaring
a bean in beans.xml.
--------------------------------------------------------------------------------
ShutdownHandling
================
You can configure the optional bean ShutdownHandler using the class
Ding\Helpers\ShutdownHandler\ShutdownHandlerHelper to quickly implement a 
shutdown handler for your script via register_shutdown_function().

@ShutdownHandler
================
Annotate a class with this annotation will have the same result has declaring
a bean in beans.xml.
--------------------------------------------------------------------------------
HttpSession
===========
A helper so you can access the session from the mvc. You can setAttribute()'s
and getAttribute()'s, destroy() it, etc. See the mvc example.
--------------------------------------------------------------------------------
PAMIHelper
==========
This helper integrates PAMI (https://github.com/marcelog/PAMI) with Ding, 
offering a quick, easy, and effective way to access and manager asterisk
installations via the asterisk manager interface (ami). 

See: docs/examples/pami
--------------------------------------------------------------------------------
PAGIHelper
==========
This helper integrates PAGI (https://github.com/marcelog/PAGI) with Ding, 
offering a quick, easy, and effective way to make agi (Asterisk Gateway
Interface) applications (PrePaid systems, voicemail's, etc). 

See: docs/examples/pagi

In order to run the example, you need something like this in your dialplan:

[default]
exten => _X,1,AGI(/tmp/Ding/docs/examples/pagi/run.sh,a,b,c,d)
exten => _X,n,Hangup

Call to extension 1 and extension 2 (modify the example if you want another
extensions). Use other digit to invoke the default extension.
--------------------------------------------------------------------------------
Syslog
======
Try the SyslogHelper to easily add syslogging to your own application.
See docs/examples/syslog.
--------------------------------------------------------------------------------
Timers
======
You can setup TimerHelper's and configure any timers you'd like to have in
your application, giving the interval in milliseconds and using your own
handlers.
--------------------------------------------------------------------------------
Integration with other frameworks
=================================
See our doctrine2 integration:
https://github.com/marcelog/Ding/tree/master/docs/examples/doctrine

See the pami example: https://github.com/marcelog/Ding/tree/master/docs/examples/pami

See the pagi example: https://github.com/marcelog/Ding/tree/master/docs/examples/pagi
--------------------------------------------------------------------------------
Developers
==========
* build.xml is a phing build file, not ant.
* It's very possible that you may need to edit build.properties.
* Available main targets: all, build, test, report.
* Tools run: phpdoc, phploc, phpcs, phpmd, phpcpd, phpdepend, phpunit.
--------------------------------------------------------------------------------
Debugging, logging
==================

NOTE: log4php is NOW A REQUIREMENT. The dummy logger is gone.

You need log4php (http://logging.apache.org/log4php/).
Just make sure you copy it to the include_path and Ding will pick it up from there.

Of course it is recommended that you do not set DEBUG output in your log4php
configuration (or remove it from the include path so Ding will notice and not
use it). This *will* create a difference in performance.
--------------------------------------------------------------------------------
Performance tips
================
* Try to have small include paths. Ding will use the include path for finding
resources and autoload your own classes.
* Configure the rootLogger and ding logger in ERROR level.
* If your code is running on the php module for apache or iis, use apc for
all the cache subsytems. Otherwise, use memcached or file.
* Do not use annotations at all. Only use the XML or even better, YAML.
* If you are using annotations (good for you! just dont abuse ;)) use the
annotations cache with apc or memcached or file (in that order).
* Do not include the driver you wont be using (like SignalHandler, ErrorHandler,
Shutdown, etc).
* Do not abuse the aop feature.
--------------------------------------------------------------------------------

 Collaborators:
 ============
agvstin | agu.gutierrez@gmail.com
--------------------------------------------------------------------------------
ThanksTo
--------
jonathaningram for his issue reports.
BinPress and all the people involved in the 2011 BinPress Programming Contest.
--------------------------------------------------------------------------------
