Get the name of all the tables on my database - symfony

I need get the name of all the tables that exist on my database. I am usin Propel like my ORM. Actully i have been trying on this form.
$dbmap = \Propel::getDatabaseMap('data');
$tablastmp = $dbmap->getTables();
$tablas = array();
foreach ($tablastmp as $tablatmp) {
$tablas[] = $tablatmp->getName();
}
echo '<pre>';
print_r($tablas);
echo '</pre>';
die();
but this return an array that is empty.
array();
And I need that return something like that:
array( [0] => 'clients', [1] => 'workers' );
Please someone help. I have been trying that for a few days.

Actually, you probably wouldn't use Propel to get this information as Propel only loads the table map information when the table is actually used.
The original Schema file is used during the build phase (running 'propel_gen om' etc). The runtime part of Propel never looks at the Schema file, so there is no way to query it per se.
The answer to your question is to look at the database, e.g. the MySQL query to list the tables in a database:
SHOW [FULL] TABLES [{FROM | IN} db_name]
[LIKE 'pattern' | WHERE expr]

This might help you (hopefully)
$em = $this->getDoctrine()->getManager();
foreach ($em->getMetadataFactory()->getAllMetadata() as $md) {
var_dump($md->getName()); // dump the full class names
var_dump($md->getTableName()); // dump the table names
}

Related

Symfony2 Doctrine2 native queries basics

I am developing a basic web-app in my job. I have to work with some sql server views. I made the decision of trying native queries, and once tested it's functionality, try to write some classes to code all the queries and kinda forget their implementation.
So my issue is, I've got an Entity in Acme/MyBundle/Entity/View1.php.
This entity has got all the attributes matching the table and also it's getters and setters.
I guess this entity is well mapped to the DB (Doctrine cant work with views easily).
My aim is to let a Controller be able to fetch some data from those views(SQL SERVER) and return it to the view (twig) so it can display the info.
$returned_atts = array(
"att1" => $result[0]->getAttribute1(), //getter from the entity
"att2" => $result[1]->getAttribute2(), //getter from the entity
);
return $returned_atts;`$sql = "SELECT [Attribute1],[Attribute2],[Attribute3] FROM [TEST].[dbo].[TEST_VIEW1]"; //THIS IS THE SQL SERVER QUERY
$rsm = new ResultSetMapping($em); //result set mappin object
$rsm->addEntityResult('Acme\MyBundle\Entity\View1', 'view1'); //entity which is based on
$rsm->addFieldResult('view1', 'Attribute1', 'attribute1'); //only choose these 3 attributes among the whole available
$rsm->addFieldResult('view1', 'Attribute2', 'attribute2');
$rsm->addFieldResult('view1', 'Attribute3', 'attribute3');
//rsm built
$query = $em->createNativeQuery($sql, $rsm); //execute the query
$result = $query->getResult(); //get the array
It should be possible to return the array straight from the getResult() method isn't it?
And what's killing me, how can I access the attribute1, attriute2 and attriute2?
$returned_atts = array(
"att1" => $result[0]->getAttribute1(), //getter from the entity
"att2" => $result[1]->getAttribute2(), //getter from the entity
);
return $returned_atts;`
If you want result as array, you don't need to use ResultSetMapping.
$sql = " SELECT * FROM some_table";
$stmt = $this->getDoctrine()->getEntityManager()->getConnection()->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
That is a basic example for controller action. You can dump the result, use var_dump(), to see how to access your particular field values.
More examples here Doctrine raw sql

Processing Drupal Node Body

