Skip to content

Releases: nova-framework/framework

Add method Database\Query\Builder@addSelect

31 May 05:54
Compare
Choose a tag to compare
Merge pull request #907 from LuckyCyborg/master

Add method Database\Query\Builder@addSelect, being required by ORM for May-to-Many relations

Quick Profiler

30 May 21:36
Compare
Choose a tag to compare

This pull request integrate in Nova Framework a small and smart Quick Profiler, very useful for forensics or debugging a application in the development stage.

And YES, I have myself the habit to use this way of debugging, while development.

The Quick Profiler while well integrated on Nova's System, is a standalone system, with no influence over the Classic or New Style APIs, and will be activated on 'development' ENVIRONMENT, while in the Profiler configuration the option useForensics is set to true.

A note of warning: this Quick Profiler is a Live Debugger and show lots of sensitive information, then is recommended to NOT be activated on production sites, even for short time.

The Quick Profiler is for Development Stage only!

What to expect from...

snapshot6
snapshot7
snapshot8
snapshot9

add some site-wide functions, required for the ORM

30 May 11:48
Compare
Choose a tag to compare

This pull request add some site-wide functions, required for the ORM to works on every detail, and introduce a small fix on Support\Facades\Session.

Another optimization is moving the execution of the Views associated Hooks from Core\Controller to a Event defined on app/Events.php, making their execution optional.

This ability is very useful when the Nova Framework is used to create a RESTful API, where is no need for execution of those Hooks.

Finally, this pull request introduce improvements and optimizations of Database\Connection, adding also a support for debugging.

Also, a small Google ReCaptcha Helpers is added.

added support for using **PostgresSQL** and **SQLite**

29 May 14:56
Compare
Choose a tag to compare

This pull request introduce in the Database API the support for using PostgresSQL and SQLite Databases also, behind of the MySQL ones.

To note that this pull request does NOT introduce any API changes of breaks.

New add_http function and times helper

29 May 13:31
Compare
Choose a tag to compare

added addhttp
This function ensures passed $url starts with http or https depending on the scheme.

Usage:

$url = 'novaframework.com';
$url = add_http($url); //http://novaframework.com

Added Times helper
This helper will take an array of times and add them together to get a
total time.

use Helpers\Times;
$times = array('10:23:00', '00:15:46', '1:04:56');
$counter = new Times($times);
echo $counter->getTotalTime();
//outputs: 11:43:42

database helper compatible with database api

29 May 13:12
Compare
Choose a tag to compare

This pull request improve the Helpers\Database and integrate it with the Database API, making possible to use it even when Database API is used too, without to duplicate the database connections.

The single visible change in API is that the optional parameter of the method Database::get() is now a string, defaulting to 'default', and indicating the Database API configuration entry used, instead of being a configuration array. Usage is simple:

// Get the default Database instance
$db = Database::get();

// Get a custom configured Database instance
$customDb = Database::get('custom');

To note that the API remains unchanged in the rest.

improved Legacy Rendering System + ORM

29 May 10:36
Compare
Choose a tag to compare

An improved Legacy Rendering System

Introduction

The improved Legacy Rendering System will queue the generated View and Template instances, along with the developer's calling of the Legacy View Calls.

They will be processed on the Controller's Middleware, when the current Action returns NULL, together with the given Legacy Header Calls, and there will be generated a Response instance and it will be sent according.

This Design permit a faster page / response generation and an improved compatibility and interchangeability between the Classic and New Style APIs.

Basic Usage

There are no changes on the user-exposed Legacy Rendering API.

Database API - Object Relational Models

Introduction

The Database ORM included with Nova Framework provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table.

Before getting started, be sure to configure a database connection in app/Config/Database.php.

Basic Usage

To get started, create an ORM model. Models typically live in the app/Models directory, but you are free to place them anywhere that can be auto-loaded according to your composer.json file.

Defining An ORM Model

class User extends \Database\ORM\Model {}

Note that we did not tell ORM which table to use for our User model. The lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, ORM will assume the User model stores records in the users table. You may specify a custom table by defining a table property on your model:

class User extends \Database\ORM\Model {

    protected $table = 'my_users';

}

