Skip to content

Getting Started

ccapndave edited this page Apr 11, 2011 · 14 revisions

This is a step-by-step guide to setting up a simple Flextrine project. Topics touched on in this document will be expanded upon in later documentation, but this a good place to get an idea of the fundamentals of Flextrine and how to apply them in your projects.

1. Setting up the server

The first thing to do is to setup the server side component of Flextrine. This is contained within the php folder of the distribution. The quickest and easiest way to make Flextrine ready for use is merely to make the php/web directory accessible via a URL (either through a VHost or an alias). For the purposes of this tutorial we will assume that you have configured the URL http://localhost/flextrine to point at this directory.

2. Creating an empty Flextrine server-side application

We now need to create a blank server-side app and for this we'll use the Flextrine console tool. Open up a console window, and move to the php/bin directory. Then execute the following command:

flextrine app:create myapp

This will create an new app called myapp. If you look in the php/apps directory you will see a new myapp folder containing an empty Flextrine project.

3. Configuring the database

Create a new database for your Flextrine project, configure a user and password with access to the database and then edit php/myapp/config/development.yml accordingly.

For example, if you had created a MySQL database called myflextrinedb, with user myflextrineuser and password password the config file might read:

connection_options:
  dbname: myflextrinedb
  user: myflextrineuser
  password: password
  host: localhost
  driver: pdo_mysql

The rest of the application's development.yml can be left at its default settings.

4. Create a persistent entity

Now we'll define a persistent entity for our application. In order to keep things simple we're just going to create one entity with no associations. In Flextrine entities are defined as PHP classes.

Create a new folder vo in php/apps/myapp/entities, and within that create a file Doctor.php:

<?php
namespace vo;

/**
 * @Entity
 */

class Doctor {

    /** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
    public $id;
    
    /** @Column(length=100, type="string") */
    public $name;
    
}

This is the simplest of entities - a Doctor object that has an auto-generated id and a name.

See the Entities documentation for more details on creating entities.

5. Create the database schema

We'll now use the console tool to generate an appropriate schema for the database.

flextrine orm:schema-tool:create

Under the hood Flextrine (in fact Doctrine) will have examined your entities and worked out the most appropriate tables and columns to store your entities. In this case the following simple SQL will have been executed:

CREATE TABLE doctor (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
);

6. Create a Flex project

Create a new Flex project in your favourite IDE and add either the as3/flextrine/src folder or the as3/flextrine/bin/flextrine.swc library to your classpath.

IMPORTANT: If you are using Flex 3 you need to add the following to additional compiler options:

-keep-as3-metadata += Id Association Entity

This is not necessary if you are using Flex 4.

Now its necessary to generate AS3 classes matching our PHP class. Use the following console command to generate the AS3 classes. Replace <my_flex_src_folder> with the relative or absolute path to the src folder of your newly created Flex project.

flextrine as3:generate-entities <my_flex_src_folder>

This will create a new package vo containing Doctor.as and DoctorEntityBase.as.

7. Write some code!