I'm new to Drupal. I looked here and on google for a while before asking, but I'm sure I can't find the answer because I don't know how to ask the question.
Here is what's going on. I'm using a custom module to load certain entities and then output them in a specific format for an application to access. The problem is that the NODE BODY contains special information and media files that should be converted. My goal is to obtain the HTML output that would normally be used on this field.
// Execute an EntityFieldQuery
$result = $query->execute();
if (isset($result['node'])) {
$article_items_nids = array_keys($result['node']);
$article_items = entity_load('node', $news_items_nids);
}
// Loop through each article
foreach ($article_items as $article) {
return $article->body[LANGUAGE_NONE]['0']['value'];
}
All of this works great. The only problem is that I get things like this in the output:
[[{"type":"media","view_mode":"media_original","fid":"283","attributes":{"alt":"","class":"media-image","data-thmr":"thmr_32","height":"400","width":"580"}}]]
or
*protoss_icon*
My goal is to find a way that these items are converted just like they are when these articles are viewed normally.
I've tried doing things such as:
render(field_view_field('node', $article, 'body'));
or
render($article->body[LANGUAGE_NONE]['0']['value']);
without success. Thanks for any help, I'm learning so I don't have a complete grasp of the process drupal uses to build output.
You can try something like this (this works only with nodes not with other custom entity types):
$node = node_load($nid);
$field = field_get_items('node', $node, 'your_field_name');
$output = field_view_value('node', $node, 'your_field_name', $field[$delta]);
the field_view_value returns a renderable array for a single field value. (from drupal api documentation)

Best practice for storing simple variables like 'total rows' in Symfony2

In my symfony2 application I need to display some totals at the top of all pages, ie "Already 200,154,555 users registered".
I don't want to run the query to come up with that count on every page load. The solution I've come up with is to create a "variable" entity that would have two columns, name and value. Then I would set up a console command that runs on cron which would update these variable entities (eg "totalPeople") with a query that counted all the rows of people, etc.
This feels a little heavy handed... Is there a better solution to this problem?
You could set global parameters and add a service to rewrite them. Then call the service from your Command.
Or directly set up a service to read/write a file (as a json array for example).
Or set up a option table with a row storing the data. It's not going to be a resource intensive query that way.
Here is what I'm using to store RSS feeds (after I parsed them)
public function checkCache($data=array(), $path = '')
{
foreach ($data as $service => $feed)
{
$service = strtolower($service);
$service = str_replace(' ', '-', $service);
$path = $path.'web/bundles/citation/cache/rss/' . $service . '.cache';
if ((!file_exists($path) || time() - filemtime($path) > 900) && $cache = fopen($path, 'w'))
{
$rss_contents = $this->getFeed($feed); //fetch feed content & returns array
fwrite($cache, serialize($rss_contents));
fclose($cache);
return $rss_contents;
}
else
{
$cache = fopen($path, 'r');
return unserialize(file_get_contents($path));
fclose($cache);
}
}
}
You can implement that on your backend for example so every time an admin logs it'll check for cache and refresh only if it's too old. Although I'm quite fond of the 4AM cron job solution too.
You could use the pagination feature of doctrine (if you use doctrine). That will leverage the "limit" part of your queries (even with joins) and will give you a total count of rows (via a count query).

Modifying a field collection programmatically missing hostEntity fields

