I'm looking to use Lithium framework to build my application config interface as I like its minimal approach and the document-store (i.e. Mongodb) centric model.
However, (and I know its not quite released yet), there is little-to-no information, tutorials or examples out there to move you on from the simple blog tutorial.
What I am trying to do now is build an app that will show me the collections I have in Mongodb, and then let me work with which ever collection I choose. I can't seem to figure out:
a) how would I build a model that enumerates the collections - preferably according to my internal naming scheme,
b) how do I break the convention model so I can specify the name of the collection to use?
I think there are two things i'm struggling with to answer these two questions - perhaps a fundamental misunderstanding of how to move a model in MVC beyond the simple collection-model-controller-view examples, and secondly, the actual process of telling the mongo datasource what collection to use.
any pointers or examples, gratefully received.
Chris
update::
So I figured out how to set the collection - for reference you can set source in the $_meta array like this:
protected $_meta = array(
'source' => '<<collectionName>>'
);
still no idea how to use a Model that will list me all the collections I have in my DB though. Any ideas how to do that from a philosophical and also technological manner?
further update::
so I have got a bit further thanks to the comments below. At least I might now be able to re-phrase the question a bit. I can define my model something like this:
<?php
namespace app\models;
use lithium\data\Model;
class Posts extends \lithium\data\Model{
protected $_meta = array('source' => false);
public function testcolls(){
return (self::connection()->sources());
}
}
?>
then in my view I can use:
<?php foreach ($post->testcolls() as $coll): ?>
<h2><?=$coll ?></h2>
<?php endforeach; ?>
that works - however, what I really want to do is not create a 'testcolls' method in my Model but as Medhi suggested below, I need to override the find method. I can't seem to figure out how to do that and what it would need to return. The docs are not too clear on this.
final update
based on the comment below and a bit of experimentation, I came up with the following that works for being able to call find with a collection as a parameter.
model:
class Dataqueues extends \lithium\data\Model{
protected $_meta = array('source' => false);
public static function find($filter, array $options = array()) {
if (isset($options['collection'])){
self::meta('source', $options['collection']);
}
return parent::find('all',$options);
}
}
controller:
class DataqueuesController extends \lithium\action\Controller {
public function index() {
$dataqueues = Dataqueues::find('all',array('limit'=>20,'collection'=>'W501'));
return compact('dataqueues');
}
}
getting a model that returns a list of collections was also pretty simple in the end:
class Collections extends \lithium\data\Model{
protected $_meta = array('source' => false);
public static function find($filter, array $options = array()) {
return self::connection()->sources();
}
}
note that the controller won't support options or filters.
Nothing holds you from having a Collections
Model, where you set $_meta['source'] = false
to prevent Lithium from looking for a Collection in your database named collections.
In this model, you can call YourModel::connection()->sources()
to list all your Mongo Collections.
Docs for sources(): http://li3.me/docs/lithium/data/source/MongoDb::sources(). Basically it calls listCollections()
on a MongoDB instance http://php.net/manual/en/mongodb.listcollections.php
You can override your Model::find() method to return the list of collections, instead the list of documents, or pass the collection as a param Collections::find('all', array('conditions' => ..., 'collection' => 'foo'))
... or wathever you want :-)
Lithium is designed to don't force that much on you !