PHP code example of phpixie / orm

1. Go to this page and download the library: Download phpixie/orm library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

phpixie / orm example snippets



$slice = new \PHPixie\Slice();
$database = new \PHPixie\Database($slice->arrayData(array(
    'default' => array(
        'driver' => 'pdo',
        'connection' => 'sqlite::memory:'
    )
)));
$orm = new \PHPixie\ORM($database, $slice->arrayData(array(
    // We will add some configuration later
)));

$repository = $orm->repository('article');

$newArticle   = $repository->createEntity();
$articleQuery = $repository->query();

// shorthands
$newArticle   = $orm->createEntity('article');
$articleQuery = $orm->query('article');

return array(
    'models' => array(
        'article' => array(
            'type'       => 'database',
            'connection' => 'default',
            'id'         => 'id'
        ),

        // you can also define embedded models
        // if you are using MongoDB,
        // more on that later
    )
);

// Saving an entity
$article->title = 'Welcome';
$article->save();

// Getting a field with a default value
$article->getField('title', 'No Title');

// Getting a >asObject();

// Deleting
$article->delete();

// Find article by name
$article = $orm->query('article')
    ->where('title', 'Welcome')
    ->findOne();

// Find by id
$article = $orm->query('article')
    ->in($id)
    ->findOne();

// Query by multiple ids
$articles = $orm->query('article')
    ->in($ids)
    ->findOne();

// Actually the in() method can be used
// to also 5)
    ->find();

// Ordering
// Supports multiple fields
$articles
    ->orderAscendingBy('name')
    ->orderDescendingBy('id');

// Limit and offset
$articles
    ->limit(1)
    ->offset(2);

// It continues in the same way
// as in the Database component

$articles = $orm->query('article')
    ->where('name', 'Welcome')
    ->or(function($query) {
        $querty
            ->where('viewsTotal', '>', 2)
            ->or('viewsDone', '<', 5);
    })
    ->find();

// Alternative syntax for
// nested conditions
$articles = $orm->query('article')
    ->where('name', 'Welcome')
    ->startWhereConditionGroup('or')
        ->where('viewsTotal', '>', 2)
        ->or('viewsDone', '<', 5)
    ->endGroup()
    ->find();

// Iterate over it
// Note: this can be done only once
foreach($articles as $article) {
    // ...
}

// Convert into an array
// to allow multiple iterations
$articles = $articles->asArray();

// Convert it into plain objects,
// useful for serializing
$data = $articles->asArray(true);

// Convert it into associative array
$data = $articles->asArray(true, 'id');

// To load relationships eagerly
// just pass their names to find() or findOne()
$articles = $query->find(array(
    'author',
    'tags'
));

// You can also preload nested relationships
// using the dot notation
$articles = $query->find(array(
    'author.friends',
));

// Count matched items
$count = $articleQuery->count();

// Delete matched items
$articleQuery->delete();

// Update a field in all matched items
$articleQuery
    ->update(array(
        'status' => 'published'
    ));

// Some more advanced updating
$articleQuery
    ->getUpdateBuilder()
        ->increment('views', 1)
        ->set('status', 'published')
        // Removing a field in MongoDB
        ->remove('isDraft')
        ->execute();

class UserEntity extends \PHPixie\ORM\Wrappers\Type\Database\Entity
{
    // Get users full name
    public function fullName()
    {
        // You can access the actual entity
        // Using $this->entity;
        return $this->entity->firstName.' '.$this->entity->lastName;
    }
}

class UserQuery extends \PHPixie\ORM\Wrappers\Type\Database\Query
{
    // Extending queries is useful
    // For adding bulk conditions
    public function popular()
    {
        // Access query with $this->query
        $this->query
            ->where('viewsPerDay', '>', 5000)
            ->orWhere('friendCount' '>=', 100);
    }
}

// You will rarely need to extend repositories
class UserRepository extends \PHPixie\ORM\Wrappers\Type\Database\Repository
{
    // Overriding a save method
    // can be used for validation
    public function save($entity)
    {
        if($entity->getField('name') === null) {
            throw new \Exception("You must provide a user name");
        }

        $this->repository->save($entity);
    }
}

