GithubHelp home page GithubHelp logo

orm's Introduction

Kohana PHP Framework

Kohana is an elegant, open source, and object oriented HMVC framework built using PHP5, by a team of volunteers. It aims to be swift, secure, and small.

Released under a BSD license, Kohana can be used legally for any open source, commercial, or personal project.

Documentation

Kohana's documentation can be found at http://kohanaframework.org/documentation which also contains an API browser.

The userguide module included in all Kohana releases also allows you to view the documentation locally. Once the userguide module is enabled in the bootstrap, it is accessible from your site via /index.php/guide (or just /guide if you are rewriting your URLs).

Reporting bugs

If you've stumbled across a bug, please help us out by reporting the bug you have found. Simply log in or register and submit a new issue, leaving as much information about the bug as possible, e.g.

  • Steps to reproduce
  • Expected result
  • Actual result

This will help us to fix the bug as quickly as possible, and if you'd like to fix it yourself feel free to fork us on GitHub and submit a pull request!

orm's People

Contributors

acoulton avatar bharat avatar biakaveron avatar bluehawk avatar boxyman avatar brmatt avatar cs278 avatar davecarlson avatar enov avatar geogamba avatar hinton avatar isaiahdw avatar jheathco avatar jimktrains avatar joelpittet avatar kemo avatar kiall avatar martinodf avatar melvinmt avatar mvdnes avatar neo22s avatar pocesar avatar ryross avatar shadlaws avatar yakatz avatar zeelot avatar zombor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orm's Issues

When using with, columns are joined with :, but not escaped.

When creating column names for with(), : is used to join the table and column, the column name now needs to be escape in databases such as Postgres, since : isn't a valid identifier ins ANSI SQL. A possible solution could be to use ___ (3 underscores) as the separator to avoid having to rework many things. A possible patch is included.

:100644 100644 5418cdd... 0000000... M  modules/orm/classes/Kohana/ORM.php

diff --git a/modules/orm/classes/Kohana/ORM.php b/modules/orm/classes/Kohana/ORM.php
index 5418cdd..6e900f1 100644
--- a/modules/orm/classes/Kohana/ORM.php
+++ b/modules/orm/classes/Kohana/ORM.php
@@ -849,7 +849,7 @@ class Kohana_ORM extends Model implements serializable {
                }

                // Split object parts
