Giter Club home page Giter Club logo

lithium's Introduction

li₃

You asked for a better framework. Here it is.

li₃ is the fast, flexible and the most RAD development framework for PHP.

A framework of firsts

li₃ is the first and only major PHP framework built from the ground up for PHP 5.3+, and the first to break ground into major new technologies, including bridging the gap between relational and non-relational databases through a single, unified API.

Promiscuously opinionated

Some frameworks give you a solid set of classes, but little or no default project organization, leaving you to fend for yourself on each project you create, and spend time wiring up framework classes that should just work together. Others provide you with great organizational conventions, but no way to break out of those conventions if you need to, and too often, no way to override or replace core framework classes.

li₃ is the first framework to give you the best of both worlds, without compromising either. In fact, li₃'s API is intentionally designed to allow you to "grow out of" the framework and into your own custom code over the course of your application's lifecycle, if your needs require.

Technology

li₃ takes full advantage of the latest PHP features, including namespaces, late static binding and closures. li₃'s innovative method filter system makes extensive use of closures and anonymous functions to allow application developers to "wrap" framework method calls, intercepting parameters before, and return values after.

li₃ also complies with PSR-4, the PHP namespacing standard, allowing you to easily integrate other PHP standard libraries and frameworks with li₃ applications, and vice-versa.

li₃ integrates the latest storage technologies, including MongoDB, CouchDB and Redis, with plugin support for Cassandra, ElasticSearch and others.

Flexibility

li₃ gives you full control over your application, from filters to dynamically modify framework internals, to dynamic dependencies to extend and replace core classes with application or plugin classes, to heavy use of adapter-oriented configurations, to make it seamless to move between different technologies and options.

Every component of the li₃ framework stack is replaceable through the robust plugin architecture. Swap out the default ORM / ODM implementation for Doctrine 2 or PHP ActiveRecord. Don't like the templating? Use Twig, Mustache, or roll your own.

If you don't even need to write a full application, build a micro-app in a single file using the routing system, without giving up the maintainability of the framework's structure.

lithium's People

Contributors

alkemann avatar cgarvis avatar daetal-us avatar daschl avatar ddebernardy avatar dyster avatar ericcholis avatar farhadi avatar greut avatar gwoo avatar hans-d avatar howard3 avatar indiefan avatar jails avatar jlogsdon avatar jperras avatar koushki avatar kuja avatar m4rcsch avatar mackstar avatar mariano avatar mariuswilms avatar masom avatar mehlah avatar mikegreiling avatar nateabele avatar niel avatar rapzo avatar rmarscher avatar vesln 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  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

lithium's Issues

Cannot call find() on $RecordSet unless $RecordSet->count() is called first

I cannot call find() on a RecordSet unless I somehow iterate over the data. Seems like a lazy-load issue.

/**
 * This does not work as expected
 */
$rs = Companies::find('all');

$i = 0;
$rs->find(function($entity) use (&$i) {
    $i++;
});

var_dump($i); // $i = 0



/**
 * If we call $rs->count() then $rs->find() works as expected
 */
$rs = Companies::find('all');
$rs->count(); 

$i = 0;
$rs->find(function($entity) use (&$i) {
    $i++;
});

var_dump($i); // $i > 1;

Memcache adapter should be `Memcached`

While they are both using memcached, Memcache and Memcached are two separate PHP extensions.
When I configured my Cache and wrote 'adapter' => 'Memcache' I expected li3 to use Memcache and not Memcached.

Validating empty arrays

Note: this ticket is ported over from rad-dev.org and consolidates a bunch of tickets of the same topic.

The enhancement states some way of validating if an array is empty or not (which is handy vor validating selects, checkboxes and other stuff).

Here is a proposal for a recursive approach to test for empty arrays. It basically extends the current pattern recursively on arrays. Some test cases included. Feel free to talk about and/or contribute!

//'notEmpty'     => '/[^\s]+/m',
'notEmpty'     => function($value, $format = null, array $options = array()) {
    $pattern = '/[^\s]+/m';
    $arrayTest = function($arr) use ($pattern, &$arrayTest) {
        foreach($arr as $k => $v) {
            if(is_array($v)) {
                return $arrayTest($v, $arrayTest);
            } else {
                if(preg_match($pattern, $v)) {
                    return true;
                }
            }
        }
        return false;
    };
    return $arrayTest((array)$value);
},

public function testNotEmptyRule() {
    $this->assertTrue(Validator::isNotEmpty('abcdefg'));
    $this->assertTrue(Validator::isNotEmpty('fasdf '));
    $this->assertTrue(Validator::isNotEmpty('fooo' . chr(243) . 'blabla'));
    $this->assertTrue(Validator::isNotEmpty('abç�ĕʑʘπй'));
    $this->assertTrue(Validator::isNotEmpty('José'));
    $this->assertTrue(Validator::isNotEmpty('é'));
    $this->assertTrue(Validator::isNotEmpty('Ï€'));
    $this->assertFalse(Validator::isNotEmpty("\t "));
    $this->assertFalse(Validator::isNotEmpty(""));

    $this->assertTrue(Validator::isNotEmpty(array('foo', 'bar')));
    $this->assertTrue(Validator::isNotEmpty(array(array('foo'))));
    $this->assertFalse(Validator::isNotEmpty(array()));
    $this->assertFalse(Validator::isNotEmpty(array(array())));
    $this->assertFalse(Validator::isNotEmpty(array("", "\t ")));
    $this->assertFalse(Validator::isNotEmpty(array(array(""), "\t ")));
}

