Is Drupal support ORM? - drupal

I want using drupal for create a website.
it's very important for me to know drupal is support ORM.
and me know that drupal 7.0 and upper using orm but it's not clear for me .
any one can help me completly to know about drupal orm?
thank you.

Drupal 7 doesn't use a real ORM like Doctrine, it uses a proprietary database API as referenced on Drupal.org. So you don't write full SQL statements directly but write it using their API to assemble a query.
So yes it acts as a type of ORM but it's not one that's used outside of the Drupal project.
Examples make things easier: from https://drupal.org/node/310075
Regular SQL:
<?php
$result = db_query("SELECT uid, name, status, created, access FROM {users} u WHERE uid <> 0 LIMIT 50 OFFSET 0");
?>
Drupal DB API:
<?php
// Create an object of type SelectQuery
$query = db_select('users', 'u');
// Add extra detail to this query object: a condition, fields and a range
$query->condition('u.uid', 0, '<>');
$query->fields('u', array('uid', 'name', 'status', 'created', 'access'));
$query->range(0, 50);
?>

In addition to the database abstraction layer mentionned in Steve's answer, Drupal 7+ has provide an Entity API (completed by the Entity API module). It evolved from the the node system, completed by the CCK module, from Drupal 6. It does provide abstraction to store, query and retrieve data using objects, but the Entity API is not an ORM, and it does no attempt to be one.

Related

PHP: Doctrine & twig, many queries executed for joins