Note: ORM will also assume that each table has a primary key column named id. You may define a primaryKey property to override this convention. Likewise, you may define a connection property to override the name of the database connection that should be used when utilizing the model.

Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place updated_at and created_at columns on your table by default. If you do not wish to have these columns automatically maintained, set the $timestamps property on your model to false.

Retrieving All Models

$users = User::all();

Retrieving A Record By Primary Key

$user = User::find(1);

var_dump($user->name);

Note: All methods available on the QueryBuilder are also available when querying ORM models.

Retrieving A Model By Primary Key Or Throw An Exception

Sometimes you may wish to throw an exception if a model is not found, allowing you to catch the exceptions using an App::error handler and display a 404 page.

$model = User::findOrFail(1);

$model = User::where('votes', '>', 100)->firstOrFail();

To register the error handler, listen for the ModelNotFoundException

use Database\ORM\ModelNotFoundException;

App::error(function(ModelNotFoundException $e)
{
    return Response::make('Not Found', 404);
});

Querying Using ORM Models

$users = User::where('votes', '>', 100)->take(10)->get();

foreach ($users as $user)
{
    var_dump($user->name);
}

ORM Aggregates

Of course, you may also use the query builder aggregate functions.

$count = User::where('votes', '>', 100)->count();

If you are unable to generate the query you need via the fluent interface, feel free to use whereRaw:

$users = User::whereRaw('age > ? and votes = 100', array(25))->get();

Chunking Results

If you need to process a lot (thousands) of ORM records, using the chunk command will allow you to do without eating all of your RAM:

User::chunk(200, function($users)
{
    foreach ($users as $user)
    {
        //
    }
});

The first argument passed to the method is the number of records you wish to receive per "chunk". The Closure passed as the second argument will be called for each chunk that is pulled from the database.

Specifying The Query Connection

You may also specify which database connection should be used when running an ORM query. Simply use the on method:

$user = User::on('connection-name')->find(1);

Mass Assignment

When creating a new model, you pass an array of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment. This is convenient; however, can be a serious security concern when blindly passing user input into a model. If user input is blindly passed into a model, the user is free to modify any and all of the model's attributes. For this reason, all ORM models protect against mass-assignment by default.

To get started, set the fillable or guarded properties on your model.

Defining Fillable Attributes On A Model

The fillable property specifies which attributes should be mass-assignable. This can be set at the class or instance level.

class User extends \Database\ORM\Model {

    protected $fillable = array('first_name', 'last_name', 'email');

}

In this example, only the three listed attributes will be mass-assignable.

Defining Guarded Attributes On A Model

The inverse of fillable is guarded, and serves as a "black-list" instead of a "white-list":

class User extends \Database\ORM\Model {

    protected $guarded = array('id', 'password');

}

Note: When using guarded, you should still never pass Input::get() or any raw array of user controlled input into a save or update method, as any column that is not guarded may be updated.

Blocking All Attributes From Mass Assignment

In the example above, the id and password attributes may not be mass assigned. All other attributes will be mass assignable. You may also block all attributes from mass assignment using the guard property:

protected $guarded = array('*');

Insert, Update, Delete

To create a new record in the database from a model, simply create a new model instance and call the save method.

Saving A New Model

$user = new User;

$user->name = 'John';

$user->save();

Note: Typically, your ORM models will have auto-incrementing keys. However, if you wish to specify your own keys, set the incrementing property on your model to false.

You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all ORM models protect against mass-assignment.

After saving or creating a new model that uses auto-incrementing IDs, you may retrieve the ID by accessing the object's id attribute:

$insertedId = $user->id;

Setting The Guarded Attributes On The Model

class User extends \Database\ORM\Model {

    protected $guarded = array('id', 'account_id');

}

Using The Model Create Method

// Create a new user in the database...
$user = User::create(array('name' => 'John'));

// Retrieve the user by the attributes, or create it if it doesn't exist...
$user = User::firstOrCreate(array('name' => 'John'));

// Retrieve the user by the attributes, or instantiate a new instance...
$user = User::firstOrNew(array('name' => 'John'));

Updating A Retrieved Model

To update a model, you may retrieve it, change an attribute, and use the save method:

$user = User::find(1);

$user->email = '[email protected]';

$user->save();

Saving A Model And Relationships

Sometimes you may wish to save not only a model, but also all of its relationships. To do so, you may use the push method:

$user->push();