Render select as multiple checkboxes

During discussion on IRC with @alkemann, a possibility would be to render a select box (or similar), as a list of multiple checkboxes.

Here is a snipped by @alkemann that does basically the same but not tightly integrated into the form helper:

<?php 
/**
 * Render a special field that uses multiple checkboxes
 *
 * @param string $field
 * @param array $options
 * @return string
 */
public function multiple($field, $options) {
    $ret = '<div class="item checkbox"><label>';
    $ret .= isset($options['display']) ? $options['display'] : \lithium\util\Inflector::humanize($field);
    $ret .= '</label>';
    $fieldOptions = array(
        'wrap' => array('class' => 'sub-item'),
        'type' => 'checkbox',
        'hidden' => false
    );
    foreach ($options['options'] as $value => $label) {
        $optionOptions = array(
            'id' => $field.'-'.$value,
            'value' => $value,
            'label' => $label)
                + $fieldOptions;
        if (isset($options['default']) && in_array($value, $options['default'])) {
            $optionOptions['checked'] = true;
        }
        $ret .= parent::field($field.'[]', $optionOptions);
    }
    $ret .= '</div>';
    return $ret;
}
?>

What do you guys think about that? If we choose a specific implementation, I'll volunteer to implement it with tests.

Regards, daschl

Form helper config doesn't work for field

In lithium/template/helper/Form.php (function field) lines

list($options, $fieldOptions) = $this->_options($defaults, $options);
list(, $options, $template) = $this->_defaults(__FUNCTION__, $name, $options);

should be switched to

list(, $options, $template) = $this->_defaults(__FUNCTION__, $name, $options);
list($options, $fieldOptions) = $this->_options($defaults, $options);

as it is in other functions. For now config doesn't work properly for field.

CouchDb connection almost un-usable?

Given the following test

namespace app\tests\cases\models;

use lithium\data\Connections;
use app\tests\mocks\MockModel;

class CouchDbTest extends \lithium\test\Unit {

    protected $_testData = null;

    public function setUp() {
        $this->_testData = array(
            '_id' => 'testid',
            'name' => 'name'
        );

        Connections::add('couch', array(
            'type' =>  'http',
            'adapter' => 'CouchDb',
            'database' => 'testing',
            'host' => 'localhost'
        ));
        Connections::add('mongo', array(
            'type' =>  'MongoDb',
            'database' => 'testing',
            'host' => 'localhost'
        ));
    }

    public function testMongDbIterations() {
        MockModel::meta(array('connection' => 'mongo'));
        $data = MockModel::create($this->_testData);
        $this->assertTrue($data->save());
        $results = MockModel::all();
        $this->assertEqual(1, count($results));
        foreach($results as $result){
            $this->assertEqual($this->_testData['_id'], $result->_id);
            $this->assertEqual($this->_testData['name'], $result->name);
        }
        $result = MockModel::first();
        $this->assertEqual($this->_testData['_id'], $result->_id);
        $this->assertEqual($this->_testData['name'], $result->name);
        $data = MockModel::create(array('_id' => 'testid2', 'name' => 'name2'));
        MockModel::remove(array('_id' => 'testid2'));
        $results = MockModel::all();
        $this->assertEqual(1, count($results));
        MockModel::remove();

    }

    public function testCouchIterations() {
        MockModel::meta(array('connection' => 'couch'));
        $data = MockModel::create($this->_testData);
        $this->assertTrue($data->save());
        $result = MockModel::find($this->_testData['_id']);
        $this->assertEqual($this->_testData['_id'], $result->id);
        $this->assertEqual($this->_testData['name'], $result->name);
        $result = MockModel::first();
        $this->assertEqual($this->_testData['_id'], $result->id);
        $this->assertEqual($this->_testData['name'], $result->name);
        $results = MockModel::all();
        $this->assertEqual(1, count($results));
        foreach($results as $result){
            $this->assertEqual($this->_testData['_id'], $result->id);
        }
    }

}

And the following not really mock object

namespace app\tests\mocks;

class MockModel extends \lithium\data\Model {

}

I have compared the results with those for mongo, which tests all pass. You need to make sure that you have a db named 'testing'

Model::find($id); does work

It seems clear that all, first and similar queries are not producing results as they should. I don't know if this is a problem with the http datasource or couchdb adapter, but the problem is very apparent seemingly making it unusable. Is this just me?

CouchDB "_attachments"

The current framework of Lithium seems not he be set to upload "_attachments" to CouchDB.

By using for example the FormHelper the files are not added in the CouchDB database as the, by CouchDB provided, _attachment field. Thi field could in a second step be simply loaded.

