How does persist work in Symfony? - symfony

I am new to Symfony, and I could not find an answer on the official site.
Can I use one variable to persist more then once ?
For example:
for ($i = 0; $i < count($allArea); $i++) {
$area = new Area();
$area->setValue($i);
$em->persist($area);
}
$em->flush();

The persist($area) call tells Doctrine to "manage" the $area object. This does not cause a query to be made to the database.
When the flush() method is called, Doctrine looks through all of the objects that it's managing to see if they need to be persisted to the database.
So basically in this case use flush() inside the loop or, if you want to use it once outside - create new 'area' obejects and do use the same $area.

Related

Object is too big when load from database symfony

I need load and object from the database and need to store it in session .
The problem is that the loaded object is too big that when i print it my browse crushes .
How can i load just the pure object from the database ?
And here is the code :
if ($session->get('record')->getId()) {
$record = $this->container->get('myweb.record_repository')->findOneById($session->get('record')->getId());
$session->set('record', $record);
print_r($session->get('record'));
die;
}
Try to hydrate as array... in symfony there is the option to Query::HYDRATE_ARRAY and then normalize it to an object
You're not dumping your code correctly.
With Symfony, there is the dump() function.
You can either use it in controller, or in twig.
In controller:
//Check if parameter exists first, else you might trigger an error
if($session->has('record') && $session->get('record')->getId() !== null) {
$record = $this->container->get('myweb.record_repository')->findOneById($session->get('record')->getId());
$session->set('record', $record);
dump($session->get('record'));
exit();
}
In Twig (you can pass a variable name)
{{ dump() }}
Then again, like I said in comment, it's most likely pointless to store your object in session.
Doctrine will query for the object most of the time.
Lets say you do this:
$relatedEntity->getRecord();
Doctrine won't look into the session for the object, it will query database.

Symfony 2 Variable Entity Naming

I feel like this shouldn't be to hard, but try as I might, I keep getting errors.
What I'm wanting to do, is to have a single "add" function that will handle the basic functionality of adding records to any / all tables. Basically, the post data will contain the table name, as well as the fields / values to be inserted. The controller itself, confirms the user has access to do these things, and then verifies the fields are valid, before creating a new instance of the entity, that's where things go haywire:
$entityName = 'Products';
$row = new $entityName(); //doesn't work
$row new Products(); //works
I haven't found a way or any examples of creating a new entity using the Entity Manager, or else that might work, because i've created functions using EM to do queries, updates, and deletes, but I just can't get this to work with the add functions.
1. Your problem is almost certainly namespacing (see below). Try this instead:
$entityName = 'My\Bundle\Entity\Products';
$row = new $entityName();
Should work. ;)
2. If you want to create new instances using an EntityManager, try this:
$entityName = 'My\Bundle\Entity\Products';
$row = $em->getClassMetadata($entityName)->newInstance();
...assuming $em is your EntityManager. :-)
3. To "prove" that your problem is namespacing, try this in a plain .php file that you run from the command line:
namespace Foo;
class Test {}
$class1 = 'Foo\Test';
$class2 = 'Test';
$x = new Test(); // Will work
$y = new $class1(); // Will work
$z = new $class2(); // Will trigger "Class 'Test' not found" fatal error
Two things:
Try with "Products" instead of 'Products'
I suppose that your entity Products has a namespace, it is required (even if you declared an use statement). So try with "My\Bundle\Entity\Products".

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).

is it possible to set a field in drupal to some value by using nodeapi

So I have this field named field_movie_cast_count this is a field of a content named movie so what I want is that whenever the movie is updated (like I add another cast member) the field_movie_cast_count field would be updated too. I have successfully done it using this code:
function count_cast_nodeapi(&$node, $op) {
$id = $node->nid;
if($op == 'update' && $node->type == 'movie') {
$count=count($node->field_movie_cast);
$q = db_query("update content_type_movie set field_movie_cast_count_value = '$count' WHERE nid = '$id'");
}
}
Now, my boss told me that I should not use query. So, how do I achieve this by not using a database query?
is it not possible to just set field_movie_cast_count[]['value']=$count? i tried this code it doesnt work. lol
OR SHOULD I REPHRASE THE QUESTION is there any other way of displaying the count cast? aside from my way? cause maybe i did not understand my boss right.
hook_nodeapi() has a presave operation which is invoked just before the node (and field data) is committed to the database. The definition of the operation is:
The node passed validation and is about to be saved. Modules may use this to make changes to the node before it is saved to the database.
You can use it to update a field value, without resorting to hitting the database manually (which will be overwritten anyway) like so:
function MYMODULE_nodeapi(&$node, $op) {
if ($op == 'presave' && $node->type == 'movie') {
$node->field_movie_cast_count[0]['value'] = count($node->field_movie_cast);
}
}

How to remove all items in a magento product collection?

Seems doesn't works:
<?php
$collection = Mage::getModel('catalog/product')->getCollection();
foreach($collection->getItems() as $key => $_product){
//product
$collection->removeItemByKey($key);
}
?>
$collection is still populated
If you'd like to work with an empty collection, the best approach would be to load it with a filter that would always produce an empty set. Here's an example:
$collection = Mage::getModel('catalog/product')->getCollection()
->addFieldToFilter('entity_id', 0);
Because Magento product ids start at 1, this collection would remain empty, until you add items to it with the addItem() method.
clear() and removeItemByKey(), on the other hand, will only trigger a second run to the database to refetch the data you don't want in there.
You question doesn't make sense. Running the following code
$c = Mage::getModel('catalog/product')->getCollection();
foreach($c->getItems() as $key=>$item)
{
$c->removeItemByKey($key);
}
foreach($c->getItems() as $key=>$item)
{
var_dump($key);
}
var_dump( "Done" );
results in only the word "done" being output (Magento 1.6.1).
My guess it something about your installation of Magento is making the call to $c->getItems(); trigger a reload of the collection. So, you remove all the items, but then when you call your second getItems, the collection is refetched.
There's clear() method in Varien_Data_Collection class which clears the collection.
I'm not sure if the method exists in the time the question was asked, but it exists in Magento 1.7
There's also a possibility to remove all the items without "fake loading" (in opposite to Shay Acrich's answer):
class MyCollection extends SomeCollection {
// ...
public function setEmpty()
{
$this->clear();
$this->_totalRecords = 0;
$this->_setIsLoaded(true);
return $this;
}
// ...
}
Setting _totalRecords to 0 is required in order not to allow getSize() method to reload the collection.
Nevertheless, one needs to extend / modify a collection's code, because both the field _totalRecords and the method _setIsLoaded() are protected.
There should be noted, that if a particular collection ignores flags like _totalRecords and _isCollectionLoaded the above solution may not work as expected.
$collection->clear()
should do the work.

Resources