PHOCOA has a very large set of technologies. Because it is based on Cocoa (Apple's development infrastructure), if you are a Cocoa programmer things will make a lot of sense to you. If you are not familar with Cocoa, there is a bit of a learning curve. But trust us, it's worth it. The power of PHOCOA will allow you to deliver robust web applications with minimal coding in record time.
Instead of starting off by explaining all of the concepts and technologies, we will first walk you through the steps to build a simple application (a blog) to show you how easy it is to write PHOCOA applications. You will be much more motivated to learn the concepts when you realize how much time PHOCOA can save you.
This chapter will walk you through the development of a simple blog application that shows off all of the basic concepts. We will explain each concept as simlpy as possible for the example.
PHOCOA comes with a shell script to help you manage common PHOCOA tasks. This script is aptly named phocoa.
![]() | If you're not using a PEAR install of PHOCOA, the phocoa command won't be in your path. The phocoa command is located at phocoa/phing/phocoa. We recommend that you alias it to avoid having to type the entire path each time. |
Let's use phocoa to create a new workspace for our blog project.
$ phocoa newProject
phing -f /Users/alanpinstein/dev/sandbox/phocoa/phocoa/phing/build.xml -Dusing.phocoa.make=true -Dphocoa.pwd=/Users/alanpinstein/dev/sandbox
-Dphocoa.dir=/Users/alanpinstein/dev/sandbox/phocoa/phocoa -Dphocoa.project.name= -Dphocoa.project.dir= newproject
Buildfile: /Users/alanpinstein/dev/sandbox/phocoa/phocoa/phing/build.xml
phocoa > prepareGeneral:
[echo] PHOCOA framework base dir at: /Users/alanpinstein/dev/sandbox/phocoa/phocoa
phocoa > newProject:
Enter the name of the new project: [] blog
[echo] The container directory for your PHOCOA project will be used to place the log, runtime, and project directories. Please be careful!
Enter the path to the project container directory: [/Users/alanpinstein/dev/sandbox/blog]
[realpathexpandhome] Resolved /Users/alanpinstein/dev/sandbox/blog to /Users/alanpinstein/dev/sandbox/blog
Enter the name of the server (ie dns name) that will host this application: [localhost] blog.phocoa.com
Enter the IP of the server that will host this application: [127.0.0.1] 10.0.1.201
Enter the PORT of the server that will host this application: [80] 8080
[phingcall] Calling Buildfile '/Users/alanpinstein/dev/sandbox/phocoa/phocoa/phing/build.xml' with target 'setupProjectContainer'
phocoa > setupProjectContainer:
[echo] Creating project container directories and setting up permissions
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/log
[chmod] Changed file mode on '/Users/alanpinstein/dev/sandbox/blog/log' to 777
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/runtime
[chmod] Changed file mode on '/Users/alanpinstein/dev/sandbox/blog/runtime' to 777
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/runtime/smarty/templates_c
[chmod] Changed file mode on '/Users/alanpinstein/dev/sandbox/blog/runtime/smarty/templates_c' to 777
[echo] Creating project directory: /Users/alanpinstein/dev/sandbox/blog/blog
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/blog
[echo] Copying PHOCOA templates...
[copy] Copying 9 files to /Users/alanpinstein/dev/sandbox/blog/blog
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/blog/wwwroot/www
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/blog/modules
[echo] Setting up configuration files...
[copy] Copying 3 files to /Users/alanpinstein/dev/sandbox/blog/blog
[filter:ReplaceTokens] Replaced "##SERVER_IP##" with "10.0.1.201"
[filter:ReplaceTokens] Replaced "##SERVER_PORT##" with "8080"
[filter:ReplaceTokens] Replaced "##SERVER_NAME##" with "blog.phocoa.com"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_BASE_DIR##" with "/Users/alanpinstein/dev/sandbox/phocoa/phocoa"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_BASE_DIR##" with "/Users/alanpinstein/dev/sandbox/phocoa/phocoa"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_CONTAINER_DIR##" with "/Users/alanpinstein/dev/sandbox/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_CONTAINER_DIR##" with "/Users/alanpinstein/dev/sandbox/blog"
[filter:ReplaceTokens] No token defined for key "##PHOCOA_APP_DIRBASE_DIR##"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_BASE_DIR##" with "/Users/alanpinstein/dev/sandbox/phocoa/phocoa"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_CONTAINER_DIR##" with "/Users/alanpinstein/dev/sandbox/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_CONTAINER_DIR##" with "/Users/alanpinstein/dev/sandbox/blog"
[filter:ReplaceTokens] Replaced "##PHOCOA_APP_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/blog"
[phingcall] Calling Buildfile '/Users/alanpinstein/dev/sandbox/phocoa/phocoa/phing/build.xml' with target 'httpdconf'
phocoa > prepareGeneral:
[echo] PHOCOA framework base dir at: /Users/alanpinstein/dev/sandbox/phocoa/phocoa
phocoa > prepareProject:
[echo] 1
[php] Evaluating PHP expression: $_ENV['_']
[echo] PHOCOA project dir at: /Users/alanpinstein/dev/sandbox/blog/blog
[realpathexpandhome] Resolved /Users/alanpinstein/dev/sandbox/blog/blog/.. to /Users/alanpinstein/dev/sandbox/blog
[echo] PHOCOA project container dir at: /Users/alanpinstein/dev/sandbox/blog
[property] Loading /Users/alanpinstein/dev/sandbox/blog/blog/conf/build.properties
[property] Unable to find property file: /Users/alanpinstein/dev/sandbox/blog/blog/conf/build.properties... skipped
phocoa > httpdconf:
[echo] PHOCOA requires some httpd configurations to work its magic. You must either be able to edit httpd.conf, or have an apache with mod_rewrite enabled.
Select httpd configuration mode: 1=httpd.conf, 2=.htaccess [1] 1
[echo] Make sure your httpd.conf file contains the line: Include /Users/alanpinstein/dev/sandbox/blog/blog/blog/conf/httpd.conf
Will this project use database access via Propel?(yes/no) [1] yes
[phingcall] Calling Buildfile '/Users/alanpinstein/dev/sandbox/phocoa/phocoa/phing/build.xml' with target 'addpropel'
phocoa > prepareGeneral:
[echo] PHOCOA framework base dir at: /Users/alanpinstein/dev/sandbox/phocoa/phocoa
phocoa > prepareProject:
[echo] 1
[php] Evaluating PHP expression: $_ENV['_']
[echo] PHOCOA project dir at: /Users/alanpinstein/dev/sandbox/blog/blog
[realpathexpandhome] Resolved /Users/alanpinstein/dev/sandbox/blog/blog/.. to /Users/alanpinstein/dev/sandbox/blog
[echo] PHOCOA project container dir at: /Users/alanpinstein/dev/sandbox/blog
[property] Loading /Users/alanpinstein/dev/sandbox/blog/blog/conf/build.properties
[property] Unable to find property file: /Users/alanpinstein/dev/sandbox/blog/blog/conf/build.properties... skipped
phocoa > addpropel:
[echo] Setting up PHOCOA project for Propel in dir: /Users/alanpinstein/dev/sandbox/blog/blog/propel-build
Select the path for executable: propel-gen: /Users/Shared/src/propel-1.3.0beta2/generator/bin/propel-gen
[selectExecutable] Using propel-gen at /Users/Shared/src/propel-1.3.0beta2/generator/bin/propel-gen
[mkdir] Created dir: /Users/alanpinstein/dev/sandbox/blog/blog/propel-build
Enter the database type:(pgsql,mysql,mssql,sqllite,ldap) pgsql
Enter the database name: blog
Enter the database username: blog
Enter the database password:
Enter the database host: [localhost]
[writeconffile] Writing conf file: /Users/alanpinstein/dev/sandbox/blog/blog/propel-build/build.properties.
[echo] Building Propel... setup conf file, reverse engineer database, build db classes.
[copy] Copying 1 file to /Users/alanpinstein/dev/sandbox/blog/blog/propel-build
[filter:ReplaceTokens] Replaced "##LOG_DIR##" with "/Users/alanpinstein/dev/sandbox/blog/log"
[filter:ReplaceTokens] Replaced "##PHOCOA_PROJECT_NAME##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_NAME##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_NAME##" with "blog"
[filter:ReplaceTokens] Replaced "##PROPEL_DATABASE##" with "pgsql"
[filter:ReplaceTokens] Replaced "##PROPEL_DATABASE##" with "pgsql"
[filter:ReplaceTokens] Replaced "##DB_NAME##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_USER##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_HOST##" with "localhost"
[filter:ReplaceTokens] Replaced "##DB_PASS##" with ""
[filter:ReplaceTokens] Replaced "##PROPEL_DATABASE##" with "pgsql"
[filter:ReplaceTokens] Replaced "##DB_HOST##" with "localhost"
[filter:ReplaceTokens] Replaced "##DB_NAME##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_USER##" with "blog"
[filter:ReplaceTokens] Replaced "##DB_PASS##" with ""
[exec] Executing command: /Users/Shared/src/propel-1.3.0beta2/generator/bin/propel-gen /Users/alanpinstein/dev/sandbox/blog/blog/propel-build convert-props 2>&1
[exec] Buildfile: /Users/Shared/src/propel-1.3.0beta2/generator/build.xml
[exec] [resolvepath] Resolved /Users/alanpinstein/dev/sandbox/blog/blog/propel-build to /Users/alanpinstein/dev/sandbox/blog/blog/propel-build
[exec]
[exec] BUILD FAILED
[exec] Target 'convert-props' does not exist in this project.
[exec] Total time: 0.1039 seconds
[echo] Propel general setup complete.
[echo] To complete propel integration, complete the following manual tasks:
[echo] 1. Make sure that propel is available in your include_path. If not, edit webapp.conf and munge include_path.
[echo] 2. Add define('PROPEL_CONF', APP_ROOT . '/conf/blog-conf.php'); to your webapp.conf.
[echo] 3. Add Propel::init(PROPEL_CONF); to your WFWebApplicationDelegate's initialize() method.
[echo] 4. Edit the propel/runtime/classes/propel/om/BaseObject.php BaseObject declaration to this: 'abstract class BaseObject extends WFObject'.
If your database already exists, we can generate a PHP interface to your database objects. Does your database already exist?(yes/no) [] no
[echo] Skipping Propel code generation. You can always generate your classes with Propel in the future:
[echo] /Users/Shared/src/propel-1.3.0beta2/generator/bin/propel-gen /Users/alanpinstein/dev/sandbox/blog/blog/propel-build main
[echo] Done adding Propel support.
[echo] New Project setup complete.
BUILD FINISHED
Total time: 36.6166 seconds
You should now have a directory blog containing your new PHOCOA application.
$ ls -l blog total 0 drwxr-xr-x 8 alanpins showcase 272 Sep 11 14:20 blog drwxrwxrwx 2 alanpins showcase 68 Sep 11 14:20 log drwxrwxrwx 3 alanpins showcase 102 Sep 11 14:20 runtime
This directory contains your PHOCOA deployment structure. This directory is called the container directory because it contains your web application, including your PHOCOA application project. Typically, log and runtime (tmp / cache) files are not part of your source code, so PHOCOA sets up a container directory for these items.
The blog directory inside of this deployment structure is your PHOCOA application directory.
![]() | The application directory is the root directory of your PHOCOA application code, and is what you should check in to your version control system. The log and runtime directories are not versioned resources, thus we keep them one level up in the container directory for organizational purposes. |
Now let's have a look at the directory structure.
$ ls -l blog/blog total 0 drwxr-xr-x 3 alanpins showcase 102 Sep 11 14:20 classes drwxr-xr-x 6 alanpins showcase 204 Sep 11 14:21 conf drwxr-xr-x 2 alanpins showcase 68 Sep 11 14:20 modules drwxr-xr-x 4 alanpins showcase 136 Sep 11 14:21 propel-build drwxr-xr-x 3 alanpins showcase 102 Sep 11 14:20 skins drwxr-xr-x 4 alanpins showcase 136 Sep 11 14:20 wwwroot
The classes directory is where all of your classes go. These are classes specific to your application.
The conf directory contains all configuraiton files.
The modules directory is where all components go. These components are the building blocks of your application and include both entire pages and sub-components.
The skins directory is where all skins go.
The wwwroot directory is a public wwwroot that contains the front controller for the PHOCOA project. All public documents (i.e. the tradiditional public www root) go in wwwroot/www/.
A new PHOCOA project will have 2 config files. The first is the Apache config file, httpd.conf, followed by the web app config file, webapp.conf.
$ ls -l conf total 16 -rw-r--r-- 1 alanpins showcase 2594 May 10 15:41 httpd.conf -rw-r--r-- 1 alanpins showcase 2770 Sep 11 23:03 webapp.conf
Usually, you won't need to edit any of these files to get things working.
You will need to edit your main Apache conf file to include the conf file for this host, like so:
Include /path/to/blog/blog/conf/httpd.conf
Now restart Apache.
If everything worked, you should be able to go to your web host your specified in the newproject build and see the PHOCOA examples page.
At this point, you should be able to access the site via the web. You should be able to access the application via http://servername/ and see the PHOCOA examples page.
Now, we can move on to the tutorial!