Also the by naming the field _attachment has no success since CouchDB does not allow to insert the file by this way.

The current framework makes it impossible to upload files to CouchDB.

Thanks, Nils

Model is described twice

If no scheme defined in the Model, it will call scheme method.

/*...*/
if (!$self->_schema) {
    $self->_schema = static::connection()->describe($self::meta('source'), $self->_meta);
/*...*/

Then meta calls hasField() which calls scheme again. This executes describe query twice.

Problem with filters

Hi,

I want to do one filter for verify unique username.

Follow below my code:

<?php

namespace app\models;

use \lithium\util\Validator;
use \lithium\data\Connections;


class Users extends \lithium\data\Model {



    public $validates = array(
        'username' => array(
            array('notEmpty', 'message'=>'You must include a username.'),
            array('isUniqueUsername', 'message'=>'username ja utilizado'),
        ),
        'password' => array(
            array('notEmpty', 'message'=>'You must include a password.')
        ),
    );

    public static function __init(array $options = array()) {
        parent::__init($options);
        $self = static::_instance($options);

        $self->_finders['count'] = function($self, $params, $chain) use (&$query, &$classes) {
        $db = Connections::get($self::meta('connection'));
        $records = $db->read('SELECT count(*) as count FROM users', array('return' => 'array'));

        Validator::add('isUniqueUsername', function ($value, $format, $options) {
                $conditions = array('username' => $value);
                // Lookup for posts with same title
                // If editing the post, skip the current psot
                if (isset($options['values']['id'])) {
                        $conditions[] = 'id != ' . $options['values']['id'];
                }

                return !Users::find('first', array('conditions' => $conditions));
        });
        return $records[0]['count'];
        };
    }
}
        //We call the applyFilter() method OUTSIDE the class to create our new filter rules
       Users::applyFilter('save', function($self, $params, $chain){
       //Temporarily store our entity object so that we can manipulate it
       $record = $params['entity'];

       //If an id doesn't exist yet, then we know we're saving for the first time. If a
       //password is provided, we need to hash it
       if(!$record->id && !empty($record->password)){
          $record->password = \lithium\util\String::hash($record->password);
       }
       //Write the modified object back to $params
       $params['entity'] = $record;
       //Allow the next filter to be run
       return $chain->next($self, $params, $chain);
       });


?>

my server return:

[Wed Mar 30 20:45:15 2011] [error] [client 189.101.236.49] PHP Warning:  Missing argument 1 for lithium\\core\\StaticObject::_instance(), called in /home/trinion/dev/labs/lithiumtest/dev/html/app/models/Users.php on line 25 and defined in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/StaticObject.php on line 94
[Wed Mar 30 20:45:15 2011] [error] [client 189.101.236.49] PHP Notice:  Undefined variable: name in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/StaticObject.php on line 95
[Wed Mar 30 20:45:15 2011] [error] [client 189.101.236.49] PHP Notice:  Undefined variable: name in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/StaticObject.php on line 98
[Wed Mar 30 20:45:15 2011] [error] [client 189.101.236.49] PHP Fatal error:  Uncaught exception 'lithium\\core\\ClassNotFoundException' with message 'Invalid class lookup: `$name` and `$type` are empty.' in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php:614\nStack trace:\n#0 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php(631): lithium\\core\\{closure}('lithium\\core\\Li...', Array)\n#1 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/StaticObject.php(98): lithium\\core\\Libraries::instance(NULL, NULL, Array)\n#2 /home/trinion/dev/labs/lithiumtest/dev/html/app/models/Users.php(25): lithium\\core\\StaticObject::_instance()\n#3 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php(470): app\\models\\Users::__init()\n#4 [internal function]: lithium\\core\\Libraries::load('app\\models\\User...')\n#5 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/security/auth/adapter/Form.php(202): spl_autoload_call('app\\models\\User...')\n#6 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/s in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php on line 614
[Wed Mar 30 21:04:37 2011] [error] [client 189.101.236.49] PHP Fatal error:  Uncaught exception 'lithium\\core\\ClassNotFoundException' with message 'Invalid class lookup: `$name` and `$type` are empty.' in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php:614\nStack trace:\n#0 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php(631): lithium\\core\\{closure}('lithium\\core\\Li...', Array)\n#1 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/StaticObject.php(98): lithium\\core\\Libraries::instance(NULL, Array, Array)\n#2 /home/trinion/dev/labs/lithiumtest/dev/html/app/models/Users.php(25): lithium\\core\\StaticObject::_instance(Array)\n#3 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php(470): app\\models\\Users::__init()\n#4 [internal function]: lithium\\core\\Libraries::load('app\\models\\User...')\n#5 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/security/auth/adapter/Form.php(202): spl_autoload_call('app\\models\\User...')\n#6 /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lit in /home/trinion/dev/labs/lithiumtest/dev/html/libraries/lithium/core/Libraries.php on line 614

Somebody help me?

Wrong default value for timestamp columns in mysql

Fatal error: Uncaught exception 'lithium\data\model\QueryException' with message 'INSERT INTO posts (title, postAt, body) VALUES ('ggggggggggggg', 'CURRENT_TIMESTAMP', 'ggggggggggggggggggg');: Incorrect datetime value: 'CURRENT_TIMESTAMP' for column 'postAt' at row 1' in F:\phpweb\li.tlt.tld\libraries\lithium\data\source\database\adapter\MySql.php:343 Stack trace: #0 F:\phpweb\li.tlt.tld\libraries\lithium\core\Object.php(240): lithium\data\source\database\adapter{closure}(Object(lithium\data\source\database\adapter\MySql), Array, NULL) #1 F:\phpweb\li.tlt.tld\libraries\lithium\data\source\database\adapter\MySql.php(344): lithium\core\Object->_filter('lithium\data\so...', Array, Object(Closure)) #2 F:\phpweb\li.tlt.tld\libraries\lithium\core\Object.php(169): lithium\data\source\database\adapter\MySql->_execute('INSERT INTO `po...') #3 F:\phpweb\li.tlt.tld\libraries\lithium\data\source\Database.php(227): lithium\core\Object->invokeMethod('_execute', Array) #4 F:\phpweb\li.tlt.tld\libraries\lithium\core\Object.php(2 in F:\phpweb\li.tlt.tld\libraries\lithium\data\source\database\adapter\MySql.php on line 343

Exporter::_update is giving bad results with embedded documents

I have created a little test for anyone willing to check it out:
http://pastium.org/view/4a35aeb1bf856634d7185df970bc7981

Basically, after saving the second list of documents in "otherDocs", the content of "docs" is inserted inside the parent document which we don't want...

I've been looking at the _update method inside Exporter.php and it seems the results it's giving for embedded documents are not really appropriate.

Hope this helps!

(Mongo version 1.8.2)

Model::first() is returning an array, not an object

I believe the following is meant to return an instance of lithium\entitty\Document, it is however an array. Using MongoDB. Another on irc also said they had experienced the same. It may only be under certain conditions?

The following test fails. MockArtists is a regular model.

namespace app\tests\cases\models;

use app\tests\mocks\MockArtists;

class BugTest extends \lithium\test\Unit {


    public function setUp(){
        MockArtists::remove();
    }

    public function testSignup(){

        $artist = MockArtists::create(array('name' => 'Jacko', 'act' => array('singer', 'dancer')));
        $artist->save();
        $artist = MockArtists::first();
        $this->assertTrue(is_object($artist));
        $this->assertEqual('Jacko', $artist->name); 

    }
}

PostgreSql Query fails with Aliases

$query = self::first($entity->data('id'), array('fields'=>'role_id'));

Debug Warning: /pwi2/libraries/lithium/data/source/database/adapter/PostgreSql.php line 395 - pg_query(): Query failed: ERROR: invalid reference to FROM-clause entry for table "users"
LINE 1: SELECT Users.role_id FROM "users" AS "Users" LIMIT 1;
^
HINT: Perhaps you meant to reference the table alias "Users".

Constraint Complex Array

Assertion 'assertEqual' failed in lithium\tests\cases\data\source\DatabaseTest::testRenderArrayJoinConstraintComplexArray() on line 730:
expected: 'SELECT * FROM {comments} AS {Comments} LEFT JOIN {posts} AS {Post} ON ({Comment}.{post_id} <= {Post}.{id} && {Comment}.{post_id} => {Post}.{id}) WHERE Comment.id = 1;'
result: 'SELECT * FROM {comments} AS {Comments} LEFT JOIN {posts} AS {Post} ON {Comment}.{post_id} <= {Post}.{id} WHERE Comment.id = 1;'

@link agborkowski@e9866eb

checkbox doesn't keep it's value

<?= $this->form->field('tos_accept', array('type' => 'checkbox')); ?>
It create properly two field, a hidden and a checkbox. After form submit the bounded value is '1' (with default options).

In Form::checkbox() method:

if (!isset($options['checked'])) {
    if ($this->_binding && $bound = $this->_binding->data($name)) { // $bound === '1'
        $options['checked'] = !($bound === $default);  // $default === '1'  =>  ($default === $bound) is true always, so checkbox won't be checked
    } else { // $bound === ''
        $options['checked'] = ($scope['value'] != $default);
    }
}

With default options the checkbox doesn't keep it's checked value.
$options['checked'] = ($bound === $default); with this change it works properly

Test case:

//$record = new Record(array('model' => $this->_model, 'data' => array('foo' => true)));
$record = new Record(array('model' => $this->_model, 'data' => array('foo' => '1')));
$this->form->create($record);

$result = $this->form->checkbox('foo', array('value' => '1'));
$this->assertTags($result, array(
    array('input' => array('type' => 'hidden', 'value' => '', 'name' => 'foo')),
    array('input' => array(
        'type' => 'checkbox', 'value' => '1',  'name' => 'foo',
        'id' => 'MockFormPostFoo', 'checked' => 'checked'
    ))
));

Overriding Core helpers doesn't work

When trying to override \lithium\template\helper\Form with my own app\extensions\helpers\Form, in views Lithium doesn't load my helper.

Custom Helpers do load correctly.

in app/app/extensions/helper/Form.php

please see this following gist: https://gist.github.com/1159576

what i expected

a var_dump of 'bar' and die()

what happened

Form output as normal

HTTP Response Content-Type parsing fail when no encoding

Parsing an HTTP Response with a Content-Type=application/json should store the response type as application/json.

Instead, Response->type = text/html (default constructed value)

and, parsing a Content-Type=application/json;charset=utf-8 works perfectly.

RFC: Update on embedded Document fields does not save properly (MongoDB)

Quirk in Documents on MongoDB, if you have an embedded object and you update it on the fly, lithium will not save the document changes to the database.

(Note that the keys used are merely verbose for comprehension, not what I am actually using)

$document = Model::find('first', array('conditions' => array('_id' => 'SOME_IDENTIFIER')));

$document->embedded->some_key = 'some value'; //This document already retains an 'embedded' object

$document->save(); //Does not save updated embedded field

However this works but it's a bit ugly:

$document = Model::find('first', array('conditions' => array('_id' => 'SOME_IDENTIFIER')));

$document->embedded = array('some_key' => 'some_value') + $document->embedded->to('array'); //oy, clunky

$document->save();

Incidentally so does this:

$document = Model::find('first', array('conditions' => array('_id' => 'SOME_IDENTIFIER')));

$document->embedded->some_key = 'some value';
$document->embedded = $document->embedded; //Because it makes a call to __set()

$document->save();

It seems like whenever an embedded document gets updated and the Document has save() called on it, it should take into account the changes to the embedded. When I do a dump of the updated document, the embedded does have the _updated property set properly for the embedded, but not the global document.

I should also note that this issue is probably not limited to MongoDB since it has to do with Document not properly updating itself on embedded key changes.

Find method dies during a `with` query in MySQL

If a Model::find() is run using a with array to attach associated models, and the current model doesn't match a record, the model throws an exception:

lithium\data\model\QueryException (code 1064)

SELECT * FROM `posts` AS `Posts` LEFT JOIN `comments` AS `Comments` ON `Posts`.`id` = `Comments`.`post_id` WHERE YEAR(date) = 2011 AND MONTH(date) = 7 AND DAY(date) = 12 AND published = 1 AND Posts.id IN ();: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1

It appears that two queries are processed. Attaching a filter on _execute in Connections.php, it shows the first query grabs the ID value, and the second is the one that breaks if no ID value was returned.

Console: li3 create <Model> dies unexpectedly.

Overview

when you run li3 create user (or anything similar) it creates the controllers and models as expected, but fails when creating the model test.

Problem

The model test introspects the previously created model through the ReflectionClass but in there the problem occurs: it seems that no environment is defined at the moment.

This only happens when environments in the connections files are defined. A default one works fine.

Example config:

Connections::add('default', array(
    'production' => array(
        'type'     => 'database',
        'adapter'  => 'MySql',
        'host'     => 'db1.application.local',
        'login'    => 'secure',
        'password' => 'secret',
        'database' => 'app-production'
    ),
    'development' => array(
        'type'     => 'database',
        'adapter'  => 'MySql',
        'host'     => 'localhost',
        'login'    => 'root',
        'password' => '',
        'database' => 'app'
    )
 ));

Calling li3.bat create user results in

Users created in app\models.
UsersController created in app\controllers.
No adapter set for configuration in class `lithium\data\Connections`.

Possible Solution

It seems that there is a bug in how the console handles environments and deals with configurations that have more than one defined.

'double' output on errors

when there's an unhandled exception in the layout/view the produced output until that point is shown before the output of the errors controller.

to reproduce: turn on errors (bootstrap), write <?= $this->nonexist->foo(); ?> in your layout/view.

Session: cookie adapter with hmac strategy fails after write

This ticket has been moved vom rad-dev.org to here (originally reported by scoates).

What happened:

  • HMAC tampering RuntimeException after a Session::write()

What was expected:

  • the signature cookie should change to reflect the new data after a Session::write()

Reproduce code (controller; run this twice from the same browser session):

try {
    $read = Session::read('t');
} catch (MissingSignatureException $e) {
    // ignore; we're starting a new session
    $read = false;
}
if (!$read) {
    Session::write('t', time());
}

Model::first() is returning an array, not an object

I believe the following is meant to return an instance of lithium\entitty\Document, it is however an array. Using MongoDB. Another on irc also said they had experienced the same. It may only be under certain conditions?

The following test fails. MockArtists is a regular model.

namespace app\tests\cases\models;

use app\tests\mocks\MockArtists;

class BugTest extends \lithium\test\Unit {


    public function setUp(){
        MockArtists::remove();
    }

    public function testSignup(){

        $artist = MockArtists::create(array('name' => 'Jacko', 'act' => array('singer', 'dancer')));
        $artist->save();
        $artist = MockArtists::first();
        $this->assertTrue(is_object($artist));
        $this->assertEqual('Jacko', $artist->name); 

    }
}

Helper.php _strings and li3_design _strings conflict.

The image is not displayed because of cache of _context of Helper.php.

dummy->image(200, 200); //OK ?> html->image("/photos/view/test.jpg", array('width'=> 100));//NG ?>
html->image("/photos/view/test.jpg", array('width'=> 100));//OK ?> dummy->image(200, 200); //NG ?>

Auth _validators generate wrong cond (r2)

+ Hello i'm agborkowski and i have problem with Auth class

  • When i use in Auth::config filters witch md5 for my password and password => false in validator (thanks for
  • @nateabele #56 (comment))
  • Auth::check < Form::check generate condition witchout password
  • SELECT * FROM users AS Users WHERE enable = 't' AND login = 'ab2' LIMIT 1;
  • if u want look of debug from my problem u can check pastium code and comments
  • this workaround works for me gr8 :
  • // security/adapters/Fromm.php
  • $conditions = $this->_scope + $data; // + array_diff_key($data, $this->_validators);
  • and conditions generate right..
    <<HEAD
    http://pastium.org/view/86337d69c1a2c64efb874a50f9980900

Renaming app directory to 1234 breaks Auth

Howdy folks,

I'm opening a ticket while digging deeper, 'cause maybe someone will have a clue faster.

The problem, as I see it

Taken a fresh app and directories layout, and renaming the main app/ directory to 1234 (or any integer), break Auth.

Environment details

I'm using PHP 5.3.6, nginx, and all tests are green

Background

I'm deploying an app using Capistrano and a home made gem for Lithium easy deployments.
Capistrano, by default, creates a directory layout as follows:

[deploy_to]
[deploy_to]/releases
[deploy_to]/releases/20080819001122
[deploy_to]/releases/...
[deploy_to]/shared
[deploy_to]/shared/log
[deploy_to]/shared/pids
[deploy_to]/shared/system
[deploy_to]/current -> [deploy_to]/releases/20100819001122

Each time you deploy, a new directory will be created under the “releases” directory, and the new version placed there. Then, the “current” symbolic link will be updated to point to that directory. (For now, don’t worry about the shared directory; we’ll get to that eventually.)

The web server's document root should be set to the [deploy_to]/current directory.

That means, the app/ directory name is a timestamp, which break things right now.

A "maybe" related ticket: http://dev.lithify.me/lithium/tickets/view/367

Custom command is not finding models

Weirdly enough it finds other custom classes in my lithium app

Here is my custom command

namespace golf\extensions\command;

use golf\models\News;

class Tools extends \lithium\console\Command {

    public function test() {
        $news = News::all();
    }
}   

I know that the model is fine because I can call it from a controller example

namespace golf\controllers;

use golf\models\News;

class NewsController extends ApplicationController {

    public function index() {
        $news = News::all();
        return compact('news');
    }
}   

Here is my stack trace... Sorry I didn't have enough time to write a unit test for this.

li3 tools test

Fatal error: Class 'golf\models\News' not found in /Users/MackstarMBA/Sites/golf/extensions/command/Tools.php on line 0

Call Stack:
    0.0037     341636   1. {main}() /Users/MackstarMBA/Sites/libraries/lithium/console/lithium.php:0
    0.2552    3630924   2. lithium\console\Dispatcher::run() /Users/MackstarMBA/Sites/libraries/lithium/console/lithium.php:34
    0.2553    3632572   3. lithium\core\StaticObject::_filter() /Users/MackstarMBA/Sites/libraries/lithium/console/Dispatcher.php:103
    0.2553    3632808   4. lithium\console\{closure}() /Users/MackstarMBA/Sites/libraries/lithium/core/StaticObject.php:119
    0.2928    3787672   5. lithium\core\StaticObject::invokeMethod() /Users/MackstarMBA/Sites/libraries/lithium/console/Dispatcher.php:99
    0.2928    3787700   6. lithium\console\Dispatcher::_call() /Users/MackstarMBA/Sites/libraries/lithium/core/StaticObject.php:75
    0.2928    3788780   7. lithium\core\StaticObject::_filter() /Users/MackstarMBA/Sites/libraries/lithium/console/Dispatcher.php:192
    0.2929    3790136   8. lithium\util\collection\Filters::run() /Users/MackstarMBA/Sites/libraries/lithium/core/StaticObject.php:126
    0.2929    3791964   9. {closure}() /Users/MackstarMBA/Sites/libraries/lithium/util/collection/Filters.php:183
    0.2930    3791964  10. lithium\util\collection\Filters->next() /Users/MackstarMBA/Sites/golf/config/bootstrap/console.php:15
    0.2930    3791992  11. lithium\console\{closure}() /Users/MackstarMBA/Sites/libraries/lithium/util/collection/Filters.php:202
    0.2930    3792020  12. lithium\console\Command->__invoke() /Users/MackstarMBA/Sites/libraries/lithium/console/Dispatcher.php:189
    0.2930    3792164  13. lithium\core\Object->invokeMethod() /Users/MackstarMBA/Sites/libraries/lithium/console/Command.php:108
    0.2930    3792192  14. golf\extensions\command\Tools->test() /Users/MackstarMBA/Sites/libraries/lithium/core/Object.php:167

Add a notice to home when compiled `--with-curlwrappers`

If php is compiled with curl wrappers, then in the read method...

$meta = stream_get_meta_data($this->_resource);

can return an array containing arrays

'wrapper_data' => 
    array
      'headers' => 
        array
          ...
      'readbuf' => resource(21, stream)

which seems to cause the later call to

join("\r\n", $meta['wrapper_data'])

to throw an exception.

If i compile without curlwrappers then all the lithium tests pass as expected, if its compiled then I get a bunch of exceptions from the join on line 99 in lithium\net\http\Context::read().

net/http/Request: couldnt handle multiple equivalent keys since f453b39b1ef13684ce2e78f33adc98f50e0a77be

The transition from params to query i a quite good idea.

But changing to a "normal" key=value array cause me an unwanted behavior. Request wouldnt accept multiple equivalent keys with different values.
Example: A Solr Filter query, with multiple "fq" keys and different values for a multi filter request..

http://url.tld/select?q=bla&fq=field1&fq=field2

the current Code overwrites the first key/value pair

Cannot add runtime configuration in g11n extract command

$name = $this->in('Please choose a configuration or hit [enter] to add one:', array(
'choices' => array_keys($configs)
));

Command::in() method default "quit" value is "q" not enter, so the user goes nowhere by pressing enter...
It should be changed, otherwise it cannot use the proper way (Catalog needs a Code property hardcoded in the application).

Request->to('url')

Using IIS 7.5 on Windows7 with rewriting enabled.

While retrieving the request url via $params['request']->to('url') in a run filter to Dispatcher it throws a notice "Array to string conversion in libraries\lithium\util\String.php on line 245". By disabling notices, the returning url contains array in place of a query string.

This only occurs when the querystring is empty, thus sending an empty array as $options['query'] to \lithium\net\htttp\Request::to($format, $options).

Line 163 makes sure $options['query'] is a string, but only if it's non-empty.

if ($options['query'] && is_array($options['query'])) {
    $options['query'] = $this->queryString($options['query']);
}

Removing the first condition resolved my problem.

Tests through browser are using the development connection

I have the following connections being set

Connections::add('default', array(
    'production' => array(
        'type' =>  'MongoDb',
        'database' => 'golf_prod',
        'host' => 'localhost'
    ),
    'development' => array(
        'type' =>  'MongoDb',
        'database' => 'golf_dev',
        'host' => 'localhost'
    ),
    'test' => array(
        'type' =>  'MongoDb',
        'database' => 'golf_test',
        'host' => 'localhost'
    ),
));

Within the test Environment::get() correctly returns 'test'. When using for example a User model User::connection()->_config['database'] is golf_dev when it should be golf_test. Of course the data is being stored in golf_dev.

Through the console the expected result is correct. User::connection()->_config['database'] returns golf_test and the data is stored in the test database.

quoted fields...

This query @code http://pastium.org/view/86337d69c1a2c64efb874a50f98a683a generate that:

SELECT Aros.id, Aros.parent_id, Aros.model, Aros.foreign_key, Aros.alias FROM "aros" AS "Aros" LEFT JOIN "aros" AS "Aros0" ON "Aros"."lft" <= "Aros0"."lft" AND "Aros"."rght" <= "Aros0"."rght" WHERE "Aros0"."model" = 'Roles' AND Aros0.foreign_key = 7 ORDER BY "Aros"."lft" DESC LIMIT 1;

One way standard and more clarity fields should be quoted

why SELECT fields are unquote but after FROM fields are quoted ? Where can i add quotes to SELECT fields ?

Adapter are not responsible for that.

$_schema not working, ObjectId is saved as string

I tried to do Model::update() on a record and saving as an object, but the _id is saved as string and not ObjectId.

friends._id should be an ObjectId and not a string.

Here are the codes:

Model - http://pastium.org/view/4a35aeb1bf856634d7185df9706ebca3
Controller - http://pastium.org/view/4a35aeb1bf856634d7185df9706eec98
data - http://pastium.org/view/4a35aeb1bf856634d7185df9706ed290

Though I got this working using filter, I'm quite sure this will work using $_schema.

Thanks & Keep Rocking!

`Model::save()` should only save modified values

It's a feature request:

It would be nice to save only changed values (auto) instead of the whole entity.
If I want to change only a certain fields I need to disable validation because another validation rules fail (e.g. password hashing, rule depends on form value, hashed after validation, pass is changeable so rule cannot depends on create or update event), so allow partial validation. It would be nicer to pass events to validation. By default only validates changed fields.

I wrote a little Model extension:

<?php

namespace app\extensions\data;

class Model extends \lithium\data\Model {

    public static function __init() {
        static::_isBase(__CLASS__, true);
        parent::__init();
    }

    public function save($entity, $data = null, array $options = array()) {
        if ($data) {
            $entity->set($data);
        }

        $options += array(
            'validate' => true,
            'events' => $entity->exists() ? 'update' : 'create',
            'whitelist' => array_keys($entity->modified())
        );

        $whitelist = (array) $options['whitelist'];

        if ($rules = $options['validate']) {
            if (!is_array($rules)) {
                $rules = $this->validates;
            }

            $rules  = array_intersect_key($rules, array_flip($whitelist));
            $params = is_array($rules) ? compact('rules') : array();
            $params['events'] = $options['events'];

            if (!$entity->validates($params)) {
                return false;
            }

            $options['validate'] = false;
        }

        $options['whitelist'] = array_intersect($whitelist, array_keys($this->_schema)); 

        return parent::save($entity, null, $options);
    }
}

?>

Test fail on CollectionTest::testCollectionSort()

The new "sort" method on collections recently added to master fails on invalid call string

Assertion 'assertFalse' failed in lithium\tests\cases\util\CollectionTest::testCollectionSort() on line 301:

expected: false
result: array (
  '_config' => 
  array (
    'init' => true,
  ),
  '_methodFilters' => 
  array (
  ),
)

Looks like the sort() method needs to return false or the test needs to be modified so that it doesn't use assertFalse()

The possibility of throwing an exception on an invalid sort() call might be a solution as well

Undefined variable: request #manual

What happened:

  • im taken eg. from @link http://lithify.me/docs/manual/02_lithium_basics/02_filters.wiki
    /.../
    if (isset($ctrl->publicActions) && in_array($params['action'], $ctrl->publicActions)) {
    return $ctrl;
    }
    return function() use ($request) {
    ^^^^^^^^^
    return new Response(compact('request') + array('location' => '/users/login'));
    };
    /.../
  • put this to auth.php (full code) @link http://pastium.org/view/4a35aeb1bf856634d7185df9709628ad
  • every request to app throw notice
    -( ! ) Notice: Undefined variable: request in /home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/auth.php on line 32
  • Catchable fatal error: Closure object cannot have properties in /home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/action.php on line 61

i reset to HEAD action.php and modify filter:

https://gist.github.com/1064588

now its work better but
im not sure from come $request is.
$request is set by Auth::check('default', $this->request); in UsersController->login() ?
but why eg from manual don't wanna work without my isset workaround.. ?

call_user_func() and call-time pass-by-reference

The pull request #35 from @jmccaffrey42 introduced a Warning
Parameters for call_user_func() should not be passed by reference as it was Deprecated since PHP 5.3

Deprecated: Call-time pass-by-reference has been deprecated in /usr/local/lib/li3/libraries/lithium/util/Collection.php on line 367

I small workaround could be

call_user_func_array($sorter, array(&$this->_data));

But not sure that's a good idea... Needs a cleaner solution

crash after unslash error.php

Notice: Undefined variable: render in /home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/errors.php on line 29
Call Stack

Time Memory Function Location

1 0.0001 323268 {main}( ) ../index.php:0
2 0.0002 323528 require( '/home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap.php' ) ../index.php:21
3 0.0336 839588 require( '/home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/errors.php' ) ../bootstrap.php:91

( ! ) Catchable fatal error: Argument 2 passed to lithium\core\ErrorHandler::apply() must be an array, string given, called in /home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/errors.php on line 32 and defined in /home/agborkowski/Sites/holicon/pwi2/libraries/lithium/core/ErrorHandler.php on line 278
Call Stack

Time Memory Function Location

1 0.0001 323268 {main}( ) ../index.php:0
2 0.0002 323528 require( '/home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap.php' ) ../index.php:21
3 0.0336 839588 require( '/home/agborkowski/Sites/holicon/pwi2/app/config/bootstrap/errors.php' ) ../bootstrap.php:91
4 0.0344 852732 lithium\core\ErrorHandler::apply( ) ../errors.php:32

Classes with no or too weak test coverage

About

This is a list of all classes which have no or too weak test coverage at the moment. All classes need to have a test coverage of 85% or more to be labeled as "well tested". This list will be updated as soon as tests are merged into the master branch. Classes flagged with no test don't have a test class created, while those flagged with has test and n/a coverage have an empty class body.

The following list was created with the lithium_qa tool li3 covered:

No Coverage:

no test | n/a | lithium\test\Filter
no test | n/a | lithium\test\filter\Coverage
no test | n/a | lithium\test\filter\Profiler
no test | n/a | lithium\net\Socket
no test | n/a | lithium\g11n\catalog\adapter\Memory
no test | n/a | lithium\data\source\Mock
no test | n/a | lithium\data\source\mongo_db\Result
no test | n/a | lithium\data\source\database\Result
no test | n/a | lithium\data\source\database\adapter\sqlite3\Result
no test | n/a | lithium\data\source\database\adapter\my_sql\Result
no test | n/a | lithium\data\model\Relationship
no test | n/a | lithium\console\command\G11n
has test | n/a | lithium\test\Controller
has test | n/a | lithium\analysis\Debugger

Too weak coverage:

has test | 62.07% | lithium\data\Collection
has test | 76.25% | lithium\data\Entity
has test | 77.78% | lithium\data\Source
has test | 80.42% | lithium\data\source\MongoDb
has test | 46.88% | lithium\data\collection\DocumentArray
has test | 39.06% | lithium\data\collection\DocumentSet
has test | 71.21% | lithium\data\collection\RecordSet

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.