You may also run updates as queries against a set of models:

$affectedRows = User::where('votes', '>', 100)->update(array('status' => 2));

Deleting An Existing Model

To delete a model, simply call the delete method on the instance:

$user = User::find(1);

$user->delete();

Deleting An Existing Model By Key

User::destroy(1);

User::destroy(array(1, 2, 3));

User::destroy(1, 2, 3);

Of course, you may also run a delete query on a set of models:

$affectedRows = User::where('votes', '>', 100)->delete();

Updating Only The Model's Timestamps

If you wish to simply update the timestamps on a model, you may use the touch method:

$user->touch();

Soft Deleting

When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at timestamp is set on the record. To enable soft deletes for a model, specify the softDelete property on the model:

class User extends \Database\ORM\Model {

    p...
Read more

minor patch for Respose

26 May 23:09
Compare
Choose a tag to compare
Merge pull request #889 from geomorillo/master

changing use for Respose

improve the **Pagination API**

26 May 09:30
Compare
Choose a tag to compare

This pull request improve the Pagination API and its integration with Database API.

Also, it introduce a Facade for Pagination API and ability to configure the current page name, aka the query parameter which specify the Pagination's current Page. Usage:

use Paginator;
use DB;

// Set the custom Page Name
Paginator::setPageName('p');

// Get a Paginator instance from the QueryBuilder.
$paginate = DB::table('posts')->paginate(25);

// Print the Pagination Links.
echo $paginate->links();

// Process the current Page results.
foreach ($paginate->getItems() as $post) {
    echo $post->title .'<br>';
}

Also, there is introduced the ability to specify per Model the number of Items returned for a Page on the Pagination\Paginator instance by QueryBuilder, using as following:

namespace App\Models;

use Database\Model;

class Users extends Model
{
    /**
     * The table associated with the Model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The primary key for the Model.
     *
     * @var string
     */
    protected $primaryKey = 'id';

    /**
     * The number of Records to return for pagination.
     *
     * @var int
     */
    protected $perPage = 25;
}

That perPage setting will be honored, of course, on the Model's associated QueryBuilder instances.

Finally, the Database\Query\Builder API is enhanced for a better Pagination integration.

Pagination API

26 May 07:07
Compare
Choose a tag to compare

This pull request introduce a new Pagination API, in a Laravel-esque style, integrated with the Database API, permitting a very simple usage while offering a strong API.

Example of the Pagination API usage:

use DB;

// Get a Paginator instance from the QueryBuilder.
$paginate = DB::table('posts')->paginate(20);

// Add additional query parameters.
$paginate->appends(array(
    'testing' => 1,
    'example' => 'the_example_string',
));

// Get the Pagination Links.
$content = $paginate->links();

// Process the current Page results.
foreach ($paginate->getItems() as $post) {
    $content .= '<h3>' .$post->title .'</h3>';
    $content .= $post->content;
}

echo $content;

For a full control on QueryBuilder paginate():

// Get a full customized Paginator instance from the QueryBuilder.
$paginate = DB::table('posts')->paginate(25, array('*')); 

Like you see, there is no need to instantiate the Pagination\Paginator yourself, the QueryBuilder returning a properly instance, which contains also the expected results for the current Page and accessible with the method getItems(), or even using directly the Paginator isntance. For example:

$content = $paginate->links();

// Process the current Page results.
foreach ($paginate as $post) {
    $content .= '<h3>' .$post->title .'</h3>';
    $content .= $post->content;
}

echo $content;

For rendering the Pagination Links, the Pagination\Paginator use the concept of Presenter, by default using the native one, Pagination\Presenter, compatible with the Bootstrap 3.x based templates, but it is possible to extend it and to use a custom Presenter instance, as following:

use App\Pagination\CustomPresenter;
use DB;

// Get a Paginator instance from the QueryBuilder.
$paginate = DB::table('posts')->paginate(20);

// Get a custom Presenter instance and setup it.
$presenter = new CustomPresenter($paginate);

echo $presenter->links();

Alternatively, you can setup the custom Presenter instance to be used by the Paginator instance directly by default.

$paginate->setPresenter($presenter);

// Print the custom Pagination Links.
echo $paginate->links();

To note that this Pagination API is a new feature of New Style APIs only, then it doesn't introduce any API break.