Skip to content
Jay Williams edited this page Mar 7, 2012 · 2 revisions

Ultralite Proposal

Goals

Ultralite 2, codename for Pixelpost 2.0, need a new start. It needs to use the latest technologies to take advantage of the best of the web and keep a KISS (keep it simple) spirit.

Utlralite 2 need to run fast. It should be minimalist and mostly modular (extendable by plugin) and easy for the end user.

Today, it is important to keep in mind that the web is not only about a single website. The web is all about bringing technologies together, and sharing information, and Ultralite 2 should respect this way of life. Indeed Ultralite 2 should be completely controllable by an API and adopt open technologies such as JSON, XML-RPC, RSS, etc... Utltralite 2 needs to be "mobile ready" and offer an adaptive interface to mobile devices and screens both small and large.

Finally, in the respect of the user, Ultralite 2 should be as accessible as possible, a standard for a great user experience.

Thank you.

Index

Application Programming Interface

The API should be accessible in multiple formats, such as JSON and XML (or XML-RPC). This should be discussed. All API action (listed below) need a specific page with its full description (query format, query response, error code, arguments, etc.)

Authentication API

The goal of the Authentication API is to expose full access to the content. Full access doesn't mean public access, so the authentication service is the first part of this API. Authentication in a challenge/response method removes the need for the client to send the password in clear text over the internet.

A challenge is sent to the user and if the client has the correct secret key (password), it can successfully reply. If the reply is good, the API will send a token (an identifier key, similar to a cookie) which will authorize the client to exchange with the rest of the API.

Tokens are limited in time and need to be refresh if the user need more time to communicate with the API.

auth.request		// Client requesting a new auth challenge
			        // Client must identify itself, and specify the
			        // permission level (read | write | delete).

auth.getToken		// Authenticate the client by replying to the
		            // challenge and sending a token.

auth.checkToken		// Checks of the token is still valid,
                    // and return a new token if applicable.

auth.refresh		// (Not needed?)

Comment by Jay: Should we consider a simple username/password approach initially?

Comment by Alban: By writing permission level I think you want to be closer with other API, permission access is not authentication. Auth by Token is very simple to implements and totally transparent for poeple want to deal with the API. But beside the auth there is an account. Just a login/password couple for one user. (perhaps I say that because I have work very often with banque API).

So identify user is one thing. After if you want to provide access to other entity which doesn't have an account system. That's need create key pair (like flickr etc...). That's other thing.

In third this entity that have an access with key pair etc... you can restrict them, by right. you can adopte the CRUD (create/read/update/delete) idea, other exists. That's again another thing.

I didn't known Tumblr API but I known Flickr API, by dealing with it for my plugins. Takes me a lot of hours to really understand how it's work. In facts the API is quite confusing on this subjet. She shuffle Trusted access/untrusted access/privileges... in the same part/method. Are you sure that's you want ?

If you prefer username/password auth, there is no problem for me. I rather the token because the admin account password is not sent in clair text throw the web. (but all people send their password like that many and many time all the day).

Photo API

A fully featured Photo API. Needs to be complete with new features...

photo.add				// add a new photo.
photo.list				// list all photos. (photo.search?)
photo.delete			// delete a photo.
photo.getInfo			// retrieve all informations about a photo.
// photo.getTitle			// retrieve the photo title.
// photo.getDescription		// retrieve the photo description.
// photo.getDates			// retrieve the photo posted & taken dates
// photo.getState			// retrieve the photo state
							// (published|draft|publish-on)
photo.getExif			// Retrieve photo EXIF/XMP/GPS data
// photo.setInfo			// change the photo info?
photo.setMeta			// change the photo title & description
photo.setDates			// change the photo posted & taken date.
photo.setState			// change the photo visibility.

Comment by Jay: We should inspect closely the Flickr & Tumblr APIs. I'd suggest starting with just the bare essentials at first. And slowly add more API methods as we progress. I'm also trying to keep in mind the whole RESTful aspect. I seriously doubt it's efficient to issue individual HTTP calls to set only a title or description. But then again, I may be wrong.

Comment by Seza: Sure, in facts when i write this models i have flickr API documentation on my eye. Personally I prefer my version of the set/get for one reason. Take for example the setMeta you propose. 2 different data for one set method that's a bad idea. How did you explain to the final user you have to provide 2 data for setting one of them. They are certainly most of people just want set the title or description but not both at the same time (think ajax edit like in flickr page). Perhaps you think, the two data are not mandatory. Leave empty the other data you want set ? and if I want reset the field ? Have a default value to say don't care of it ? Have a new field attachment to other that say what is set and what is not ? Very complicated don't you think ?