I am trying to modify a field collection in a node that already exists so I can change an image on the first element in an array of 3. The problem is, the hostEntity info is not set when I do a entity_load or entity_load_single so when I do a:
$field_collection_item->save(true); // with or without the true
// OR
$fc_wrapper->save(true); // with or without the true
I get the following error:
Exception: Unable to save a field collection item without a valid reference to a host entity. in FieldCollectionItemEntity->save()
When i print_r the field collection entity the hostEntity:protected fields are indeed empty. My field collection is setup as follows:
field_home_experts
Expert Image <--- Want to change this data only and keep the rest below
field_expert_image
Image
Expert Name
field_expert_name
Text
Expert Title
field_expert_title
Text
Here is the code I am trying to use to modify the existing nodes field collection:
$node = getNode(1352); // Get the node I want to modify
// There can be up to 3 experts, and I want to modify the image of the first expert
$updateItem = $node->field_home_experts[LANGUAGE_NONE][0];
if ($updateItem) { // Updating
// Grab the field collection that currently exists in the 0 spot
$fc_item = reset(entity_load('field_collection_item', array($updateItem)));
// Wrap the field collection entity in the field API wrapper
$fc_wrapper = entity_metadata_wrapper('field_collection_item', $fc_item);
// Set the new image in place of the current
$fc_wrapper->field_expert_image->set((array)file_load(4316));
// Save the field collection
$fc_wrapper->save(true);
// Save the node with the new field collection (not sure this is needed)
node_save($node);
}
Any help would be greatly appreciated, I am still quite new to Drupal as a whole (end-user or developer)
Alright so I think I have figured this out, I wrote up a function that will set a field collection values:
// $node: (obj) node object returned from node_load()
// $collection: (string) can be found in drupal admin interface:
// structure > field collections > field name
// $fields: (array) see usage below
// $index: (int) the index to the element you wish to edit
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
if ($node && $collection && !empty($fields)) {
// Get the field collection ID
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
// Load the field collection with the ID from above
$entity = entity_load_single('field_collection_item', array($eid));
// Wrap the loaded field collection which makes setting/getting much easier
$node_wrapper = entity_metadata_wrapper('field_collection_item', $entity);
// Loop through our fields and set the values
foreach ($fields as $field => $data) {
$node_wrapper->{$field}->set($data);
}
// Once we have added all the values we wish to change then we need to
// save. This will modify the node and does not require node_save() so
// at this point be sure it is all correct as this will save directly
// to a published node
$node_wrapper->save(true);
}
}
USAGE:
// id of the node you wish to modify
$node = node_load(123);
// Call our function with the node to modify, the field collection machine name
// and an array setup as collection_field_name => value_you_want_to_set
// collection_field_name can be found in the admin interface:
// structure > field collections > manage fields
updateFieldCollection(
$node,
'field_home_experts',
array (
'field_expert_image' => (array)file_load(582), // Loads up an existing image
'field_expert_name' => 'Some Guy',
'field_expert_title' => 'Some Title',
)
);
Hope this helps someone else as I spent a whole day trying to get this to work (hopefully I won't be a noob forever in Drupal7). There may be an issue getting formatted text to set() properly but I am not sure what that is at this time, so just keep that in mind (if you have a field that has a format of filtered_html for example, not sure that will set correctly without doing something else).
Good luck!
Jake
I was still getting the error, mentioned in the question, after using the above function.
This is what worked for me:
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
$fc_item = entity_load('field_collection_item', array($eid));
foreach ($fields as $field => $data) {
$fc_item[$eid]->{$field}[LANGUAGE_NONE][0]['value'] = $data;
}
$fc_item[$eid]->save(TRUE);
}
I hope this helps someone as it took me quite some time to get this working.

How do I connect to the database from a Drupal 7 module?

I would like to connect to the database from a Drupal 7 module. Currently I only have the query I want to run which is:
$query = db_select('z_lists)
->fields('country')
->condition('value', $country, '=')
->execute()
->fetchAssoc();
What I can't figure out is how to establish a connection to the default database.
Any help?
In Drupal7 there is function called db_query(). you can use that function to run your queries.
You can use below syntex
$var1 = 1;
$result = db_query('SELECT n.title FROM {node} n WHERE n.uid = :uid', array(':uid' => $var1));
$result will be stdClass object so you can use it in foreach loop.
The only problems with the op's example code was a misuse of the db_select and a missing single quote.
Dynamic queries: https://drupal.org/node/310075
It would have been fine if you'd just used this instead:
$query = db_select('z_lists','z')
->fields('z')
->condition('value', $country, '=')
->execute()
->fetchAssoc();
That would return all fields for the matching record(s).
the ->fetchAssoc() chained to the end would ensure you only received the first matching record. If you expected multiple results you'd leave off ->fetchAssoc() and just loop through the results with:
foreach($query as $result){
... do something with the data here ...
}
But to answer the actual ASKED question, you're automatically connected to the default database. There is no need to declare any kind of DB connection before running any kind of query to the site db.
If you're trying to connect to an external database that's a different issue.

Resources