Everything is now setup to start using our Doctor entity in a Flex application. Create a new MXML file called FlextrineExample.mxml and set it as the entry point to your application. In order to get started with Flextrine we need to obtain a reference to the EntityManager (which is the central access point to Flextrine's functionality). We also need to configure it - at a minimum this means giving it the URL we setup for the Flextrine server-side component in step 1.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="creationComplete()">
        <mx:Script>
                <![CDATA[
                        import org.davekeen.flextrine.orm.Configuration;
                        import org.davekeen.flextrine.orm.EntityManager;
                        import vo.Doctor;

                        private var em:EntityManager;

                        private function creationComplete():void {
                                // Get the EntityManager and configure it to point at our server-side component
                                em = EntityManager.getInstance();
                                
                                var configuration:Configuration = new Configuration();
                                configuration.gateway = "http://localhost/flextrine/gateway.php";
                                em.setConfiguration(configuration);
                                
                                // Put your Flextrine code here!
                        }
                        
                ]]>
        </mx:Script>
</mx:Application>

Now lets use Flextrine to create some new doctors. To tell Flextrine to create a new object in the database we use the persist method on EntityManager, passing the entity we want to persist as the parameter.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="creationComplete()">
        <mx:Script>
                <![CDATA[
                        import org.davekeen.flextrine.orm.Configuration;
                        import org.davekeen.flextrine.orm.EntityManager;
                        import vo.Doctor;

                        private var em:EntityManager;

                        private function creationComplete():void {
                                // Get the EntityManager and configure it to point at our server-side component
                                em = EntityManager.getInstance();
                                
                                var configuration:Configuration = new Configuration();
                                configuration.gateway = "http://localhost/myflextrineproject/gateway.php";
                                em.setConfiguration(configuration);
                                
                                // Create some doctors
                                var doctorRobert:Doctor = new Doctor();
                                doctorRobert.name = "Doctor Robert";
                                em.persist(doctorRobert);
                                
                                var doctorBorquin:Doctor = new Doctor();
                                doctorBorquin.name = "Doctor Borquin";
                                em.persist(doctorBorquin);
                                
                                em.flush();
                        }
                        
                ]]>
        </mx:Script>
        
</mx:Application>

Notice that we call flush on EntityManager after persisting the two Doctors. Flextrine doesn't actually make any changes on the database until we call this method; instead it queues up all the things it needs to do until we call flush at which point it executes everything on the server. The doctor table in the database now contain two rows, one for Doctor Robert and another for Doctor Borquin.

This time lets retrieve the doctors in the database and show them in a DataGrid.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="creationComplete()">
        <mx:Script>
                <![CDATA[
                        import org.davekeen.flextrine.orm.Configuration;
                        import org.davekeen.flextrine.orm.EntityManager;
                        import vo.Doctor;

                        private var em:EntityManager;

                        private function creationComplete():void {
                                // Get the EntityManager and configure it to point at our server-side component
                                em = EntityManager.getInstance();
                                
                                var configuration:Configuration = new Configuration();
                                configuration.gateway = "http://localhost/myflextrineproject/gateway.php";
                                configuration.entityTimeToLive = -1;
                                em.setConfiguration(configuration);
                                
                                dataGrid.dataProvider = em.getRepository(Doctor).entities;
                                em.getRepository(Doctor).loadAll();
                        }
                        
                ]]>
        </mx:Script>
        
        <mx:DataGrid id="dataGrid" width="100%" height="100%">
                <mx:columns>
                        <mx:DataGridColumn dataField="name" />
                </mx:columns>
        </mx:DataGrid>
        
</mx:Application>

In this example we bind the dataProvider of the DataGrid to the entities in the Doctor EntityRepository. Check out the EntityRepository page for more details on this class, but very simply you can think of an EntityRepository as your local copy of the objects in the database. It starts out empty, but as you persist and load objects from the server the repositories fill up with objects. There is one EntityRepository for each entity - in this case we are binding to the entities in the Doctor repository. And since Flextrine respects databinding throughout its architecture any change in the entities of a repository will be instantly reflected in any components bound to it.

Once an entity is in an EntityRepository (either because it has been loaded or persisted) Flextrine will start watching that entity for changes, and if any of its properties change it will schedule that entity for an update on the next flush. This means that we can very simply add editing capability to our example.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="creationComplete()">
        <mx:Script>
                <![CDATA[
                        import org.davekeen.flextrine.orm.Configuration;
                        import org.davekeen.flextrine.orm.EntityManager;
                        import vo.Doctor;
                        
                        private var em:EntityManager;
                        
                        private function creationComplete():void {
                                // Get the EntityManager and configure it to point at our server-side component
                                 em = EntityManager.getInstance();
                                
                                var configuration:Configuration = new Configuration();
                                configuration.gateway = "http://localhost/myflextrineproject/gateway.php";
                                configuration.entityTimeToLive = -1;
                                em.setConfiguration(configuration);
                                
                                dataGrid.dataProvider = em.getRepository(Doctor).entities;
                                em.getRepository(Doctor).loadAll();
                        }
                        
                ]]>
        </mx:Script>
        
        <mx:DataGrid id="dataGrid" width="100%" height="100%" editable="true" valueCommit="em.flush()">
                <mx:columns>
                        <mx:DataGridColumn dataField="name" />
                </mx:columns>
        </mx:DataGrid>
        
</mx:Application>

All we have done here is to set editable="true", and added an event handler that tells the EntityManager to flush when a row is changed. Flextrine and Flex databinding takes care of the rest, ensuring that any changes to a Doctor are queued up and written to the database as required.

Note! You may have noticed that there is an extra configuration line in the last two examples - configuration.entityTimeToLive = -1;. Since Flextrine 0.9 the entities collection is weakly referenced which means that entities in repositories become eligible for garbage collection after a certain amount of time (by default 5 seconds) unless there is a strong reference to them somewhere in your application. For simplicity's sake in this example we are disabling garbage collection in repositories by setting the entityTimeToLive to -1. See Garbage Collection for more details.

Conclusion

It is quite simple to create powerful data driven applications with Flextrine. However, the full capabilities of Flextrine become apparent when you start using associations to link objects together. Read through the rest of the documentation for more details.