I you want we make a RESTful API, we can. But that's not what is write above. For me RESTful is like that: You have one method, let's say 'api.photo'. If you call it with HTTP GET method, you'll retrieve the photo. Call the same method but in HTTP PUT, you'll send a photo this time. For me that is REST. What's your point of view ?

If you are afraid about performance ? This is similar than the ajax history. Lot of little call / versus less big calls. Think how many Mega octet you loose by pushing all the photo description in the mysql buffer, looping on it, escape it for a user that's just want list photo by title.

In fact, this is why I include in my version, a single set/get (keep the CRUD aspect) a complete set/get. The developer can choose the method feet its needs.

I want to add a last thing, if we open the API (by plugins i think), we could'nt control entierly, just the base. (And perharps provide a model of development).

PS: please, don't be care to the "ton". When I read what's I wrote (i wrote too much) I think that's direct, awful, brutal. I haven't so much vocabulary to explain clearly my point of view with the right manner to say.


Jay has commented up to this point.


ALBUM

provide a photo album gesture, need to be completed with new feature...

album.add               // add a photo album.
album.list              // list all photo albums.
album.del               // delete a photo album.
album.get               // get all informations about an album.
album.getTitle          // retrieve the photo album title.
album.getDescription    // retrieve the photo album description.
album.getVisibility     // retrieve the photo album visibility.
album.setTitle          // change the photo album title.
album.setDescription    // change the photo album description.
album.setVisibility     // change the photo album visibility.
album.photo.link        // add a photo to a photo album.
album.photo.unlink      // remove a photo to a photo album.
album.photo.list        // list all photo in a photo album.

ACTIVITY

provide information about recent activity on the data...

activity.photo.added    // return the last photo added.
activity.photo.updated  // return the last photo updated.
activity.album.updated  // return the last photo album updated (new photo in).

REQUIREMENTS

Ultralite 2

PHP 5.3

PHP 5.3 becomes the new way of web application, it is better than its previous version by running faster and big innovation in the language. In term of popularity PHP is the main used language for web application and the 5.3 version is quite used today and obviously more and more tomorow. PHP 5.3 have an interisting support of Sqlite 3, a better version than Sqlite 2 and utlralite 2 certainly need of this support.

PHP GD 2 LIBRARY

This is not a surprise for an web application working on photo require an support of file format used by photography. GD2 offer all the possibility needed by Ultralite 2.

APACHE MOD_REWRITE

Clearly today it is important to offer to the end user nice URL, also important, nice URLs offer improvment in website SEO (Search Engine Optimization) which is a common feature required by the user.

CODING STANDARDS

PHP

  • Add PHPDoc formatted comments to all functions, methods, constants, etc...
  • Functions and methods names should be all lowercase and use underscores _ to separate words my_public_method()
  • Curly brackets should be placed on the line below the statement, not on the same line
  • Code should be properly indented using tabs not spaces
  • Add a space after all if, while, and for statements
  • Add a space after function parameters my_function($param1, $param2)
  • Files will be saved in UTF-8 format using *NIX style linefeeds \n not the Windows style \r\n
  • No shorthand PHP tags. e.g. <? ?>
  • Constants should be all caps with underscores separating words. MY_CONSTANT
  • No closing PHP tag ?> at the end of PHP documents
  • Private & Protected methods should have an underscore prefix _my_private_method()
  • Use single quotes for strings, only use double quotes when necessary

HTML

  • *NIX formated (UTF-8, \n)
  • Well indented with tabulations not spaces
  • Lowercase tag, lowercase attribute, with double quote <a href="#">link</a>
  • No empty attribute
  • In cas of long long tag add a linefeed before a new attribute.