class ORMWrappers extends \PHPixie\ORM\Wrappers\Implementation
{
    // Model names of database entities to wrap
    protected $databaseEntities = array(
        'user'
    );

    // Model names of queries to wrap
    protected $databaseQueries = array(
        'user'
    );

    // Model names of repositories to wrap
    protected $databaseRepositories = array(
        'user'
    );

    // Model names of embedded entities to wrap
    // We cover them later in this manual
    protected $embeddedEntities = array(
        'post'
    );

    // Provide methods to build the wrappers

    public function userEntity($entity)
    {
        return new UserEntity($entity);
    }

    public function userQuery($query)
    {
        return new UserQuery($query);
    }

    public function userRepository($repository)
    {
        return new UserRepository($repository);
    }

    public function postEntity($entity)
    {
        return new PostEntity($entity);
    }
}

$wrappers = new ORMWrappers();
$orm = new \PHPixie\ORM($database, $slice->arrayData(array(
    // Configuration options
)), $wrappers);

return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        array(
            'type'  => 'manyToMany',
            'left'  => 'article',
            'right' => 'tag'
        )
    )
);

// Lets say we have a one to many relationship
// between categories and articles

// Finding all categories with
// at lest one article
//
// Note that you use the property name,
// and not the model name here.
// You can modify property names
// in your config file, more on them later
$categoryQuery->relatedTo('articles');

// or all articles with a category
$articleQuery->relatedTo('category');

// Use logic operators
// like with where()
$articleQuery->orNotRelatedTo('category');

// Find categories related to
// particular articles
$categoryQuery->relatedTo('articles', $articles);

// $articles can be an id of an article,
// an article entity or an article query,
// or an array of them, e.g.
$categoryQuery->relatedTo('articles', $articleQuery);
$categoryQuery->relatedTo('articles', $someArticle);
$categoryQuery->relatedTo('articles', 4); //id

// Will find all categories related
// to any of the defined articles
$categoryQuery->relatedTo('articles', array(
    4, 3, $articleQuery, $articleEntity
));


// Relationship conditions

// Find categories related to articles
// that have a title 'Welcome'
$categoryQuery->relatedTo('articles', function($query) {
    $query
        ->where('title', 'Welcome');
});

// Or a shorthand
// You'll be using this a lot
$categoryQuery->where('articles.title', 'Welcome');

// You can use the '.'
// to go deeper in the relationships

// Find categories that have at least one article
// written by the author 'Dracony'
$categoryQuery->where('articles.author.name', 'Dracony');

// Or combine the verbose approach
// with the shorthand one
$categoryQuery->relatedTo('articles.author', function($query) {
    $query
        ->where('name', 'Dracony');
});

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'  => 'oneToMany',
            'owner' => 'category',
            'items' => 'article',

            // The following keys are optional
            // and will fallback to the defaults
            // based on model names

            'ownerOptions' => array(
                // the name of the property added to the owner
                // e.g. $category->articles();
                //
                // defaults to the plural of the item model
                'itemsProperty' => 'articles'
            ),

            'itemsOptions' => array(

                // the name of the property added to items
                // e.g. $article->category()
                //
                // defaults to the owner model
                'ownerProperty' => 'category',

                // the field that is used to link items
                // defaults to '<property>Id'
                'ownerKey' => 'categoryId',

                // The default behavior is to set
                // the field defined in ownerKey to null
                // when the owner gets deleted
                //
                // changed it to 'delete' to delete
                // the articles when their category is deleted
                'onOwnerDelete' => 'update'
            )
        )
    )
);

// Using with entities

// Getting articles category
// The property names used are
// the ones defined in the config
$category = $article->category();

// Get category articles
$articles = $category->articles();

// Add article to category
$category->articles->add($article);

// Remove article from category
$category->articles->remove($article);

// Remove categories from all articles
$category->articles->removeAll();

// Or you can do the same
// from the article side
$article->category->set($category);
$article->category->remove();

// You can use queries, ids and arrays
// anywhere you can use an entity.
// This allows performing bulk operations faster

// Assign first 5 articles
// to a category
$articleQuery
    ->limit(5)
    ->offset(0);