I've recently started rebuilding a old PHP application using Silex, Doctrine and Twig.
One of the main entities is "issue" (It's a issue tracking system), the issue has relations to many other entities, like "status", "Owner", "creator" , etc.
I've created all entities as doctrime ORM entities and defined all relationships.
From the controller, I fetch one "issue" and send it to the twig template like this:
$issue = $app['orm.em']->getRepository('MMW\Entity\Issue')->find($issueId);
In the twig template i can easily print out the related entities, like:
{{ issue.status.name }}
and
{{ issue.owner.name }}
It works like a charm, but when I enable logging to see what queries are send to the database like this:
$em->getConnection()
->getConfiguration()
->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
I notice that for each join, a separate query is send to the database. I would think that performance wise, one query with SQL joins would be much faster.
Should I build my application in a different way, maybe use the querybuilder in the controller to fetch the exact columns and entities I need? Or is there a way to force doctrine to build the query in a different way?
Or should I just not worry about it and leave it as is...?
You should use Doctrine fetch joins to fetch the entire entity and prevent this way to access for every field. I recommend you to read the Doctrine documentation: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#joins

Is there a way to add views bulk operations to a custom table in Drupal?

I created a custom table from a custom module using theme table; theme('table', array('header' => $table_header, 'rows' => $data)); the data that I'm showing can not be retrieved from views as i'm showing data from a 3rd-party services and this data is not saved in the database.
Is there a way to add VBO to my custom table?
Thanks.
no you cannot add vbo features that don't use the fields api of core drupal. the data from 3rd party services will needed to be imported into a field in order for BVO to work properly.
You have to declare the hook_entity_info() because:
VBO only supports entity (base or revision) table Implement hook_entity_info() and make your table an entity. Use EntityAPIController so that you don't need to write other boilerplate functions.
https://www.drupal.org/node/1282486
Yes is it possible.We can use contributed data module.This module bind the custom table data and relationship.after that we can integrate by views or create view for that data
table entity.

Viewing, adding and editing database content

I just started using Drupal and I was wondering if there is an easy way of viewing, adding or editing data from my custom database. Are there tutorials/modules which allow me to do these actions?
Sorry for the newbie question, I have no idea what to look for...
This question is perhaps more suitable for the Drupal Answers community.
Connecting a custom database
There is a great tutorial on how to connect Drupal to a separate, custom database, called How to connect to multiple databases within Drupal. In summary, it can be achieved by adding the following code into your settings.php file.
<?php
$databases = array();
$databases['default']['default'] = array(
// Drupal's database credentials go here
);
$databases['custom']['default'] = array(
// Custom database credentials go here
);
?>
Accessing custom database
First, tell Drupal that you're accessing a custom database, by inserting db_set_active('custom'); right before your query. To switch back to Drupal's default database, insert db_set_active();.
To make queries to your database, refer to a list of Database Functions. Although these functions are geared more towards a Drupal's default database, you'll find that certain functions will work on a custom database. For example, for simple SELECT queries, you may want to use the db_query.
db_query usage:
<?php
$uid = 1;
$result = db_query('SELECT n.nid, n.title, n.created
FROM {node} n WHERE n.uid = :uid', array(':uid' => $uid));
// Fetch next row as a stdClass object.
$record = $result->fetchObject();
// Fetch next row as an associative array.
$record = $result->fetchAssoc();
// Fetch data from specific column from next row
// Defaults to first column if not specified as argument
$data = $result->fetchColumn(1); // Grabs the title from the next row
// Retrieve a single value
$result->fetchField();
// Retrieve all records into an indexed array of stdClass objects.
$result->fetchAll();
// Retrieve all records as stdObjects into an associative array
// keyed by the field in the result specified.
// (in this example, the title of the node)
$result->fetchAllAssoc('title');
// Retrieve a 2-column result set as an associative array of field 1 => field 2.
$result->fetchAllKeyed();
// Also good to note that you can specify which two fields to use
// by specifying the column numbers for each field
$result->fetchAllKeyed(0,2); // would be nid => created
$result->fetchAllKeyed(1,0); // would be title => nid
// Retrieve a 1-column result set as one single array.
$result->fetchCol();
// Column number can be specified otherwise defaults to first column
$result->fetchCol($db_column_number);
// Count the number of rows
$result->rowCount();
?>
You were not clear if you need to merely manage the data, or edit the data in Drupal. If managing data is the need, use a front-end. Since you are using Drupal, you must be using PHP. If you are new to accessing databases, you may like to use PHPMyAdmin http://www.phpmyadmin.net. It may be already included with your PHP distribution if you installed PHP with MAMP, or XAMMP or one of the similar packages, but you didn't say.
Viewing, adding and editing database data in Drupal requires reading and understanding the Drupal database API https://www.drupal.org/developing/api/database

Doctrine ODM PHPCR query builder document join on relational database

I have 2 different kind of storage for a CMS that I am building. A relational database and a content repository (PHPCR + Doctrine ODM). I have a User which is stored inside the relational database and I have a Post document which is stored inside PHPCR. How would I get all posts for all active users.
Psuedo code (for demonstration purpose):
$qb = $this->createQueryBuilder('Document\Post', 'post');
$qb->join('post.user', 'user'); // We join on the table inside a relation database
$qb->where('user.active = 1');
$posts = $qb->getQuery()->execute(); // All posts objects of active users
Is this even possible? Or do I need to use 1 type of storage (relational or PHPCR) for all of my data?
Hope somebody can help me out!
You can not join over the different databases. If you do not have thousends and thousands of users, you could just map them into PHPCR. Otherwise you could do two queries. One on the ORM to fetch your user(s) and then one on PHPCR-ODM to fetch all posts that have a username that is one of the users you are looking for.
For links from ORM to PHPCR, you can use the "referenceable" feature of documents and store the UUID in the relational database. You can find a document by UUID:
$dm->find(null, $uuid)

migrating node references

I am working on a project to migrate a website from asp.net to drupal architecture. But the site content is very hierarchal and has a lot of references between entities.
for example: each content belongs to a category, and each category belongs to another category section. Now there may be another level of hierarchy even.
I am planning to make use of migrate module for migrating the database content and linking the migrated nodes via a node reference field.
But i am getting stuck with migrate module as i can't find a way to migrate the node reference field anywhere...
can anyone help me out with this...
Actually, it doesnt seem to be that hard .. in 2012. Yes, you have to keep track of source IDs versus import IDs, but the migrate module does this for you, in a neat little table. You can join that table in your source query, and update the node reference field with the nid of the .. referenced node. Ofcourse, the referenced nodes should have already been imported. If they werent, you can run an run an 'update' later and referenced nids get entered based on the latter imports too. In practice:
$query = Database::getConnection(
'default', 'mysourcedb'
)->select(
'mysourcetable','source'
)->fields('source', array(
'id',
'title',
'whatever'
'rel_rec_id'
)
);
$query->leftJoin('migrate_map_relimport','relmap','relmap.sourceid1=source.rel_rec_id');
$query->addField('relmap','destid1','rel_node_id');
The code above assumes you have a 'mysourcedb' with a 'mysourcetable' in it that refers to a 'rel_rec_id', and theres another import called RelImport that imports the rel table that rel_rec_id is refering to; it should have already run (or will run before you run an additional update). Do a migrate-status once you have the RelImport class to make sure the table exists.
To be able to make joins to the 'migrate_map_relimport' table, make sure map tables are written to the source database, not the drupal database. This is not always necessary, but here it is:
$this->map = new MigrateSQLMap(
$this->machineName,
array(
'id' => array(
'type' => 'int',
'unsigned' => true,
'not null' => true,
'alias' => 'source'
)
),
MigrateDestinationNode::getKeySchema(),
'mysourcedb' // connection to use to write map tables
);
and finally, assign the retrieved rel_node_id to your node reference:
$this->addFieldMapping( 'field_rel_node', 'rel_node_id' );
Yay, it is rocket science .. YMMV
As far as I know, you will not be able to do this entirely within the migrate module. You'll have to run a few queries directly in MySQL.
Essentially, you'll have to create an extra field in each content type to house their legacy ID's and an additional field for each legacy reference (in addition to the actual nodereference field). Load all the data into the content types (leave the nodereference field empty). Then once all of the entities are loaded in, you run mysql queries to populate the nodereference fields based on the legacy IDs and legacy reference fields. Once that's done you can safely delete these legacy fields.
Not the most elegant solution, but I've used it many times.
Caveats:
This is for Drupal 6; Drupal 7's fields implementation is totally different AFAIK.
For very large migrations, you might want to do your legacy field deletions through MySQL.
You might also take a look at the code for the Content Migrate module (more information at https://drupal.org/node/1144136). It's for migrating D6 Content Construction Kit (CCK) content to D7 Fields and it's been integrated with the References module.
It won't do what you need out of the box, as you're coming from an ASP.net site instead of a D6 site, but it may provide some clues.

Resources