Skip to content
ActiveRecord-style Document ORM for Yii https://bitbucket.org/intel352/activedocument
PHP JavaScript
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
.idea
behaviors
drivers
schema
validators
vendors
.hgignore
.hgsub
.hgsubstate
.hgtags
Adapter.php
Behavior.php
Connection.php
Container.php
Criteria.php
DataProvider.php
Document.php
DocumentBehavior.php
Event.php
Exception.php
Form.php
MetaData.php
Object.php
README.md
Relation.php
Sort.php

README.md

ActiveDocument: Document ORM for Yii

ActiveDocument is an ORM for Yii, providing Active Record functionality for document-based storage engines. This library is functionally similar to Yii's own SQL-based Active Record class, CActiveRecord.

Current Storage Drivers

  • Memory - temporary storage using PHP memory. Good for nested documents, and testing.
  • Riak - via the Yii ext, Riiak (currently packaged in with ActiveDocument)
  • MongoDB - via PHP PECL extension

Planned Storage Drivers

  • CouchDB
  • Redis
  • SQL - may possibly add support for SQL, if only as a CActiveRecord wrapper (to enable seamlessly changing storage driver)

Requirements

  • Yii 1.1+ (Yii 1.1.7+ recommended, lower releases should be compatible, but are untested)
  • PHP 5.3+ (ActiveDocument library is namespaced, which is a PHP 5.3 feature)

Installation

Clone this repository to your protected/extensions/ directory, to use the latest available code

hg clone https://bitbucket.org/intel352/activedocument

Quick start

This quick example uses the Memory driver

protected/config/main.php:

// ...
'components' => array(
    // ...
    'conn'=>array(
        'class' => '\ext\activedocument\Connection',
        'driver' => 'memory',
    ),
    // ...
),
// ...

protected/models/Config.php:

<?php

/**
 * NOTE 1:
 * An important difference in ActiveDocument from CActiveRecord, is that you are no longer required to specify a
 * model() method within every model class that you create. ActiveDocument makes use of a PHP 5.3 feature, Late
 * Static Binding, to achieve the same purpose as CActiveRecord::model() with less redundancy.
 *
 * NOTE 2:
 * In CActiveRecord, table fields/columns are detected and made available as magic properties, which are
 * listed in the phpdoc for any model generated by Gii.
 * Since Document engines typically do not store a schema for your data, you would normally have to specify
 * every attribute as an actual class property, or via the attributeNames method.
 *
 * To reduce redundancy, a feature has been built into ActiveDocument's MetaData class, which will parse
 * your phpdoc to determine what attributes are available for a model, as well as the var type (to be used for
 * default attribute validation rules).
 *
 * @property string $name
 * @property ConfigSetting[] $options Not needed for ActiveDocument, this exists as helper phpdoc for IDE users
 */
class Config extends \ext\activedocument\Document {

    /**
     * Relations function similar to CActiveRecord, see below for an example.
     *
     * @return array
     */
    public function relations() {
        return array(
            /**
             * For CActiveRecord, a relation requires 3 values specified (type, model, foreign key).
             * ActiveDocument instead requires 2 values (type, model). A foreign key is no longer needed, as related
             * documents have their primary key stored into the parent document.
             *
             * If you specify the named parameter, 'nested', as true, the related document[s] will have copies
             * stored directly into this model. So in this specific example, if 4 ConfigSetting instances were saved
             * to the 'options' relation, a copy of each would be stored within the Config instance in the data
             * engine.
             */
            'options'=>array(self::HAS_MANY, 'ConfigSetting', 'nested'=>true),
        );
    }

}

protected/models/ConfigSetting.php:

<?php

/**
 * ConfigSetting
 *
 * We have not specified any relations in this model, since it's intended to be nested within any parent relation
 *
 * @property string $name Setting name
 * @property mixed $value
 */
class ConfigSetting extends \ext\activedocument\Document {

    /**
     * If you do not specify which attribute carries your primary key value, then the default of '_pk' will be used.
     * If the default '_pk' is used, a primary key may be generated for you, based on the behavior of your selected
     * driver and storage engine.
     *
     * You can specify a composite key, by returning an array of attribute names.
     *
     * @return string|array
     */
    public function primaryKey() {
        return 'name';
    }

}

protected/controllers/TestController.php:

<?php

class TestController extends Controller {

    public function actionIndex() {
        $config = new Config;
        $config->name = 'Test Config';

        $cs = new ConfigSetting;
        $cs->name = 'config1';
        $cs->value = 'config1value';

        $cs2 = new ConfigSetting;
        $cs2->name = 'config2';
        $cs2->value = 'config2value';

        /**
         * Helper method to add one or more related documents.
         * Other ways to add related documents:
         * - $config->addRelated('options', array($cs, $cs2));
         * - $config->options = array($cs, $cs2);
         */
        $config->addRelated('options', $cs);
        $config->addRelated('options', $cs2);

        $config->save();

        /**
         * $config->primaryKey triggers magic call to Document::getPrimaryKey()
         */
        $pk = $config->primaryKey;

        /**
         * Perform a fresh lookup of the new config instance
         */
        $config = Config::model()->findByPk($pk);

        /**
         * Loop and print the related values
         */
        foreach($config->options as $option) {
            echo 'Option "'.$option->name.'": "'.$option->value.'"<br />';
        }
    }

}
Something went wrong with that request. Please try again.