$category->articles->add($articleQuery);

// Assign articles to a category
$articlesQuery->category->set($category);

// Assign articles to a category with a single
// database call, without the need to select
// rows from database
$categoryQuery->where('title', 'PHP');
$articlesQuery->category->set($category);

// Unset categories for all articles
$orm->query('aricle')
    ->category->remove();

// Unset only some ctaegories
$categoryQuery->where('title', 'PHP');
$orm->query('aricle')
    ->category->remove($category);

// You can also use query properties
// for query building
$categoryQuery = $articleQuery
    ->where('title', 'Welcome')
    ->categories();

// is the same as
$categoryQuery = $orm->query('category')
    ->relatedTo('articles.title', 'Welcome');

// or
$articleQuery->where('title', 'Welcome');
$categoryQuery = $orm->query('category')
    ->relatedTo('articles', $articleQuery);

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'  => 'oneToOne',
            'owner' => 'worker',
            'item' => 'task',

            // The following keys are optional
            // and will fallback to the defaults
            // based on model names

            'ownerOptions' => array(
                // the name of the property added to the owner
                // e.g. $worker->task();
                //
                // Unlike manyToMany this uses
                // a singular case by default
                'itemProperty' => 'task'
            ),

            // note it's 'itemOptions' here
            // but 'itemsOptions' for One To Many
            'itemOptions' => array(

                // the name of the property added to items
                // e.g. $task->worker()
                'ownerProperty' => 'worker',

                // the field that is used to link items
                // defaults to '<property>Id'
                'ownerKey' => 'workerId',

                // The default behavior is to set
                // the field defined in ownerKey to null
                // when the owner gets deleted
                //
                // changed it to 'delete' to delete
                // the task when its worker is deleted
                'onOwnerDelete' => 'update'
            )
        )
    )
);

// Using with entities

// Getting task worker
$worker = $task->worker();

// Getting worker tasks
$worker = $task->worker();

// assign worker to a task
$task->worker->set($worker);
$worker->task->set($task);

// Unset task
$task->worker->remove();
$work->task->remove();

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'  => 'manyToMany',
            'left'  => 'article',
            'right' => 'tag',

            // The following keys are optional
            // and will fallback to the defaults
            // based on model names

            'leftOptions' => array(
                'property' => 'tags'
            ),

            'rightOptions' => array(
                'property' => 'articles'
            ),

            // depends on property names
            // defaults to <rightProperty><leftProperty>
            'pivot' => 'articlesTags',


            'pivotOptions' => array(

                // defaults to the connection
                // of the left model
                'connection' => 'default',

                // columns in pivot table
                // default to '<property>Id'
                'leftKey'  => 'articleId',
                'rightKey' => 'tagId',
            )
        )
    )
);

// Add
$article->tags->add($tag);

// Remove a particular tag
$article->tags->remove($tag);

// Remove all tags from article
$article->tags->removeAll();

// Remove all tags from multiple articles
$orm->query('article')
    ->where('status', 'published')
    ->tags->removeAll();

// Construct a tag query from article query
$tagQuery = $orm->query('article')
    ->where('status', 'published')
    ->tags();

// Everything else can be used
// in the same way as categories
// in the one-to-many examples

// Link multiple articles
// to multiple tags in one go
$articleQuery->tags->add($tagQuery);

return array(
    'models' => array(

        // Some database models
        'article' => array(),
        'topic'   => array(),

        // Configuring an embedded model
        'author' => array(
            'type' => 'embedded'
        ),
    ),

    'relationships' => array(
        array(
            'type'  => 'embedsOne',
            'owner' => 'article',
            'item'  => 'author'
        ),

        array(
            'type'  => 'embedsOne',
            'owner' => 'topic',
            'item'  => 'author'
        ),
    )
);

// Embedded entities cannot be saved on their own.
// Instead you just save the database entity
$article->author()->name = 'Dracony';
$article->save();

// Getting the parent model
// Conditions are specified as usual
$articleQuery
    ->where('author.name', 'Dracony');

