Difference between revisions of "Slib"

From ProgClub
Jump to: navigation, search
(→‎Misc: Adding HTTP Headers Reference...)
(Updating functional specification...)
Line 96: Line 96:
 
   
 
   
 
  $this->assertSame( "https://www.progclub.org/wiki/Main_Page//test", strval( $uri ) );
 
  $this->assertSame( "https://www.progclub.org/wiki/Main_Page//test", strval( $uri ) );
 +
 +
=== Asset management ===
 +
 +
There is a [https://www.progclub.org/pcrepo/slib/trunk/src/class/SlibResourceManager.php?view=markup ResourceManager] and a [https://www.progclub.org/pcrepo/slib/trunk/bin/compile.php?view=markup compiler]. The compiler bundles CSS and JavaScript, the ResourceManager handles requests for assets. Note: the compiler automatically generates .gz files for all assets so the ResourceManager can return them.
 +
 +
=== Database schema management ===
 +
 +
There is a [https://www.progclub.org/pcrepo/slib/trunk/src/db/SlibDatabaseUpgrader.php?view=markup DatabaseUpgrader] that handles database schema migrations. There was some talk of factoring the SQL out into .sql files, but I think this format is easier to maintain/reference as all the table definitions are right there in the source.
 +
 +
=== A new approach to dependency injection ===
 +
 +
The slib framework has a new approach to dependency injection. If you want to provide a mock/instrumented instance of any of the framework classes all you have to do is define the ClassName that you want to inherit from the SlibClassName. Your ClassName file will automatically be instantiated by the factory method that Creates/Loads your implementation. The way this works is that slib registers a [https://www.progclub.org/pcrepo/slib/trunk/src/mock-loader.php?view=markup mock-loader] that will generate a concrete type if no concrete type is defined.
  
 
=== Misc ===
 
=== Misc ===
  
* Managed cached gzipped resources, e.g. bundle.js to /var/tmp/12/12..34/bundle.js.gz
 
** Hash is MD5 of APPCODE . '-' . {SLIB,MY}VERSION . '-' . 'res/path/to/file.js'
 
** APPCODE is e.g. 'pdb', 'slib', 'my-app', etc.
 
** Don't forget to set Content-Encoding: gzip and maybe Content-Length: xxx? See [http://msdn.microsoft.com/en-us/library/aa287673%28v=vs.71%29.aspx HTTP Headers Reference]
 
* replace asset URLs and load all CSS in one bundle
 
* /var/tmp/bundle-SHA1-file-names-hash.{js,css} cache resource bundles
 
* partition load order and default partition in settings
 
* SQL files in /etc/slibdb/12345-table-name.sql
 
* database upgrader to use SQL files one at a time from /etc/slibdb/*.sql
 
* database versions: global() and partition( $id )
 
* generate and auto-load mocks in /var/tmp
 
* user creation includes user's partition being created
 
 
* database interface, Database inherits SlibDatabase (sorting/pagination/filtering support)
 
* database interface, Database inherits SlibDatabase (sorting/pagination/filtering support)
 
** db()
 
** db()
Line 170: Line 170:
 
** same schema in all databases
 
** same schema in all databases
 
* create partition_* databases, one for each partition
 
* create partition_* databases, one for each partition
 +
* partition load order and default partition in settings
 +
* database versions: global() and partition( $id )
 +
* user creation includes user's partition being created
  
 
== Technical specification ==
 
== Technical specification ==

Revision as of 18:28, 14 May 2014

Slib is the ProgClub PHP framework software. That's the software that provides a framework for your PHP applications. For other projects see projects.

Project status

Under way. Not released yet, there's stuff TODO.

Contributors

Members who have contributed to this project. Newest on top.

All contributors have agreed to the terms of the Contributor License Agreement. This excludes any upstream contributors who tend to have different administrative frameworks.

Copyright

Copyright 2011, Contributors. Licensed under APACHE 2.0.

Source code

The repository can be browsed online:

https://www.progclub.org/pcrepo/slib/trunk

The code for slib is publicly available from svn:

https://www.progclub.org/svn/pcrepo/slib/tags/latest

Or privately available for read-write access:

https://www.progclub.org/svn/pcrepo/slib/trunk

Links

No links at this time.

Functional specification

The software provides a web-framework/toolkit for PHP applications.

URI/URL management

The SlibUri class and its associates provide an interface for reading and manipulating URIs. The following diagram illustrates the six types of URI supported and the component pieces:

SlibUriHierarchy-1.png

The software has been specifically designed to cater to specialised URI handling, such as seen with SlibMailtoUri which extends SlibUri with 'mailto' specific API such as get_mail_user(), get_mail_domain(), get_mail_subject(), etc., etc. At this time the only specialised URI is for mailto links, all other schemes are handled with URI types 1 to 5, most of them being a 4.

For a list of all documented URI schemes see URI scheme at Wikipedia. There is a code generator which generates the strong-typed URIs based on documented schemes. The idea is that the design caters for URIs to be scheme specific, but the design doesn't need to be done immediately. Presently the only real URI support is for schemes: http, https, file and mailto, the rest are generic for the time being.

Note: because of the decision to use 'strong-typed' classes on the API it is possible to do something odd. For example I could create a SlibHttpUri using ::Parse(...) and then on that URI change the scheme to 'mailto', I will then have a SlibHttpUri that reports its scheme as 'mailto', not 'http'. It's not a great design, but hey, it works if you don't push it and importantly: it's done!

Here's an example of using SlibUri for getting URL components:

$uri = SlibUri::Parse( "https://www.progclub.org/wiki/Main_Page", '/wiki' );
$this->assertSame( 'https', $uri->get_scheme() );
$this->assertSame( 'www.progclub.org', $uri->get_host()->to_string() );
$this->assertSame( '/wiki', $uri->get_base() );
$this->assertSame( '/Main_Page', $uri->get_path()->to_string();

$uri = SlibUri::Parse( "mailto:jj5@progclub.org?subject=test" );

$this->assertSame( 'jj5', $uri->get_mail_user() );
$this->assertSame( 'progclub.org', $uri->get_mail_domain()->to_string() );
$this->assertSame( 'test', $uri->get_mail_subject() );

$uri = SlibUri::Parse( "https://www.progclub.org/pcwiki/index.php?title=Main_Page&action=edit" );

$this->assertSame( '/pcwiki/index.php', $uri->get_path()->to_string() );
$this->assertSame( 'pcwiki', $uri->get( 1 ) );
$this->assertSame( 'index.php', $uri->get( 2 ) );
$this->assertSame( 'index.php', $uri->get_filename() );
$this->assertSame( 'php', $uri->get_extension() );
$this->assertSame( 'Main_Page', $uri->get( 'title' ) );
$this->assertSame( 'edit', $uri->get( 'action' ) );

And here's an example of using SlibUri to build URLs:

$uri = SlibUri::Parse( "https://www.progclub.org/wiki/Main_Page", '/wiki' );

$uri = $uri->to_builder();

$uri->set( 'q', 'testing' );

$this->assertSame( "https://www.progclub.org/wiki/Main_Page?q=testing", strval( $uri ) );

$uri->set( 'a', array( 1, 2, 3 ) );

$this->assertSame( "https://www.progclub.org/wiki/Main_Page?q=testing&a=1&a=2&a=3", strval( $uri ) );

$uri->clear( 'q' );
$uri->clear( 'a' );

// set the 4th path part:
$uri->set( 4, 'test' );

$this->assertSame( "https://www.progclub.org/wiki/Main_Page//test", strval( $uri ) );

Asset management

There is a ResourceManager and a compiler. The compiler bundles CSS and JavaScript, the ResourceManager handles requests for assets. Note: the compiler automatically generates .gz files for all assets so the ResourceManager can return them.

Database schema management

There is a DatabaseUpgrader that handles database schema migrations. There was some talk of factoring the SQL out into .sql files, but I think this format is easier to maintain/reference as all the table definitions are right there in the source.

A new approach to dependency injection

The slib framework has a new approach to dependency injection. If you want to provide a mock/instrumented instance of any of the framework classes all you have to do is define the ClassName that you want to inherit from the SlibClassName. Your ClassName file will automatically be instantiated by the factory method that Creates/Loads your implementation. The way this works is that slib registers a mock-loader that will generate a concrete type if no concrete type is defined.

Misc

  • database interface, Database inherits SlibDatabase (sorting/pagination/filtering support)
    • db()
    • DataSort
    • DataPage
    • DataQuery
    • DatabaseSchema inherits SlibDatabaseSchema
  • database upgrade DatabaseUpgrade inherits SlibDatabaseUpgrade
    • dbu()
  • settings management (session, user, global)
    • sm()->settings
    • SettingsManager inherits SlibSettingsManager
    • Setting inherits SlibSetting
    • GlobalSettings, UserSettings, SessionSettings inherits SlibSettings
  • session management (login, settings/state)
    • sm()
    • SessionManager inherits SlibSessionManager
  • auth management
    • auth()->can_edit_post( $sm )
  • user/group management (auth, permissions)
    • sm()->user and user->groups
    • User inherits SlibUser
    • Group inherits SlibGroup
  • resource management (graphics, style, scripts, caching)
    • rm()
  • graphics management (database, scale, cache)
    • gm()
  • file management (database, upload, cache)
    • fm()
  • form management (validation, submission(POST)/query(GET))
    • form()
    • Submission inherits SlibSubmission
    • Query inherits SlibQuery
    • Validator inherits SlibValidator
  • content management (news, book, page)
    • cm()
    • Article (News) inherits SlibArticle (date, title, description, html)
    • Book inherits SlibBook
    • Chapter inherits SlibChapter
    • Page inherits SlibPage
  • translation facilities for content and services
    • tm()
  • access logging (all HTTP activity)
    • log()
  • error logging (write failed logins to error log, pick up with fail2ban)
    • log()->error()
  • request management (HTTP input/output)
    • req()
    • redirection support: req()->goto( $url )
    • cookie support: req()->cookie( $name, $etc )
    • HTTP headers support: req()->header( ... )
  • Category (for content, graphics, files)
  • Tag (for content, graphics, files)
  • Feed provider
    • feed()
  • sharding:
    • main_db, partition_*_db
    • log_db(), db( $partition_id )
    • same schema in all databases
  • create partition_* databases, one for each partition
  • partition load order and default partition in settings
  • database versions: global() and partition( $id )
  • user creation includes user's partition being created

Technical specification

TODO.

TODO

Things to do, in rough order of priority:

  • Create the project in svn
  • Document functional specification
  • Document technical specification
  • Copy in existing code

Done

Stuff that's done. Latest stuff on top.

  • JE 2011-12-08: created project page

Notes for implementers

If you are interested in incorporating ProgClub slib into your project, here's what you need to know:

You probably want to setup an svn:externals from your svn repository to the public release tag:

http://www.progclub.org/svnro/pcrepo/slib/tags/latest

That way you'll get changes to the framework as they're released.