-               $aliases = explode(':', $target_path);
+               $aliases = explode('___', $target_path);
                $target = $this;
                foreach ($aliases as $alias)
                {
@@ -869,7 +869,7 @@ class Kohana_ORM extends Model implements serializable {

                // Pop-off top alias to get the parent path (user:photo:tag becomes user:photo - the parent table prefix)
                array_pop($aliases);
-               $parent_path = implode(':', $aliases);
+               $parent_path = implode('___', $aliases);

                if (empty($parent_path))
                {
@@ -892,7 +892,7 @@ class Kohana_ORM extends Model implements serializable {
                foreach (array_keys($target->_object) as $column)
                {
                        $name = $target_path.'.'.$column;
-                       $alias = $target_path.':'.$column;
+                       $alias = $target_path.'___'.$column;

                        // Add the prefix so that load_result can determine the relationship
                        $this->select(array($name, $alias));
@@ -1119,7 +1119,7 @@ class Kohana_ORM extends Model implements serializable {

                foreach ($values as $column => $value)
                {
-                       if (strpos($column, ':') === FALSE)
+                       if (strpos($column, '___') === FALSE)
                        {
                                // Load the value to this model
                                $this->_object[$column] = $value;
@@ -1127,7 +1127,7 @@ class Kohana_ORM extends Model implements serializable {
                        else
                        {
                                // Column belongs to a related model
-                               list ($prefix, $column) = explode(':', $column, 2);
+                               list ($prefix, $column) = explode('___', $column, 2);

                                $related[$prefix][$column] = $value;
                        }

PHP 5.6.21 find_all

Hi after upgrading to PHP 5.6.21 find_all will return objects but _original_values is empty and new values are loaded as _changed so ->pk() function return NULL

$model = new Model_Status ();
                $results = $model->find_all ();
                foreach ( $results as $result ) {
                    self::$_table [$result->pk ()] = ( object ) $result->as_array ();
                }

object Model_Status(58) {
   protected _changed => array(4) (
        "id" => string(2) "id"
        "name" => string(4) "name"
        "code" => string(4) "code"
        "message" => string(7) "message"
    )
protected _primary_key => string(2) "id"
protected _primary_key_value => NULL

count_all() bug

Hi,

original code of ORM::count_all() looks as:

public function count_all()
{
// remembering select columns
...
    $this->_build(Database::SELECT);
...
    // Add back in selected columns
    $this->_db_pending += $selects;

    $this->reset();

    // Return the total number of records in a table
    return (int) $records;
}

$this->reset(); looks wrong:

we are counting not all records in the table, but those matching the conditions set earlier,
eg. if we have 100 records in total, but only 55 of them do have ref_id = 55 then following code will return 55

$mdl = ORM::factory('Model')->where('ref_id', '=', 55);
echo $mdl->count_all();

so why do we reset builder entirely? Should not we do $this->reset(FALSE); instead?

thanks

Using the object to fetch

Now I make a selection like this:

        $count_all = ORM::factory('Advert')
            ->where('status_id', 'in', [
                ORM::factory('Advert_Status')->where('name', '=', 'new')->find(),
                ORM::factory('Advert_Status')->where('name', '=', 'moderation')->find(),
            ])->count_all();

It would be nice to be able to do so:

        $count_all = ORM::factory('Advert')
            ->where('status_id', 'in', ORM::factory('Advert_Status')
                    ->where('name', 'in', ['new', 'moderation'])
                    ->find_all()
            )->count_all();

What do you think?

yet another count_all() bug

Hi,

having the situation of selecting users having 'admin' role and any of some predefined roles set one can use, for example, next sequence

$admins = ORM::factory('Role')->where('name', '=', 'admin')->find()->customers;
// $rids is an array of predefined roles IDs
$admins
    ->distinct(TRUE)
    ->join('customer_role', 'roles_list')->on('roles_list.customer_id', '=', 'user.id')
    ->where('roles_list.role_id', 'in', $rids);

this produces absolutely perfectly valid SQL:

SELECT DISTINCT `user`.*
FROM `customer` AS `user`
JOIN `customer_role` ON (`customer_role`.`customer_id` = `user`.`id`)
JOIN `customer_role` AS `roles_list` ON (`roles_list`.`customer_id` = `user`.`id`)
WHERE `customer_role`.`role_id` = '2' AND `roles_list`.`role_id` IN (2, 9, 1, 8)

However, if we try to count such admins using $admins->count_all() this is rendered to wrong sQL like this:

SELECT DISTINCT COUNT(`user`.`id`) AS `records_found`
FROM `customer` AS `user`
JOIN `customer_role` ON (`customer_role`.`customer_id` = `user`.`id`)
JOIN `customer_role` AS `roles_list` ON (`roles_list`.`customer_id` = `user`.`id`)
WHERE `customer_role`.`role_id` = '2' AND `roles_list`.`role_id` IN (2, 9, 1, 8)

Which in turn gives wrong count. It easy to see that we need to have

SELECT COUNT(DISTINCT user.id)
instead of
SELECT DISTINCT COUNT(user.id)

see https://github.com/kohana/orm/blob/3.3/master/classes/Kohana/ORM.php#L1621
particularly starting from line 1644 (https://github.com/kohana/orm/blob/3.3/master/classes/Kohana/ORM.php#L1644)

Thanks

Can not create row with only one column "id"

I have a table with only one column - id.
When I create object and then save them - the following error is occurring:

SQLSTATE[HY000]: General error: 1 near ")": syntax error [ INSERT INTO `attribute_collections` () VALUES ()

I think, that kohana orm does not support to insert record with only 1 column (and this one is primary key).
I think it should be fixed.

Creating node by has_one relation

I have the next code:

class Model_User extends Model_Auth_User 
{

    protected $_has_one = array(
        'profile' => array(
            'model' => 'User_Profile',
            'foreign_key' => 'user_id'
        )
    );

    protected $_has_many = array(
        'user_tokens' => array(
            'model' => 'User_Token',
            'foreign_key' => 'user_id',
        ),
        'roles'  => array(
            'model' => 'Role',
        'through' => 'roles_users'
        )
    );

}

So, i can create Model_User node and, for example, a few roles for user by:

public function createUser(array $userData, array $userProfileData, array $roles)
{
    // ...

    $this->values()->check()->save();
    $this->add('roles', $roles);

    // ...
}

But, how i can create the profile node? Profile is a simple model, which has user_id as primary key and other non-value data (first_name, last_name of user and etc.).

So, i tried to do this:

public function createUser(array $userData, array $userProfileData, array $roles)
{
    // ...

    $this->values()->check()->save();
    $userId = $this->id;

    $userProfileData['user_id'] = $userId;

    ORM::factory('User_Profile')->values($userProfileData)->check()->save(); // this

    $this->add('roles', $roles);

    // ...
}

But in values() method primary_key (user_id) is unsetting! So, i need use this:

ORM::factory('User_Profile')->set('user_id', $userId)->values($userProfileData)->check()->save(); 

That looks strange, i think. Need to create method as 'add()' (add() for has_many relations) for has_one relation, i think.

SQL injection vulnerability

ORM methods are prone to SQL injection
for example method limit($number)
should enforce / cast true natural number, not anything user passes into it.
Same with other functions

Relation existing checks in Model

I want to check existing of some relations in my model. So, for example, we take a default User model. So, for check roles we should do this: ORM::factory('User', 1)->has('roles'). If user has at least 1 role, returns TRUE. So, next, i want to check existing of user tokens (remember me checkbox in authorization), so i do this: ORM::factory('User', 1)->has('user_tokens'). And this return me an exception, because it's unknown from which table we should select number of nodes for checking this relation.

So, we have next code in our model:

class Model_User extends Model_Auth_User 
{

    protected $_has_many = array(
        'user_tokens' => array(
            'model' => 'User_Token',
            'foreign_key' => 'user_id',
        ),
        'roles'  => array(
            'model' => 'Role',
        'through' => 'roles_users'
        )
    );

}

For correct works of that function (has()) we should add to 'user_tokens' relatio name of table to 'through' key, but, by database conception, this is not correct.

And my second question is: how to check one-to-one relation? For example, i has 'user_profile' table (which contains first_name, last_name, address and other none-value information):
(the same model)

protected $_has_one = array(
    'profile' => array(
        'model' => 'User_Profile',
        'foreign_key' => 'user_id',
    )
);

And how can i check this relation? Excepting of this ofc:

ORM::factory('User', 1)->profile->count_all() > 0

So, what can you say, community?

Multiple primary keys, unique values, etc. in ORM declaration

How we know, table (by default) roles_users has 2 fields: role_id, user_id. And primary key in this table (in database level) is bunch of two fields (role_id, user_id). So, in Kohana's ORM not exist that option (I mean: declare primary key using two fields).
For example (in my project, i changed some base names for my convenience (this is default Model for roles_users table) as this:

class Model_Role_UserRef extends ORM
{
      protected $_primary_key = array('role_id', 'user_id');
      protected $_table_name = 'core_roles_users_ref';
}

Also, about unique fields. In MySQL (for example) we can also use bunch of fields for unique values (for example id and email). So, in Kohana's ORM not exist that option too. But, in Kohana, this rule works just on rules() method (one solve of that problem is: we can catch database exception from MySQL).

Add transaction feature to ORM

For creating user i need to do this actions (insert to users, roles_users and user_profile (first_name, last_name data and some) tables (this is method from Model_User):

public function createUser($userData, $userProfileData, $userRoles = array(Model_Role::ROLE_LOGIN))
{
        $db = Database::instance();

        $db->begin();

        try
        {
            // `users`

            $userData['password'] = Arr::get($userData, 'password', Generate::generatePassword(Generate::PWD_TYPE_6_NUMBERS));

            $this->values($userData);

            $this->check();
            $this->save();

            $userId = $this->id;

            // `user_profile`

            $userProfileId = ORM::factory('User_Profile')->createUserProfile($userId, $userProfileData);

            // `roles_users`

            $this->add('roles', $userRoles);

            // ...

            $db->commit();

            return $userId;
        }
        catch(Database_Exception $exception)
        {
            $exception->getMessage();
            $db->rollback();

            return FALSE;
        }

        return FALSE;
    }

So, it looks very strong and massive. And if your models are not simple (for creating 1 essence you need to create related nodes in other tables), you already must use the transactions.

I am not really sure, that it is not OK and transactions need into ORM, but we can discuss about that :)

First filter(), second rules()

By this (title of issue), password of user first hashes (By filter of Model_User (Auth::instance()->hash()), and after them it checks for some rules from rules() method. And, so, min_length, for example, doesn't works.

Auto-generating forms from ORM model declaration

This can work just by (for example, of course):

echo ORM::factory('User')->renderForm();

And we see on screen all of fields, relations (selects (one-to-one), multiple checkboxes for many-to-many relations, etc.).

I saw that option in Symfony 1.4 (you declare model class and can render form for insert node to this moel). In Symfony 1.4 you can also generate the whole admin-panel by this options. But, of course, in Symfony 1.4 are Propel and Doctrine ORM conception...

So, i think, but it is the most important thing for framework. So, developers just declare model for table and use some automatic filters, rules, checks and form generating.

Also: need to think about automatic pagination generating for list of ORM data;

Don't use magic "behind the curtains"

ORM shouldn't rely on magic methods natively but use the methods for setting / getting instead. Examples;
$this->{$name} = $var;
$this->{$key}->values($values[$key], $column);
$this->$column = $values[$column];
$data[$var] = $this->{$var};
$this->{$property} = $value;

This obviously doesn't apply to properties which aren't magic anyway

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.