// To specify a subdocument condition
// use a '>' separator.
//
// This will 

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'  => 'embedsOne',
            'owner' => 'article',
            'item'  => 'author',

            // The following keys are optional
            // and will fallback to the defaults
            // based on model names

            'ownerOptions' => array(
                // the name of the property added to the owner
                // e.g. $article->author();
                //
                // Defaults to item model name
                'property' => 'task',
            ),

            'itemOptions' => array(

                // Dot separated path
                // to the document within owner
                //
                // Defaults to owner property name
                'path' => 'author'

                // You can use nested paths
                // e.g. 'authors.editor'
            )
        )
    )
);

// get author from article
$author = $article->author();

// get author owner
$article = $author->owner();

// remove author
$article->author->remove();

// Set an author
$article->author->set($author);

// Check if an author is set
$article->author->exists();

// Create and set new author
$author = $article->author->create();

// Create with data
$author = $article->author->create($data);

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'   => 'embedsMany',
            'owner'  => 'topic',
            'items'  => 'reply',

            // The following keys are optional
            // and will fallback to the defaults
            // based on model names

            'ownerOptions' => array(
                // the name of the property added to the owner
                // e.g. $topic->replies();
                //
                // Defaults to the plural
                // of the item model name
                'property' => 'replies',
            ),

            'itemOptions' => array(

                // Dot separated path
                // to the document within owner
                //
                // Defaults to owner property name
                'path' => 'replies'

                // You can use nested paths
                // e.g. 'content.replies'
            )
        )
    )
);

// Get replies iterator
$replies = $topic->replies();

// Get reply count
$topic->replies->count();

// Get reply by offset
$reply = $topic->replies->get(2);

// Create and add a reply
$reply = $topic->replies->create();

// Create reply from data
$reply = $topic->replies->create($data);

//Create reply at offset
$reply = $topic->replies->create($data, 2);

// Add reply
$topic->replies->add($reply);

// Add reply by offset
$topic->replies->add($reply, 2);

// Remove reply
$topic->replies->remove($reply);

// Remove multiple replies
$topic->replies->remove($replies);

// Remove reply by offset
$topic->replies->offsetUnset(2);

// Remove all replies
$topic->replies->removeAll();

// Check if a reply exists
$exists = $topic->replies->offsetExists(2);

// array access
$reply = $topic->replies[1];
$topic->replies[2] = $reply;

$exists = isset($topic->replies[2]);
unset($topic->replies[2]);

// Configuration
return array(
    'models' => array(
        // ...
    ),
    'relationships' => array(
        //...

        array(
            // mandatory options
            'type'  => 'nestedSet',
            'model'  => 'category',

            // Nested Set => 'rootId',

            // You can also customize the
            // relationship property names
            'parentProperty' => 'parent',
            'childrenProperty' => 'children',

            // Defaults to "all<plural of parentProperty>"
            'allParentsProperty' => 'allParents'

            // Defaults to "all<childrenProperty>"
            'allChildrenProperty' => 'allChildren'
        )
    )
);

// Move child to parent
$category->children->add($subcategory);

// or
$subcategory->parent->set($category);

// Remove child from parent
$subcategory->parent->remove();

// Remove all children from node
$category->children->removeAll();

// Find all root nodes and preload
// their children recursively.
$categories = $orm->query('category')
    ->notRelatedTo('parent') // root nodes have no parents
    ->find(array('children'));

// Get a query representing
// all children recursively
$allChildrenQuery = $category->children->allQuery();
$allChidlren = $allChildrenQuery->find();

// Same with getting all parents parents
$allParents = $category->parent->allQuery()->find();

// Find a category with name 'Trees' that is
// a descendant of 'Plants'
$query
    ->where('name', 'Trees')
    ->relatedTo('allParents', function($query) {
        $query->where('name', 'Plants');
    })
    ->find();
    
// or like this
$query
    ->where('name', 'Plants')
    ->allChildren()
        ->where('name', 'Trees')
        ->find();

$plants->children->add($trees);
$plants->children->add($flowers);

// An exception will be thrown
$plants->delete();

// move children away from the node
$plants->children->removeAll();
//now it's safe to delete
$plants->delete();

// or delete all three,
$query->in(array($plants, $trees, $flowers))->delete();