SQL

  • SQL keyword are uppercased (SELECT, UPDATE, WHERE, ...).
  • Database, table, field are lowercased and with ` quotes.
  • All query are finished by a semicolon ;.

CORE ARCHITECTURE

BASICS SERVICES

All service should follow an PHP Interface, we certainly design interface before code thoses classes.

Filter  // provide data management (check_utf8, remove_accent, assume_int, ...)
Db      // provide database management (connect, query, exec, fetch_column, ...)
Cache   // provide cache management (save, load, settimelimit, ...)
Conf    // provide configuration management (get, set, save, ...)
Service // provide service management (in fact service could not be a service himself)
Event   // provide event management (replacement for hooks system)
Router  // provide url manager (get_template_dir, get_plugins_dir, get_controller, ...)
User    // provide user management (credentials, prefs, info, ...) (needed ?)
Lang    // provide translation management.

BASICS CLASSES COULD BE INCLUDED AS HELPER

Error   // error gesture ?
Auth    // authentication protocole (think to credential API)
Curl    // do we need connection ? (autoupdate, direct install plugins via its url)
Loader  // do we really need autoload, i think not (indeed less flexibility)
Request // parsing request (think url rewriting, get all subfolder/params...)

OTHER EXTRA CLASSES WE SHOULD THINK TO INCLUDED STYLE HELPER

Json
Sqlite
Mysql
Xml-rpc
Rss
Paginate
Email
Date

HOW ITS WORK

The more complex design, the bootstraping (big need to be discussed):

  1. Establish the minimum common environnement, constant, error recovery etc...
  2. load the service and event classes.
  3. load all plugins (who register services, events, check requirements for min/max version, other plugins version...).
  4. load other services.
  5. check credentials (if needed).
  6. register plugins signals.
  7. process page.

Processing the page, the other big thing.

Perhaps its good idea to provide all feature by plugins. (photo, albums, comment, exif, tags, photo rating). This can be a good pratices to see if the core is solid, fast, test plugins system, this could make the modularity very hight, very manageable.

And i thinking too to call (find) the page processer by throw an event/signal too. This become really easy to add page, API methods.

Actually and I did'nt find a cool way to handle template. If we follow the plugins concept, plugins can provide API methods, front or back page or just add some content in an existing page. And finally, a theme is also a plugins. Themes can just provide a css stylesheet or provide new html page... That's a complex thing to deal with that.

Actually, web page go more and more to semantics content and and theme is always more going to CSS. Is there a good idea to restrict themes to a stylesheet, all is possible, just see csszengarden website.

Certainly, we must let theme add some JS file for interactive content. This idea push me more in the way that a theme is just a plugins (that can provide a little part of a web page). How ? Why not reuse again the idea of Signal/Event ? In fact calling a plugins feature or calling a plugin content should be make by the same way.

I have just two bad feeling about that idea:

  • This can become a sapghetti calling. Who calls who ? This can be handle by a proper documentation.
  • Handle multiple response of a single call. Yes one or more plugins can use the same event. How to deal with that, how to deal with the order they called. Certainly we must provides some rules about that or good practices about that.

Finally all of me actually focused on signal/event. The good thing is we just need to write one class to handle all of our problem. This can be a powerful feature and very fast for php (less classe to load etc...). The revert of the medals is it can be hard to deals with multiple calls for same event and need an explanation to plugins developper to this concept by provide a good documentation. Multiple calls can become a kill power by making a call = one loop. So more calls = more loops. We just need not open to much doors that is needed.

Activation/unactivation of a plugins/theme need a reflexion too. Perhaps move actived plugins into a folder, and inactive into another one. Activation could meend installation too (bdd stuff, etc...).

FILE ARCHITECTURE

web_root_folder
|
|__ .htaccess          // url rewrite (need to be created on the fly)
|__ htaccess_sample    // same as above (provided for manual install)
|__ config.json        // the configuration file (json ?) (need to be created on th fly)
|__ config_sample.json // same as above (provided for manual install)
|__ README.txt
|__ README.html
|__ db.sqlite3         // the ultralite 2 database
|__ index.php          // the boostrap FRONT
|__ photos/
|   |__ originals/     // the originals photo (like they posted)
|   |__ resized/       // the resized photo (like the user want to see them)
|__ cache/             // the cache folder (need to be writable)
|__ core/              // contains the 'core' classes
|__ plugins/           // the plugins folder

TEMPLATE ARCHITECTURE

PLUGIN ARCHITECTURE

INSTALLATION PROCESS

AUTOUPDATE PROCESS

URL FORMATING

VERSION NUMBER

Exemple of a version number : version A.B.C

C is for minor update, bug fixes, never BC break in minor version. B is for important updated, reserved to BC break. A is the main stream version. Update it is synonyms of big change in the developpement way/spirit.

TODO LIST

  • Little tweak about the layout, move all the application in a folder called app except private folder, index.php, php.ini, htaccess, config.json (permit a simple copy of app folder to manual update the application)
  • Move all content of index.php in a start.php file int app folder, index.php need juste to include it. (permit to change the basic setting etc... in update)
  • Move config.json to private folder
  • Rename config.json in config_sample.json (can add config.json to .gitingore and use it for test purpose)
  • Add .htaccess to .gitingore for test purpose (can use it for test purpose)
  • Remove file php.ini if still empty in future
  • Create an install / update script.

« index

Clone this wiki locally