<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>GroundOS Owners Manual</title>
<style>
body {
font-size:11px;
font-family:Verdana;
}
p {
padding:0 20px 0 20px;
}
pre {
background:#f5fbff;
overflow:scroll;
border: 1px solid #777777;
font-family:Courier New;
font-size:14px;
}
h1 {
text-decoration:underline;
}
h2 {
border-top:1px solid #777777;
margin: 20px 0 20px 0;
padding:10px 0 0 0;
}
.paragraph {
border: 1px solid #777777;
padding:20px 20px 40px 20px;
margin: 20px 20px 40px 20px;
background:#eeeeee;
}
table, tr, td {
font-size:14px;
border: 1px solid #777777;
}
</style>
</head>
<body>
<img src="./data/gif/logo001.gif" alt="GroundOS" />
<div class="paragraph">
<h1>GroundOS Owners Manual</h1>
<br />
<h1>Table of Contents</h1>
<ul>
<li><a href="#license">GroundOS Owner's Manual License</a></li>
<li><a href="#intro">Introduction</a></li>
<li><a href="#corephil">Core Philosophies</a>
<ul>
<li><a href="#opencloud">Open Source Cloud Computing</a></li>
<li><a href="#socialcloud">P2P Social Cloud Computing</a></li>
<li><a href="#projectgoals">Project Goals</a></li>
<li><a href="#appphil">The Application is the Foundation</a></li>
<li><a href="#phpframe">PHP Framework Philosophies</a></li>
<li><a href="#groundphil">GroundOS Philosophies</a></li>
<li><a href="#dephil">Depreciation Philosophies</a></li>
<li><a href="#agile">Our Implementation of Agile Software Development</a></li>
<li><a href="#versionnumber">Version Numbering and Development Timeframes</a></li>
<li><a href="#peerreview">Peer Review</a></li>
</ul>
</li>
<li><a href="#3rdparty">3rd Party PHP and Javascript Libraries</a>
<ul>
<li><a href="#3rdintro">Introduction</a></li>
</ul>
</li>
<li><a href="#structure">The Structure of an Application</a>
<ul>
<li><a href="#structurelogic">The Structure of Logic Files</a></li>
<li><a href="#structureviews">The Structure of View Files</a></li>
<li><a href="#structureconfig">The Structure of config.php Files</a></li>
</ul>
</li>
<li><a href="#hello1">Manually Creating a "Hello World!" Application</a>
<ul>
<li><a href="#hello1intro">Intro</a></li>
<li><a href="#hello1files">Files to Create</a></li>
<li><a href="#hello1config">Contents of config.php</a></li>
<li><a href="#hello1logic">Contents of the Default Logic File</a></li>
<li><a href="#hello1view">Contents of the Default View File</a></li>
<li><a href="#hello1test">Testing Your Application</a></li>
</ul>
</li>
<li><a href="#wwb">Windows, Widgets, and Bears, Oh My!</a></li>
<li><a href="#dad">Dialogs, Alerts, and Debugs</a></li>
<li><a href="#topics">How to Use Topics</a></li>
<li><a href="#users">The User System</a>
<ul>
<li><a href="#userintro">Intro</a></li>
<li><a href="#userpass">Password Format</a></li>
<li><a href="#usercookies">Login Cookies</a></li>
<li><a href="#userpermissions">User Permissions</a></li>
</ul>
</li>
<li><a href="#input">Handling Input</a></li>
<li><a href="#debug">Debug and Error Reporting</a></li>
<li><a href="#sitedesigner">Site Designer</a>
<ul>
<li><a href="#sitedesignerview">Contents of a Default Site Designer View File</a></li>
</ul>
</li>
<li><a href="#"></a></li>
<li><a href="#devfaq">Developer's FAQ (Frequently Asked Questions)</a></li>
</ul>
</div>
<div class="paragraph">
<h1><a name="license">GroundOS Owner's Manual License</a></h1>
<p>
This manual and all example source code within this documentation is licensed under the MIT license:<br /><br />
Copyright 2009 (C) Agares Media.<br />
<br />
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
<br /><br />
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
<br /><br />
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
</p>
</div>
<div class="paragraph">
<h1><a name="intro">Introduction</a></h1>
<p>
Cloud computing is used by companys to allow distributed access to online applications. However, up until now,
there has been no easy way to setup your own cloud with just the applications you want. Sure, there have been
plenty of web "operating systems", but few are truely open source, and none of them offer the power and true
freedom to give you complete control of everything regarding <i>your</i> cloud.
</p>
<p>
GroundOS is a web based, Ajax appliance server, written on top of the AgaresCore 4 PHP framework. With GroundOS, you can
setup your own private (or public) cloud that you can access from anywhere.
</p>
<p>
This developers guide was written during the actual development of AgaresCore 4 and GroundOS, and is intended to
document the inner workings of both AgaresCore 4, the PHP/AJAX framework, and GroundOS, the cloud content
management system (CCMS)
</p>
<p>Now it may seem a bit odd at first that this is essentially one product with several names, but the reality is
that AgaresCore 4 and GroundOS are two seperate things. AgaresCore 4 is simply the PHP/AJAX framework that GroundOS
was built on top of/from. AgaresCore 4 is not tied to GroundOS, but GroundOS cannot function without AgaresCore 4. It
should be noted that both AgaresCore 4 and GroundOS would not be possible if weren't for many open source libraries
from which the entire system is based. For the AJAX side of things, we use the Prototype library. For the windowing
system we use the windowsjs library.
</p>
</div>
<div class="paragraph">
<h1><a name="corephil">Core Philosophies</a></h1>
<ul>
<li><a href="#opencloud">Open Source Cloud Computing</a></li>
<li><a href="#socialcloud">Social Cloud Computing</a></li>
<li><a href="#projectgoals">Project Goals</a></li>
<li><a href="#appphil">The Application is the Foundation</a></li>
<li><a href="#phpframe">PHP Framework Philosophies</a></li>
<li><a href="#groundphil">GroundOS Philosophies</a></li>
<li><a href="#dephil">Depreciation Philosophies</a></li>
<li><a href="#agile">Our Implementation of Agile Software Development</a></li>
<li><a href="#versionnumber">Version Numbering and Development Timeframes</a></li>
<li><a href="#peerreview">Peer Review</a></li>
</ul>
<h2><a name="opencloud">Open Source Cloud Computing</a></h2>
<p>
Cloud computing is such an overused buzzword at this point, however the reality is that this technology has yet to
fully peak. Cloud computing is here to stay, but in it's current state there are some fundamental issues that need
to be addressed before it matures. Currently cloud computing is little more than a marketing buzzword, used to dress
up the cold ugly business model of renting software, with the additional cost of losing your rights and abilities to fully
protect and control your data, all in exchange for the convience of a web based application. In reality, the entire cloud
computing business model revolves around vendor lock-in, through proprietary and closed source software that is either ad
supported, subscription based, and/or the sale of personal information. With a truely free and open source cloud solution,
the possibilities are endless. We can make cloud computing beneficial for the masses by restoring the freedom and control over the cloud
back to the individual. On that note, here is our
rebutal to the current state of cloud computing:
</p>
<ul>
<li>1. Cloud computing has taken away our ability to fully control the applications that we use.</li>
<li>2. Cloud computing has made it impossible to encrypt or protect our data, and exposes our data to privacy risks.</li>
<li>3. Cloud computing often requires subjection to targeted ads, regular subscription fees, and/or data mining.</li>
<li>4. Cloud computing has taken away our ability to fully control our own data, subjecting us to data loss through service termination.</li>
<li>5. Cloud computing has taken away our ability to host our cloud where ever we want or need.</li>
</ul>
<p>
Instead of complaining about these problems, we've simply done our best to correct them. Here's how:
</p>
<ul>
<li>1. GroundOS gives you the ability to fully control all the applications that you use, with full source code for everything.</li>
<li>2. GroundOS gives you the ability to encrypt and protect your data, through multiple security settings and SSL support.</li>
<li>3. GroundOS is completely open source, free of charge, and free of ads.</li>
<li>4. GroundOS gives you the ability to set up your own cloud, so there's no services to terminate.</li>
<li>5. GroundOS gives you the ability to set up your own cloud where ever you wants, whether at home, the office, a hosting company, or even a data center.</li>
</ul>
<h3>1. Cloud computing has taken away our ability to fully control the applications that we use.</h3>
<p>
If a cloud service goes away, you can no longer use it. If it's lacking a feature you need, you can not add it. If you need
to access the service, but they've decided to take it down for maintainence for a few hours, you have no control over that.
Regardless whether or not the cloud service you use requires a paid subscription or not, the reality is that it is not free.
It comes with the price of sacrificing freedom for the convience of the cloud. Unfortunately the current cloud computing
business model relies on taking control away from you, so that way they can serve you ads, or they can sell you premium features.
</p>
<p>
GroundOS provides true freedom for cloud computing. Every single line of source code for everything in the system is available for
modification under an open source license. You control the cloud. If there's a feature you need, you can add it. There are
no business models set in place designed to snare you into emptying your wallet. No ads to view, no premium features to buy.
</p>
<p>
True freedom in this sense not only helps the end users, but also businesses of all sizes. The convience of cloud computing
is the ability to access the cloud from anywhere, but combined with the ability to easily modify the cloud for you or your
organizations needs makes it that much more versatile.
</p>
<h3>2. Cloud computing has made it impossible to encrypt or protect our data, and exposes our data to privacy risks.</h3>
<p>
Look closely at the terms of service you are agreeing to when you sign up for a cloud service, and generally you will
find clauses and stipulations which allow the provider access and leeway with your data. Whether its to use that data for
ad targeting, market research, or to sell subsribers data, there is almost always a sacrifice in freedom over
<i>your own data</i> involved. This wouldn't be so bad if you somehow had the ability to protect that data through SSL,
cryptography, and other methods of data security of your own choosing. However, the reality is that unless the service provider gives you all
those tools, your data is not secure.
</p>
<p>
Data theft is a growing crime, and it's hard to even know it's happened especially since when the data is "stolen" it is not
missing (the data would just be copied.) Without the ability to properly protect your data while it's on the cloud,
you're risking the loss and possible theft of that data, all the while leaving it completely exposed to any hacker
with access to the internet. That's why it's important to have full control over your cloud, that way you can protect important business data through
whatever means you deem necessary. No longer are your hands tied.
</p>
<h3>3. Cloud computing often requires subjection to targeted ads, regular subscription fees, and/or data mining.</h3>
<p>
Generally when we think of the state of commercial software today, we think of paying for an application once, and that's it (well
at least until the next major release.) However, with cloud applications, greedy software companies are trying to find
new ways to get more out of your wallet: enter the subscription based software business model. Yes, imagine a world where you rent all the
software on your computer. While you're imagining this, try to forget about the good old days when you didn't pay a monthly
bill to play your music, watch your videos, use your word processor, or play your games. It's a pretty scary scenario, and
it doesn't take much insight to see that "cloud computing" in it's current state is nothing more than a fancy way to say "renting software as a
service."
</p>
<p>
As someone who has tried subscription based cloud services, what I found over time, was that I was only continuing to pay
for the service, because I had no real way to get my valuable data in a usable form apart from the service. After a tight month
financially, it occurred to me that I may not be able to pay my bill, and would likely lose access to a lot of personal and
professional data. In short, I was no longer renting the software for it's service, but rather I was paying a ransom
each month to be able to continue to have access to my valuable data. They were holding it hostage, and it was my data!
</p>
<p>
However, not all cloud services are pay based. Many of them are "free" in the sense that they don't directly charge you money.
Instead, they display intrusive ads and/or mine your data. Consumer data is a multi billion dollar industry, and once again
the fine print in some terms of service agreements allow your data to mined.
</p>
<p>
Regardless, these cloud services provide their convienence at a real cost, which is why having a completely free and open source
cloud solution, that you can run from your own home computer, from your web hosting company, or from your data center, is the best
solution.
</p>
<h3>4. Cloud computing has taken away our ability to fully control our own data, subjecting us to data loss through service termination.</h3>
<p>
Since many cloud services require you to pay a monthly fee, the question arises, what happens to my data when I stop paying?
However, it is not just pay services that we must worry about, because all cloud services, including free and ad based systems
can have their plug pulled at anytime. So what happens when the service is disconnected or discontinued, or the company is sold to
evil corporation X, or it goes out business? Where is your data? How can you get it back? Can you even get it back? Now
maybe these questions are no big deal if your data is meaningless, but for most people, and most cloud services, we're talking about
important data, such as business material, family pictures, school essays, you name it.
</p>
<h3>5. Cloud computing has taken away our ability to host our cloud where ever we want or need.</h3>
<p>
Using cloud services has traditionally meant giving up the ability to choose where we are storing our data as well as where we
are launching/streaming our application from. This often means that although you live in one location, the cloud itself may be hosted on the
other side of the globe, continent, or country. Usually this is of little consquence, or at worst simply adds additional time to your
data transfers. However, this inconvience also means you most likely do not and will never have physical access to the machine (should the need or
scenario arise where you would typically want such access.) It also means that if your needs outpace what the provider can or will
supply (think hard drive space, processing power, memory) you don't have the ability to scale up or down as needed. In short, when
you do not have the ability to choose your hosting, you do not have the ability to control the specs of the server to match your needs, nor
do you have the access to hardware needed to assure enterprise level service.
</p>
<h2><a name="projectgoals">Project Goals</a></h2>
<p>
Before we begin looking at writing applications for GroundOS, we need to first explore the underlying philosophy
behind the architecture. Once you're familiar with the core philosophies of AC4/GroundOS it helps to shed light
on the programming style and actual implementation of the philosophies into practice. The following list highlights
the main goals of the entire system:
</p>
<ul>
<li>The project should be open source (MIT/BSD style license)</li>
<li>PHP 5 based, to take advantage of better Object Orientated programming support and try/catch blocks.</li>
<li>The final (X)HTML output should pass WCC validation.</li>
<li>The PHP code itself should not trigger any errors, warning, notices, of info errors by default. </li>
<li>The entire project should not trigger any errors, warnings, or infos when loaded into the Eclipse PDT IDE.</li>
<li>The end result should be easily extensible.</li>
<li>The entire system should be organized in a predictable and uniform manner, following modern software architecture philosophies.</li>
<li>All source code should be well documented, with examples of implementation when necessary.</li>
<li>All URI's should be search engine friendly by default.</li>
<li>The framework should be in pure PHP, but the resulting page should be principly Ajax.</li>
<li>The project should bring cloud computing into every developers hands.</li>
<li>Porting non-AC4 scripts into Applications should be a trivial task.</li>
<li>The project should contain helpful debugging and error reporting tools.</li>
<li>The project should minimize http connections, minify javascript, html, and css, and compress everything for optimal performance web speed.</li>
</ul>
<h2><a name="appphil">The Application is the Foundation</a></h2>
<p>
The focus of this entire system is on the application. Applications can contain an unlimited amount of windows, widgets, and even
applications within applications. The ability to stack applications side by side, inside of each other, or however, naturally lends itself to
the quick construction of a website. If you have one application, which handles logging in, logging out, and registering new users,
then you now have the ability to include that application within any other application (such as an ecommerce site, a flash
arcade site, etc.) The more applications you have, the greater versatility you have for a website. That's where GroundOS comes in, as it
not only manages your applications, but it can also be used as simply a private cloud server for your own personal use. Or then again,
it give you an all in one web IDE, or it can drive many a multi-site network of ad generating sites, etc. What you do with GroundOS is up to you.
</p>
<h2><a name="phpframe">PHP Framework Philosophies</a></h2>
<p>
AgaresCore 4 (abbreviated as AC4) is the PHP framework that powers GroundOS. AgaresCore 4 is a 4th generation CMS (content management
system.) It was formerly called AMCMS (Agares Media Content Management System.)
</p>
<p>
AC4 is a PHP 5 based, object orientated framework. It is intended to be standards compliant, open source, and
easily extensible. The main method to create projects and mods with AC4 is through the use of applications.
Applications can be full PHP 4 and 5 scripts, HTML files, Java apps, flash content, etc.
</p>
<p>
<strong>Data, Logic, View, Router</strong><br />
I'm a fan of the MVC (Model/View/Controller) programming philosophy, however it should be noted that AC4 is not modelled using the MVC design
principles. In practice, it is very difficult to program a web framework that <i>actually</i> adheres strictly to MVC principles, so instead
of building a framework that improperly uses and abuses the MVC, we've decided to toss it out entirely. That's not to say that we
weren't influenced by MVC, but rather we choose to address the problems of web programming head on using our own guidelines and philosophies.
</p>
<p>
AC4 splits everything into 4 parts, Data, Logic, View, and Router. If you're familiar with MVC, the approach we've taken will seem a bit familiar,
although definitely not the same.
</p>
<ul>
<li><strong>DATA</strong> - This is all data, generally being files stored in the file system (use the filesystem() class) or data stored in MySQL database (use the database() class, or more specifically, the global $database object.)</li>
<li><strong>LOGIC</strong> - This includes all classes, as well as all application logic files (located in each applications /logic/ folder.) Any interaction with the DATA layer should be done in a logic file.</li>
<li><strong>VIEW</strong> - The view simply displays information, including HTML, CSS, and Javascript (located in each applications /view/ folder.) The view should never directly interact with the DATA layer, instead it should accomplish that by calling the appropriate logic file.</li>
<li><strong>ROUTER</strong> - The router processes all URI requests</li>
</ul>
<h2><a name="groundphil">GroundOS Philosophies</a></h2>
<p>
GroundOS is first and foremost an Ajax based application for the AC4 CMS. It is intended to be an alternative to
propertiary cloud web operating systems (there's no such thing as a web operating system yet, but I digress.)
GroundOS is the main AC4 application, and it is designed to be the glue that makes the entire system
both user friendly, and extremely versatile. It does this by making access to other applications easy, through
the use of a window manager similar to desktop operating systems. Unlike most other CMS solutions, GroundOS is a completely
generic script that is meant to be put to specific use by the administrator. Where as, with a CMS like
Wordpress, you know you're working with a script designed to make an excellent blogging site. With GroundOS,
you are instead given a blank canvas, in which you could mold the script and the resulting site to your specific
needs, however diverse and unique that might be.
</p>
<h2><a name="dephil">Depreciation Philosophies</a></h2>
<p>
Too often I've invested myself into a particular API or library, writing thousands upon thousands of lines of code targeting the platform, only to
find myself with an unusable project after upgrading to the latest release of the API or library. This is because, more often than not, developers
find it easier to break backwards compatiblity then to do the extra work of upgrading and refactoring code, while maintaining full backwards
compatibility. Because of the lost time and gnashed teeth, the AC4/GroundOS depreciation philosophy is to always maintain legacy functions, classes,
and methods. Changes which break backwards compatibility will not be entered into the official code repository, so you can rest assured that an
application written for AgaresCore 4.000 will function identically under AgaresCore 4.981 (for example.) This applies starting with AC4 Release
Canidate 1 (RC1) and applies to the end of the 4.x branch. AgaresCore 5 will attempt to maintain backwards compatibility with AC4 to the greatest
degree possible.
</p>
<h2><a name="agile">Our Implementation of Agile Software Development</a></h2>
<h2><a name="versionnumber">Version Numbering and Development Timeframes</a></h2>
<p>
AC4/GroundOS is developed using agile software development methods, using the time frames and version numbering outlined below:
</p>
<ul>
<li>Bug fixes, security patches, and other critical updates will be released as soon as possible whenever necessary. These updates increment the version number by 0.0001, so if todays version number is 0.5000, the release with the updates applied would be 0.5001.</li>
<li>Every 4 weeks a new iteration is released. Iterations increment the version number by 0.01, so if todays version number is 0.5005, the next iteration released would be 0.5100.</li>
<li>Once all goals are reached for the current short term goals (this can take several iterations) the version number will be incremented by 0.1. For example, if todays daily release is version 0.5409, and tomorrow we release a new version that reaches all our version goals, then the release would be version 0.6000</li>
<li>New major version releases are made (such as version 1.0, 2.0, etc) after all project goals have been met, and the project has been beta tested by sizeable testing base for a signifigant amount of time.</li>
</ul>
<h2><a name="peerreview">Peer Review</a></h2>
<p>
One of the most critical aspects of successfully utilizing Agile software development is peer review. We openly invite open source code contributions, bug reports, suggestions, criticism, open source artwork, and any other feedback or contribution possible. As we recieve such peer review and contributions we will integrate them into our development cycle.
</p>
</div>
<div class="paragraph">
<h1><a name="3rdparty">3rd Party PHP and Javascript Libraries</a></h1>
<ul>
<li><a href="#3rdintro">Introduction</a></li>
</ul>
<h2><a name="3rdintro">Intro</a></h2>
<p>I've used most of the major javascript libraries, and each had their particular strengths and weaknesses. Over time, I've been
consistently impressed with the Prototype Ajax library, and the libraries based on Prototype (script.aculo.us, windowsjs, etc.)
For these reasons, AC4/GroundOS can be considered a PHP/Prototype fusion, meant to allow PHP programmers to easily create Ajax
based websites using the Prototype Ajax library.
</p>
<h2><a name="workingjs">Working With Javascript Within PHP</a></h2>
<p>
To include a Javascript library, use the dependancy() method of the view() class. For example, to include prototype.js in your
application, use this code in your view file:
</p>
<pre>
loadclass('view');
$view = new view();
$headbottom_output .= $view->dependancy('./libraries/3rdparty/prototype/prototype.js');
</pre>
<p>
The advantages of using the dependancy() method is
</p>
<ol>
<li>Each library loaded will only be called once, no matter how many additional dependancy calls are made.</li>
<li>The javascript is compressed using the jscompress() method.</li>
<li>The javascript file is loaded directly into the current HTML document, meaning no matter how many libraries you load, there will only be 1 http request.</li>
</ol>
</div>
<div class="paragraph">
<h1><a name="structure">The Structure of an Application</a></h1>
<p>
To be considered an "Application" in GroundOS, a project must meet all of the following criterias:
</p>
<ul>
<li>The project must be located inside it's own folder in the <strong>/applications/</strong> directory</li>
<li>The project must have a properly formated config.php in it's root directory (as in <strong>/applications/<i>yourapp</i>/config.php</strong> )</li>
<li>The project must have at least both a /view/ and /logic/ folder</li>
<li>There must be at least one corresponding logic/view set, and the default logic/view should be named index.php (as in <strong>/applications/<i>yourapp</i>/logic/index.php</strong> and <strong>/applications/<i>yourapp</i>/views/index.php</strong> )</li>
</ul>
<p>Although all applications are stored in the <strong>/applications/</strong> directory, they should not be directly accessed in
that manner. Instead, when you wish to access an Application, the URI to access that app is the root installation of AgaresCore 4,
a backslash, followed by the name of the Application. For example, although the "admin" Application is located at <strong>/applications/admin/</strong>
the correct way to access that Application would be <b>http://www.example.com/admin/</b> and <b>NOT</b> <b>http://www.example.com/applications/admin/</b>
This is because of the way URI's are routed and handled by AgaresCore 4.</p>
<p>Applications can have an unlimited number of logic and view files. For each logic file, their should be a corresponding view file with the same name.
All logic files should be placed in <strong>/applications/<i>yourapp</i>/logic/</strong> and each view file should be stored in <strong>/applications/<i>yourapp</i>/views/</strong>
</p>
<p>
When you access an Application from a URI such as <b>http://www.example.com/admin/</b> you are calling the default logic and view files for that
application. Specifically, the AC4 router will load <b>/applications/admin/logic/index.php</b> followed by <b>/applications/admin/views/index.php</b>
</p>
<p>
Aside from the default logic and view files, there can be an infinite number of logic/view combinations for each application. For example,
the admin application has a logic/view pair to display the Applications Menu. To access the App Menu directly, you would visit this URL:
<b>http://www.example.com/admin/appmenu/</b> which in turn loads this logic file: <b>/applications/admin/logic/appmenu.php</b> and this view
file: <b>/applications/admin/views/appmenu.php</b>
</p>
<h2><a name="structurelogic">The Structure of Logic Files</a></h2>
<p>Logic files are meant to process all the business logic. There should be no CSS, no HTML, and no Javascript in this file period. Instead,
this file should perform all the logic that is required, load the proper variables with the values needed by the view, and leave the
presentation of such data up to the view. In addition, this is the correct place to check user permission (using the user() class), and to access data from the
file system (using the filesystem() class) or from the database (using the global $database object reference, which is an instance of the database() class.)
</p>
<h2><a name="structureviews">The Structure of View Files</a></h2>
<p>The view file is what the end user will see. Any logic/data that does not directly deal with the view should
have already been called in the logic file. The view file should take that data and put it in a useable form
for the end user. How this is done is upto you, but there's three general ways to approach creating the view:</p>
<ul>
<li>Treat the view as an HTML file, and simply use PHP calls to echo out and populate the view with data. This is not recommended.</li>
<li>Use the "Site Designer" to generate the view. In this case, the view file will contain all PHP, and to edit the view you would edit the database, and not the view file directly.</li>
<li>Manually create the view using AgaresCore 4 classes. Not as difficult as it sounds, and is by far the most powerful way to go.</li>
</ul>
<p>Now since the logic file will have already collected/generated all the information it needs, the task of outputing that
data in a usable form is up to the view. Generally the view deals with CSS, Javascript, and (X)HTML. Of course there is still
view related logic that may be required (for example, foreach loops to iterate through arrays.) However, if you find yourself
writing business logic in this file, you should consider moving the offending code to the logic file in order to code to
standards.
</p>
<h2><a name="structureconfig">The Structure of config.php Files</a></h2>
<p>Each application must have a config.php in the applications root directory. This file will be loaded anytime something
wants specific information about the application in question. This includes each and every time any logic/view is called for
the application, as well as any time the application is listed in a list. The file itself is a simple PHP script that loads
values into several variables. Changing these values has specific effects on how the application is loaded and treated
through out GroundOS. Here is a detailed list of each of the variables that can be set:</p>
<ul>
<li><strong>$displayonmenu</strong> - <i>Boolean</i> - Set this to true to display this application in the App Menu</li>
<li><strong>$applicationname</strong> - <i>String</i> - The actual name of the application. This is what people would type into a URI to each your app. For example, the admin application would have the value of "admin" here.</li>
<li><strong>$applicationicon</strong> - <i>String</i> - Full URI to the icon for the application. Optional, but recommended for applications in the App Menu</li>
<li><strong>$applicationicon16</strong> - <i>String</i> - Full URI to the 16x16 icon for the application. Optional, but recommended for applications in the App Menu</li>
<li><strong>$applicationmenuname</strong> - <i>String</i> - The user friendly name of the application. For example, the admin application's user friendly name is GroundOS.</li>
<li><strong>$applicationversion</strong> - <i>Integer</i> - The version number of the application</li>
<li><strong>$applicationauthor</strong> - <i>String</i> - The author of the application</li>
<li><strong>$applicationurl</strong> - <i>String</i> - URL for the application</li>
<li><strong>$applicationdescription</strong> - <i>String</i> - Description of the application</li>
<li><strong>$applicationlicense</strong> - <i>String</i> - License and/or HTML link to where the license can be viewed. </li>
</ul>
</div>
<div class="paragraph">
<h1><a name="hello1">Manually Creating a "Hello World!" Application</a></h1>
<ul>
<li><a href="#hello1intro">Intro</a></li>
<li><a href="#hello1files">Files to Create</a></li>
<li><a href="#hello1config">Contents of config.php</a></li>
<li><a href="#hello1logic">Contents of the Default Logic File</a></li>
<li><a href="#hello1view">Contents of the Default View File</a></li>
<li><a href="#hello1test">Testing Your Application</a></li>
</ul>
<h2><a name="hello1intro">Intro</a></h2>
<p>
GroundOS provides the Site Designer, which allows you to quickly produce applications. However,
it helps to understand how the system works, and there's no better way to do that then by
writing our own "Hello World!" application from scratch.
</p>
<h2><a name="hello1files">Files to Create</a></h2>
<p>
The first step in creating a new application will be to create the following folders:<br />
<strong>/applications/helloworld1/</strong><br />
<strong>/applications/helloworld1/logic/</strong><br />
<strong>/applications/helloworld1/views/</strong><br />
<br /><br />
And then create the following blank files:<br />
<strong>/applications/helloworld1/config.php</strong><br />
<strong>/applications/helloworld1/logic/index.php</strong><br />
<strong>/applications/helloworld1/views/index.php</strong><br />
For more information regarding the file and folder structure of an application, see <a href="#structure">The Structure of an Application</a>.
</p>
<h2><a name="hello1config">Contents of config.php</a></h2>
<p>
Next, let's edit the contents of config.php. This file configures the application.
This configuration file is loaded before any logic/view is called, each and everyone time. For more information about the config.php file, see
<a href="#structureconfig">The Structure of config.php Files</a>.<br /><br />
Here's the contents of the <strong>/applications/helloworld1/config.php</strong> file:
</p>
<pre>
<?PHP
$displayonmenu = true; // Set this to true to display an icon for this application in the App Menu
$applicationname = 'helloworld1'; // The name of the application
$applicationicon = NULL; // Full path to the icon for the application. Optional, but recommended for applications in the App Menu
$applicationicon16 = NULL; // Full path to the 16x16 icon for the application. Optional, but recommended for applications in the App Menu
$applicationmenuname = 'Hello World!'; // The name of the application for the App Menu
$applicationversion = 1.000; // The version number of the application
$applicationauthor = 'Agares Media'; // The author of the application
$applicationurl = 'https://secure.agaresmedia.com/v6/products/agarescore-4/'; // URL for the application
$applicationdescription = 'A simple hello world application'; // Description of the application
$applicationlicense = "";
?>
</pre>
<h2><a name="hello1logic">Contents of the Default Logic File</a></h2>
<p>
Now that we've got a config.php setup, it's time to edit our logic file. We'll only need a very basic logic
file as the only logic we'll actually be performing is to check to make sure the user has at least level Guest permissions
(this means that they are at least a guest, meaning that bots and banned users would not pass the validation.) Generally,
every application you write should include permissions code, unless you want it to be completely public and accessible, even
to banned users. For more information about logic files, see <a href="#structurelogic">The Structure of Logic Files</a>.
You can learn more about permissions by reading <a href="#users">The User System</a><br /><br />
Here's the contents of the <strong>/applications/helloworld1/logic/index.php</strong> file:
</p>
<pre>
<?PHP
try {
loadclass('user');
$user = new user();
$user->validatecookie();
$permissions = $user->permissions($user->currentuserid);
if($permissions<=997) {
// If the user passes validation, then we'd place any additional logic here. Since we don't need
// any more logic, the next code that will execute is the view file.
} else {
die; // No bots allowed.
}
} catch(Exception $e) {
$this->errorReport($e);
}
?>
</pre>
<h2><a name="hello1view">Contents of the Default View File</a></h2>
<p>
The view file is to display data and information, using CSS, HTML, and Javascript to provide formating, styling, and
options to interact or change the data. In our case, all we want to do is print "Hello World" to the browser screen.
To do that, we'll first load the view class, and make a new $view object. The global variables $headtop_output,
$headbottom_output, and $body_output all prepare content for output. In our case, we don't need to add any CSS
styling, so we'll leave $headtop_output as it is. We also do not need any Javascript, so we will leave $headbottom_output
alone as well. We will however edit $body_output and add the value 'Hello World!' to it. Note that you should always
add to this variables using .= and not just a "$headtop_output = 'value'" since you may be loosing information (such as
debug information) that may be sent from a different source. The output() method of the view() class does the final output
itself, generating W3C compliant web pages. See <a href="#structureviews">The Structure of View Files</a> for more
information on view files.
</p>
<pre>
<?PHP
loadclass('view');
$view = new view();
$headtop_output .= ''; // CSS Goes here:
$headbottom_output .= ''; // Javascript Goes here:
$body_output .= 'Hello World!';
// Finally this code makes everything viewable.
echo $view->output(
'Hello World!', // Set the meta tag title of the page
'hello,world', // Set the meta tag for keywords
'Hello World!', // Set the meta tag for description
'xhtml', // Set the XHTML to UTF-8, Set this to NULL if not using XHTML
'xhtml 1.0 frameset', // Use XHTML 1.0 Transitional
'utf-8', // Set to UTF-8,
$headtop_output, // Load any CSS or other top most content intended for the head tag
$headbottom_output, // Load any Javascript or othercontent intended for the bottom of head tag
NULL, // When this is NULL the body tag reads <body>. To insert custom style of javascript, insert a string into the parameter. For example, a string of this: ' style="border:1px;"' would make the body tag output as <body style="border:1px;">
$body_output // Output the body of the document
);
?>
</pre>
<h2><a name="hello1test">Testing Your Application</a></h2>
<p>
Now to view your creation, simply visit http://www.example.com/helloworld1/ (replace www.example.com with the full URI to your AC4/GroundOS installation.
Note that I am writing this tutorial on an Alpha release, so the outputed code I list here may differ in ways from what you get (debug settings also effect the code output.)
With that disclaimer aside, here's the source I get when I visit the URI of my application:
</p>
<pre>
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Hello World!</title><meta name="keywords" content="hello,world" /><meta name="description" content="Hello World!" /><script type="text/javascript"><!--//--><![CDATA[//><!--
document.domain = "localhost";
//--><!]]></script>
</head><body>Hello World!</body></html><!-- Script Execution Time: 0.0000000422971-->
</pre>
</div>
<div class="paragraph">
<h1><a name="wwb">Windows, Widgets, and Bears, Oh My!</a></h1>
<p>
So what's the difference between Windows, Widgets, and Sub-Windows? Well, first of all, "windows" load their content into
an iframe. This is useful if you want the content of the window to be a complete document, with a full DOM of it's own.
However, since windows use iframes, don't expect the search engines to index your window or any of the content in the iframe.
Widgets, on the otherhand, are simply DIVs that are loaded from content that already exists on the current web page, meaning
that while the search engines will have no problem indexing your content, you will be stuck with the current DOM, and will
not be able to load specific javascript or CSS unique to that widget. Sub-windows are identical to regular windows, except that
when they are opened, they will stay inside whatever window or widget called them. Regular windows are not confined to their
parent windows at all.
</p>
</div>
<div class="paragraph">
<h1><a name="dad">Dialogs, Alerts, and Debugs</a></h1>
<p>
In addition to the window types we've previously discussed, there are also special type of windows that we will discuss here.
</p>
</div>
<div class="paragraph">
<h1><a name="users">The User System</a></h1>
<ul>
<li><a href="#userintro">Intro</a></li>
<li><a href="#userpass">Password Format</a></li>
<li><a href="#usercookies">Login Cookies</a></li>
</ul>
<h2><a name="userintro">Intro</a></h2>
<p>
The users system built into AC4/GOS is very feature packed, but our primary goal in this document is to explain
how user authentication works step by step. This should make it easier for those trying to integrate AC4/GOS with other
CMS systems and user tables.
</p>
<h2><a name="userpass">Password Format</a></h2>
<p>
Passwords can easily be generated by using the generatepass() method of the user class. To understand exactly what goes
into the creation of an AC4 password, we'll need to look at the `user` database. The end result of the generatepass() method
is a md5 hash value that is stored in the `user_password` column. The md5 hash is generated by combining the unique
value of the `user_key` column, with the plain text password (in the example below we'll call it $stringpassword) and finally
with the $globalsalt variable that is set in /settings.php Here's an example:
</p>
<pre>
md5($user_key . $stringpassword . $globalsalt);
</pre>
<h2><a name="usercookies">Login Cookies</a></h2>
<p>
Three cookies are used for validation, "ac4login", which contains the users hashed password, the user's unique
personal hash (in the database it is user > user_key) as well as the current session ID, all of these values are
hashed again, and then serialized. Check out the setcookie() method of the user class to see the code in action.
The second cookie is "ac4uid" and simply contains an integer with the users primary key. Both cookies must be
present for the login to work. The "ac4login" cookies value is created in this manner, where $user_password is the
`user_password` column from the `user` database:
</p>
<pre>
serialize(md5($user_password . session_id()));
</pre>
<p>
When a user logs in and clicks the "Remember Me" checkbox, a 3rd cookie is set: "ac4perm" This cookie allows the user
to visit the site from the same IP address and browser without having to log in. However, if their IP address changes
then they will have to log in again. When using the "ac4perm" cookie, the "ac4login" cookie is not required, although
the "ac4uid" must still be present. The value of the "ac4perm" cookie is created completely from values from the `user`
table, specifically from these three columns per user: user_key, user_remember_key, and user_last_ip
</p>
<pre>
md5($user_key . $user_remember_key . $user_last_ip);
</pre>
<h2><a name="userpermissions">User Permissions</a></h2>
<p>
Each user can have only one global permission level (this is a integer value between 1 and 999, with 1 being the highest permissions, and
999 being the lowest level permissions.) By default, there are only 6 pre-defined global permissions, outlined in the table below:
</p>
<center>
<table>
<tr><td><strong>Level</strong></td><td><strong>Name</strong></td><td><strong>Description</strong></td></tr>
<tr><td>1</td><td>Administrator</td><td>Full site access and admin abilities</td></tr>
<tr><td>2</td><td>Moderator</td><td>Full site access and limited admin abilities</td></tr>
<tr><td>500</td><td>Regular User</td><td>End user site access</td></tr>
<tr><td>997</td><td>Guest</td><td>Guest</td></tr>
<tr><td>998</td><td>Bot</td><td>Bot access</td></tr>
<tr><td>999</td><td>Banned</td><td>No access</td></tr>
</table>
</center>
<p>
Since there are only 6 pre-defined levels, the other 993 values are available for custom permissions. However, it should be
noted that values lower than 500 should only be assigned to registered users, while values greating then 500 should only be
used for non-registered users.
</p>
<p>
Now remember, these are "global permissions" where the authority level is
</p>
</div>
<div class="paragraph">
<h1><a name="topics">How to Use Topics</a></h1>
<p>
The table `topics`
</p>
</div>
<div class="paragraph">
<h1><a name="input">Handling Input</a></h1>
<p>
There are three types of input that any web page will have to deal with:
</p>
<ol>
<li>URI Request</li>
<li>Form Data</li>
<li>Mouse Clicks</li>
</ol>
<img src="./data/jpg/help_input.jpg" alt="" />
<p>
URI requests are simply requests for a specific file on the web server. Each and every request is sent through the process() method
of the router() class. This means that you should not particularly have to concern yourself with custom handling of URI request, except
when the application you're writing needs to return $_GET values (as in, data that is sent as part of the URL.) In this case, you will
find that each value passed through the URI is contained in the global variable $commandArray[] However, unlike traditional web pages,
you will not pass GET commands in this manner: <strong>http://www.example.com/index.php?variablename=variablevalue</strong><br />
Instead, you seperate each value by a backslash, so /x/y/z/ would be 3 seperate GET values. Using the same example we would would have this URI:<br />
<strong>http://www.example.com/variablevalue/</strong> or another example: <strong>http://www.example.com/x/y/z/</strong> However, this again would be incorrect, because the first value ($commandArray[0]) is
reserved for an application. So lets reexamine this scenario again, except let's say we're using an app we've titled testapp. So now are
URI would like <strong>http://www.example.com/testapp/variablevalue/</strong> To use this information, in our logic file we would find
our apps name in $commandArray[0] and the string "variablevalue" in $commandArray[1]. A final thing to remember is that additional logic/view
files are accessed through $commandArray[1]. For example, if we want to access the appmenu, which is a part of the admin application, we would
do that with this URI: <strong>http://www.example.com/admin/appmenu/</strong> That means if we wanted to use any GET data, we would start from
$commandArray[2]
</p>
</div>
<div class="paragraph">
<h1><a name="debug">Debug and Error Reporting</a></h1>
<p>
There's nothing more frustrating then taking time from your project to build a set of helpful debugging and error diagnostic
tools. Fortunately AC4/GroundOS provides a robust and integrated PHP/Javascript debugging engine. You can open the
debug console from the App Menu > then clicking on the "Debug" button. You can also open the debug console from the Site Designer
from Debug > Open Debug Console.
</p>
<p>
To use the debugger, you must have the global $debug variable set to true. This variable is first defined in <strong>/settings.php</strong>
The actual debug() method is part of the rootclass() class, and therefore can be called using <strong>$this->debug("Debug message here");</strong>
in any class that decends from rootclass. Here's an example of calling the debug() method from a $view object:
</p>
<pre>
$view->debug("Testing the debug console");
</pre>
<p>
If you have debugging disabled, but want to use the debugger for something quickly, you can always do something like this:
</p>
<pre>
$debug = true; // Re-enable the debugger.
$view->debug("Testing the debug console");
$debug = false; // Disable it again.
</pre>
<p>
If you need to use pure Javascript, you can access the debugger using this syntax:
</p>
<pre>
top.debug("Testing the debug console");
</pre>
<p>
Note that any debugging calls done in Javascript will be outputed regardless of the status of the $debug global variable.
</p>
</div>
<div class="paragraph">
<h1><a name="sitedesigner">Site Designer</a></h1>
<ul>
<li><a href="#sitedesignerview">Contents of a Default Site Designer View File</a></li>
</ul>
<p>
The Site Designer allows you to quickly create dynamic Ajax applications by simply pointing, clicking, dragging and dropping.
Applications created with the Site Designer are mainly composed of database entries, and use the sitedesigner() class and it's
methods to save/read the site design from the database. However, keep in mind that the Site Designer does allow you to
use vitually any application within your new application.
</p>
<p>
The Site Designer uses 4 MySQL tables to store all it's information:
</p>
<ol>
<li>div - Stores DIV content and information</li>
<li>css - Stores CSS content</li>
<li>windows - Stores window/widget content and information</li>
<li>sitedesigner - Stores information regarding applications and views</li>
</ol>
<h2><a name="sitedesignerview">Contents of a Default Site Designer View File</a></h2>
<p>
When you create a new Site Designer application, it will create a both a default logic and view file for you. Let's take a look at the default
code for the view file:
</p>
<pre>
<?php
loadclass('sitedesigner');
$sitedesigner = new sitedesigner();
$sitedesigner->loadwindows('sitedesigner', 'test');
echo $sitedesigner->sdoutput('sitedesigner', 'test');
?>
</pre>
<p>
The view file can be manually edited to your hearts content. However, you should not remove any of the lines of code, and it is recommended
that any editing you do be placed directly after the <strong>$sitedesigner = new sitedesigner();</strong> line. Since the sitedesigner() class
extends the view() class, there is no need to make a new view() object.
</p>
</div>
<div class="paragraph">
<h1><a name="devfaq">Developer's FAQ (Frequently Asked Questions)</a></h1>
<p>
<strong>Q. Why do we need GroundOS when we can just setup a LAMP server and make our own cloud?</strong><br />
A. GroundOS is intended to run on top of a LAMP stack, and is meant to provide a common environment for web applications and
cloud development. Of course if you're a do-it-yourself type of programmer, there's nothing stopping you from creating
your own cloud from scratch. However, one of the goals of this project was to provide a blank canvas for web application and
cloud development, with a tool set and framework specifically targetted towards cloud construction. The question you need to
ask yourself is whether you should reinvent the wheel by doing the extra work to create your own cloud system from scratch, or
use and modify GroundOS to suit your needs instead.
</p>
<p>
<strong>Q. What seperates GroundOS from all the other web based OS'?</strong><br />
A. GroundOS is the only web based OS that:
</p>
<ul>
<li>Is designed to create websites</li>
<li>Is designed to run locally or remotely</li>
<li>Is designed to be a personal or business cloud</li>
<li>Is fully open source</li>
<li>Includes a full open source PHP/Ajax web application development framework</li>
<li>Works with thousands of existing PHP scripts</li>
<li>Provides an easy software repository to download and install new applications (and upload your own creations)</li>
</ul>
<p>
<strong>Q. Can I run GroundOS on a Windows machine?</strong><br />
A. Yes. GroundOS works fine on Apache under Windows. IIS has not been tested and is not officially supported at this time. GroundOS
requires mod rewrite and .htaccess support to be enabled, so at the very least IIS users will need to install a plugin to enable .htaccess
support.
</p>
<p>
<strong>Q. Is this project simply another PHP copycat of Ruby on Rails?</strong><br />
A. AgaresCore 4 is similiar to Ruby on Rails in that both are open source web application frameworks that are ideal for Agile software
development. However, AC4/GroundOS is intended to not only provide an open source web application framework, but also an end user
environment from which to run the web applications themselves. It further seeks to empower developers by giving them a mobile
IDE from which they can collobrate with other developers to fully execute Agile development methodology.
</p>
<p>
<strong>Q. Why is the code written for PHP 5 only?</strong><br />
A. PHP 4 is so old at this point, that it is no longer supported at all. There will be no updates for PHP 4 to patch anything, which means
any bugs, security holes, or other issues with PHP 4 will never get patched. PHP 5 itself was first released in July of 2004, so it's quite
a stable and mature PHP version, and it has a lot of advantages and improvements over PHP 4. However, not all of the new PHP 5 features are
backwards compatible with PHP 4. For these reasons, we targeted PHP 5 as our language.
</p>
<p>
<strong>Q. Will you ever release a PHP 4 version of GroundOS?</strong><br />
A. AC4/GroundOS was written in PHP 5 exclusively. If someone wants to do the work to backport the code (basically strip out all the PHP 5
code) they can create a PHP 4 fork. However, there will never be official PHP 4 support or releases for GroundOS.
</p>
<p>
<strong>Q. Can I run GroundOS on my home computing, and access it anywhere through the internet?</strong><br />
A. The simple answer to the question is yes. You need to install a web server, along with PHP and MySQL. Typically web servers are installed
to either port 80 or 8080. Because of that, you'll need to make sure that your firewall and/or router allows traffic to pass through the port
your web server is setup on. Additionally, you should be aware that installing a web server and exposing those ports will allow anyone to
connect to your machine. GroundOS provides authentication (username/password protection) but not all files can be protected from unauthorized
access with GroundOS alone. If you want your setup to only be accessible to you, then you should enable Apache's password protection for the entire
www folder.
</p>
</div>
</body>
</html>