Version 4, last updated by copesc at 25 Feb 00:34 UTC

WARNING: List of changes updated on 10/11/2010. Changes made after that date are not listed.

Those changes are already been merged into trunk.

Important changes for client code in a nutshell:

- The component folder structure has changed

- All folder names now need to be plural

- Controller actions are now being passed the full KCommandContext object, instead of only the data. In your own code you will only need to make sure your controller _actionX function accept a KCommandContext object instead of the raw $data. To get the actual data all you need to do is change your implementation to $data = KConfig::toData($context->data);

- getX functions no longer return identifiers but do return object instances. For example: KController::getView now returns an object instance, so you no longer need to do KFactory::get($this->getView()). Same for getTable, getModel, getTemplate, getController, getRow, getRowset, etc.

- In the component dispatcher you no longer need to do:
KFactory::get('app::com.foo.dispatcher)->dispatch(KRequest::get('get.view', 'cmd', default));
Instead you should do:
echo KFactory::get('app::com.foo.dispatcher)->dispatch();
(notice the echo)

- The Template Date Helper offset is automatically set by Koowa based on Joomla config

- From a tmpl file you can access the view methods using $this->getView()->methodName() instead of $this->methodName()

Full list of changes

 

## MOVING TO STANDALONE


I removed the KDecorator package and more specifically the KDecoratorJoomlaApplication class. This is a first change towards full decoupling Nooku Framework fully from Joomla.

## DATA VALIDATION


Added a new getStatusMessage and setStatusMessage to KDatabaseRowAbstract. Also added a new STATUS_FAILED const. These changes allow you to implement basic validation into your row save and delete methods.
If the status is set to failed the getStatusMessage can be used to retrieve information about why it failed.

Improved ComDefaultControllerDefault::setMessage() function to take the row(set) status into account. If the status is STATUS_FAILED we use the status message information to generate an appropriate redirect message and set the redirect to the referrer. Otherwise, we generate the message based on the action and identifier name.

You can use this as a simple validation mechanism. In your own row object you could do something like :

class ComFooRowFoo extends KDatabaseRowAbstract
{
    public function save()
    {
        $result = false;
        // Validate received data.       
        if(trim($this->name) == '')
        {
            $this->_status = self::STATUS_FAILED;
            $this->_status_message  = JText::_('Please enter a name!');
        }
        if($this->_status !=  KDatabase::STATUS_FAILED)
        {
            $result = parent::save();
        }
        return $result;
    }
}


This is a first step in providing a simple validation mechanism as discussed here
http://groups.google.com/group/nooku-framework/browse_thread/thread/24c55c9b66866755#
http://www.assembla.com/wiki/show/nooku-framework/Server-side_input_validation


## PAGINATION


Removed paginator helperlimit box dependence on javascript redirects. You will need to wrap the limit box into a form element for it to work. See also changes in com_profiles.

Make a number of changes to com_default to improve compatibility of the pagination rendering with Joomla

- Translate 'offset' to 'limitstart'  in ComDefaultHelperPaginator::_link() and ComDefaultControllerDefault::setRequest() functions to be 100%
compatible with Joomla's URL rendering. This will make sure Nooku driven extensions are fully compatible with existing SEF solutions.
See also : http://www.assembla.com/code/nooku-framework/subversion/changesets/2530

- Always use setRequest in the constructor. This allows to easily override the request data during controller construction.

- Set limit and offset to null by default in KModelTable and added extra checks to KDatabaseQuery::limit function to make sure limit and offset have a valid value when being set.


## PLUGINS AND EVENTS DISPATCHING


Did a bit of work to the way plugins work and refactored the event packages to follow the javascript DOM API naming schema for consistency.

1. Event

- KPatternObservable::attach() now returns KPatternObservable
- Renamed KEvent to KEventListener
- Renamed KEventDispatcher::dispatch to dispatchEvent.
- Renamed KEventDispatcher::register to addListener and added new KEventDispatcher::removeListener function

2. Plugins

- Added basepath support to the plugin loader. Plugins are now application specific. Each application can have its own plugins.


## OPTIMIZATIONS


Made some smaller database package optimizations

- KDatabaseTableAbstract::getIdentityColumn no longer performs a mapping. Instead it returns the real column name of the identity column.

- KDatabaseTableAbstract::insert will now also return a $context->insert_id value to retrieve the insert_id of the query. Will return zero if the query was successful but the table doesn't have a auto increment column.

- Optimized KDatabaseAdapterAbstract::insert function to return false if the query failed. Updated docblocks to reflect better what the function returns.

- Fixed typo. KDatabaseAbstract::fetchField() function has been replaced by KDatabaseAbstract::select and using the KDatabase::FETCH_FIELD mode.

---

Did a full code profile on the plane from Amsterdam to Manila resulting in quite a nice performance boost for the framework. On my laptop i'm seeing performance improvements up to 170%.

Most of the changes will not have any impact on your components. The only change that does impact your extensions is the fact that the getX functions no longer return identifiers but do return object instances. This changes was made to reduce the total number of KFactory::get calls we are making. For example:

KController::getView now returns an object instance, so you no longer need to do KFactory::get($this->getView()). Same for getTable, getModel, getTemplate, getController, getRow, getRowset, etc.

For the full list of changes please see #123 ticket :
http://nooku.assembla.com/spaces/nooku-framework/tickets/123-performance-improvements

---

Database optimisations :

- Added performance optimizations to KDatabaseAdapter::getTableInfo, getTableColumns and getTableIndexes to prevent queries from being re-run if a table doesn't exist in the database.

- If a table doesn't exist in the database KModelTable::getTable() will catch the exception and return false instead of throwing an exception himself. With this change you no longer need to add an model that extends KModelAbstract if you are not fetching data from a table.

- Added KDatabaseAdapterAbstract::show() function to handle SHOW database queries. Added KDatabase::OPERATION_SHOW and implemented show function in KDatabaseAdapaterMysqli::getTableColumns, getTableInfo and getTableIndexes.

- KDatabaseAdapterAbstract::getTableColumns, getTableInfo and getTableIndexes are now using show() function instead of going directly through the execute function. This allows the queries to be run through the command chain and will allow easy caching and debugging.

Factory optimizations :

- Refactored factory adapters to either return an object instance or the classname. If a classname the object is instantiated by KFactory::_instantiate(). This change will allow easy caching of the identifiers/classname map.


## COMMANDS


- Added KCommandInterface::getPriority function to allow commands to set their own priority. Implemented getPriority function in all classes that implement KCommandInterface.

- Added $context->query to KDatabaseAdapterAbstract::update, insert and delete functions to be able to easily retrieve the query. This allows easy logging of queries through events or commands.


## SINGULAR VS PLURAL


Fixed issue with factory and plural folder names. All folder names now need to be plural.
For more info see: http://groups.google.com/group/nooku-framework/browse_thread/thread/c93e21c06c58aad4/3c5c83993518eb7d

(Optimized the helper params handling in KTemplateAbstract::loadHelper. If the view is plural we inject the
state of the view, if the view is singular we inject the data of the row object)
Moved merging of helper parameters with view state or item data into ComDefaultTemplateDefault::loadHelper() to prevent issues with module views.


## CONTROLLER CHANGES


Controller actions are now being passed the full KCommandContext object, instead of only the data. This creates more consistency when using controllers action through execute or through a callback.

In your own code you will only need to make sure your controller _actionX function accept a KCommandContext object instead of the raw $data. To get the actual data all you need to do is change your implementation to $data = KConfig::toData($context->data); That's it.

- Added new 'display' action. This action wraps the read and browse actions and determines based on the view name what action to execute.
The display functions is especially handy when calling a controller through it's API.

- For consistency all controller actions now pass a KCommandContext $context object. If you define or specialize your own controller actions make sure to add it.


## CALLBACK HANDLING


Added new 'params' parameter to KMixinCallback that allows you to pass an array or KConfig object with configuration parameters. These parameters will be appended to the KCommandContext object when the callback is being called. No changes required.

Based on a suggestion from Ash : See also :
http://groups.google.com/group/nooku-framework/browse_thread/thread/06248bf0c7758b9f/b51a39b801212a2e#b51a39b801212a2e


## KREQUEST


Added PUT and DELETE hashes to KRequest. For PUT and DELETE requests we are now also storing the request body data in a separate global.
Either $GLOBALS[’_PUT'] or $GLOBALS['_DELETE] and the data is also being merged with the $GLOBALS['_REQUEST'] for consistency with PHP default handling.

Added support for _method to KRequest. This allows you to pass the request method by adding a special _method=x to your request body in a POST request.


## TOKEN CHECK IN DISPATCHER INSTEAD OF CONTROLLER


Moved token check from KControllerAbstract::execute() to new KDispatcherAbstract::_actionAuthorize() function. The authorize
function is being fired as a callback before _actionDispatch();  This will make it easier to implement different authorization solutions by attaching a different authorization mechanism to the dispatcher.


## ERROR HANDLING


Improved error handling and implemented failsafes to prevent WSOD (white screen of death).

- Added KTemplateStream::stream_error function to catch E_ERROR and E_PARSE error through a register_shutdown_function. This functions clean up the output buffer before sending out the error.

- Added while(@ob_get_clean()); to plgSystemKoowa to make sure all output buffers are cleared before rendering the error.

Both changes will prevent WSOD, you do need to have debug turned of from them to have effect.

Exception codes are now being passed to the Joomla error handler. This allows you to throw exceptions which result in sending out correct http status codes. For a list of status codes you can use please see :
http://www.assembla.com/code/nooku-framework/subversion/nodes/trunk/code/libraries/koowa/http/http.php

Exceptions can be throw like :

throw new KDispatcherException('Invalid token or session time-out.',  KHttp::STATUS_UNAUTHORIZED);

## STANDALONE COMPONENTS


Made changes to the way dispatchers work to allow components run in HMVC triads scenarios or standalone. Work in progress, this is a first step.

- Added 'controller_default' class property to KDispatcherAbstract to hold the name of default controller,  by default this property is set to the name of the component. When no view information is specified in the request the default controller will be used to get the controller.

- The KDispatcherAbstract::getController function now returns an controller object instance instead of an identifier and setController also accepts an object instance.

With this change you no longer need to do :

KFactory::get('app::com.foo.dispatcher)->dispatch(KRequest::get('get.view', 'cmd', default));

Instead you should do :

KFactory::get('app::com.foo.dispatcher)->dispatch();

If your default view is not the same as the name of your component you should implement a custom dispatcher and set it's controller_default to the name of your default view. For example :

class ComVersionsDispatcher extends ComDefaultDispatcher
{
    protected function _initialize(KConfig $config)
    {
        $config->append(array(
                'controller_default' => 'revisions'
        ));
        parent::_initialize($config);
    }
}


This will allow us to implement the KFactory::get('app::com.foo.dispatcher)->dispatch(); into a com_application component allow to running components stand-alone. Yes ! It's coming :)

KDispatcher

- KDispatcherAbstract::_actionRender no longer echo's the result but returns it instead. This change requires you to add an echo statement to your KDispatcher call, eg

echo KFactory::get('admin::com.harbour.dispatcher')->dispatch();

-  Removed redirect from _actionDispatch if the token check fails. The global exception handlers will catch the exception.

Changes to KDispatcherAbstract

-  Added 'request' and 'request_persistent' config paramaters

- Set 'request_persistent' to TRUE in ComDefaultDispatcher for all administrator components.

The request_persistent config param allows you to modify how the dispatcher deals with request persistency. By default this is false.

KController

Added KCommandContext $context paramater to all controller actions.

KTemplate

The template write filtering is now done at the end of the display cycle instead of after loading each individual template for performance and flexibility reasons.

-  Removed KViewTemplate::loadTemplate function. Functionality has been moved into KTemplateAbstract::loadIdentifier. Refactored KViewTemplate::display() function to load the template by identifier based on the view layout and render it. Changed KViewTemplate::__toString method to call display instead of loadTemplate.

- KTemplateStream::stream_open no longer loads the contents of the template based on the path. Instead we get the contents of the template through the template registry.

-  Fully refactored KTemplateAbstract to allow for loading of templates from string and from identifier. Added loadIdentifier and loadString methods. Reworked render() method and added new __toString method who calls render function and returns the contents.

- Changed alias for @template to $this->loadIdentifier();

KTemplateHelper

Removed behavior.keepalive function. Doesn't work with Mootools 1.2

KTemplateHelper::factory() will transform an incomplete identifier to com.default.helper.x instead of lib.koowa.template.helper.x

Added specialised version of date helper to com_default. Date helper will automatically set the offset based on Joomla's offset configuration.

- Changed 'offset' to 'gmt_offset' in KTemplateHelperData::format() to prevent collisions issues with paginator offset.

KTemplateFilter

- KTemplateFilter::factory() now cascades through com.default.template.filter when creating filters. This means that if a filter doesn't exist it will first fallback on com.default before falling back on the framework.

Editor Helper

- Removed 'row' config property from editor helper.

KHttp

Added all http status codes and implement getMessage and getHeader functions.

Removed status code from status messages and changed KHttp::getHeader() to add status to code the header string.

Using reflection

Fixed issues with get_class_methods in PHP5.2.5. Instead of using get_class_methods we are now using reflection. See http://bugs.php.net/43483

- KMixinAbstract::getMixableMethods is now using the reflection to fix an issue with get_class_methods not working correctly on PHP versions < 5.2.6.

- KObject::getMethods is now using the reflection to fix an issue with get_class_methods not working correctly on PHP versions < 5.2.6.

- KPatternDecorator::getMethods is now using the reflection API to fix an issue with get_class_methods not working correctly on PHP versions < 5.2.6.

- Added KMixinAbstract::getMethods functions to easily retrieve all the class methods.

- KDatabaseBehaviorAbstract::getHanle is now calling the parent getMethods function to fix an issue with get_class_methods not working correctly on PHP versions < 5.2.6.

- KControllerAbstract::getActions() is now calling the parent getMethods function to fix an issue with get_class_methods not working correctly on PHP versions < 5.2.6.

KConfig refactor

Refactored KConfig to solve inconsistencies (see : http://groups.google.com/group/nooku-framework/browse_thread/thread/d...)

- All arrays are now transformed into KConfig objects both associative and none-associative. The append methods allows to append both associative and none-associative arrays.

- KConfig::append() now also accepts none array values.

Component folder structure changed

Refactored the component folder structure accoording to proposal (see : http://groups.google.com/group/nooku-framework/browse_thread/thread/c...)

- Component folder structure now follows the framework package structure.

- Indentifiers now follow the framework package structure.

This change is fairly significant. You will need to change both your component's folder strcuture as the classnames. If you find any issues please open up a new thread for discussion.

For more info please see :

http://groups.google.com/group/nooku-framework/browse_thread/thread/c...

Improved language file loading

Added specialised ComDefaultControllerDefault::displayView() function to load component language file if we are not routing through the dispatcher, eg when doing an HMVC request.

KView

- Removed addStyle, addScript, getStyles and getScripts functions. Script and style handling has been fully moved into the script and style filters.

- Added KTemplateFilterStyle::_renderStyle and parseStyles function to handle default parsing and rendering of the style information. Both functions can easily be overridden to modify the script filters behavior.

- Added KTemplateFilterScript::_renderScript and parseScripts function to handle default parsing rendering of the script information. Both functions can easily be overridden to modify the script filters behavior.

- Removed document class property from KViewTemplate. Moved script and style handling from display function into new ComDefaultTemplateFilterScript and ComDefaultTemplateFilterStyle

- Changed the media:// alias filter to filter during read and write to also rewrite media:// which is part of php code constructs, like helper config arrays.