How to access items in a field collection (Drupal 7) - php

I am trying to access image uri's in an array within a field collection but I don't know how to access them. If I look in the devel module, I can see the location of the first image uri in the array looks like this:
['field_text_and_image'][0]['entity']['field_collection_item'][2474]['field_about_accreditation_image'][0]['#item']['uri']
I am puzzled because I have 'field_get_items' method to access the field collection I am targeting like so...
$text_and_image_field = field_get_items('node', $node, 'field_text_and_image');
... and if I print/render this variable, I would expect to see an array printed on the page but instead nothing gets created. However, I made a condition on the page that checks to see if the '$text_and_image_field' field collection exists, and if it does to create an element, and it does indeed create an element which shows that the field exists. I just can't seem to access any of it's content.
So, why isn't the field collection printing anything and how can I loop through the 'field_about_accreditation' array to print out all of the image uri's?
EDIT*
I've taken a few more stabs at the problem and realized that I made the mistake of trying to render the value of the '$text_and_image_field' when I should have been using print_r, which now doing so gives me this array value:
Array ( [0] => Array ( [value] => 2474 [revision_id] => 174439 ) )
Based on older code where field collections are accessed, what has happened every other time a value has been assigned to a field collection is to write the following statements:
$value = field_view_value('node', $node, '$field_text_and_image', $text_and_image_field[$i]);
$field_collection = $value['entity']['field_collection_item'][key($value['entity']['field_collection_item'])];
However, when I try to print out $value (which I expect would be '2474') nothing is displayed.

Hi field collections are stored as a seperate entity so you will need to do an entity load to get the data.
$text_and_image_field = entity_load('field_collection_item', array($entity_id));
In this case it looks like the entity id is 2474 from there you can manipulate the array as you need to.
Your end code could be something like so:
$imageuri = entity_load('field_collection_item', array(2474))[2474]->field_about_accreditation_image['und'][0]['uri'];

Let' say that you have loaded $node and inside it you have field collection field field_images. Then you can get first element of it as:
$collection_entity_id = $node->field_photo['und'][0]['value'];
Now you have entity id and you have to load full entity:
$full_entity = field_collection_item_load($collection_entity_id);
And whey you loaded entity you can access entity fields the usual way:
$title = $full_box->title;
$image_path =- $full_entity->field_image_path['und'][0]['value'];
And yes, I know it's not cleanest way to get the values, please don't rub it in my face.

Related

PHP: is there a way to execute a function/method when no method is called on an object?

I have an object that stores another subObject in it's data attribute. The subObject in the data attribute can be called vie a magic method like this:
$object->subObject. The subObject also has a data attribute in which it's value is stored. Currently when I do $object->subObject it automatically returns the value stored in the data attribute of the subObject. So basically the whole structure looks somewhat like this:
object [
data => subObject [
data => 'value'
]
]
$object->subObject //returns 'value'
I hope that this is understandable so far. Now I want to have the ability to execute someFunc() on the subObject: $object->subObject->someFunc(). That is generally not a problem. But I also want that, if I don't call a method on the subObject at all, the value of it's data attribute is returned ('value'). Is it possible to figure out within an object/a class if a method is called on it or not and act accordingly?
This is not possible. When you access a value, you get the same result regardless of what is going to be done with that value. It can't be different depending on whether you're going to call another method on it.
Remember that
$object->subObject->someFunc();
is essentially equivalent to
$temp = $object->subObject;
$temp->someFunc();
If the $object->subObject returned 'value', the first line would set $temp = 'value', and then $temp->someFunc() wouldn't work.

Symfony4 stop handleRequest() from removing values of my object

I am submitting a form and in my controller I use handleRequest to validate the form.
Lets say I try to update my object name 'object' - It has an id, name and color field.
On the same page I also show a lost with the names of all my objects that I fetch from the database
Here is my code:
$object = self::getObjectById($objectId);
$objects = self::getAllObjects();
$objectForm = self::CreateObjectForm($object);
$objectFormForm->handleRequest($request);
dd($objects);
When I submit the form and I leave the name field open,
It throws an error that the field is required when it reloads the page, the name field of the form is still empty which is normal.
But here is the problem, in the list of objects that is also showing on this page the name of the object I tried to update has no name showing anymore in this list.
I don't know why this is happening since I fetched this list of objects completely separately from the form object. When I dd() the objects after the handleRequest() I cans see in the dumped vars that indeed the name field is empty. When I check the database, the name field is not empty and still holds the old name. Which makes sense because the object is not persisted and flushed to de db.
When I dd() the same list before the handleRequest() everything is normal.
How can I prevent this behavior? And why is this happening?
I don't know why this is happening since i fetched this list of objects completely seperatly from the form object.
It's referencing the same entity which get's dumped in it's current, live, dirty state as submitted by the form.
If you need to render the clean, persisted values then you just need to store them in a variable as a string instead of as the object, and before handling the request.
Try something like this:
$object = self::getObjectById($objectId);
$objects = self::getAllObjects();
$persistedObjects = [];
foreach($objects as $obj){
$persistedObjects[$obj->getId()] = $obj->getName();
}
$objectForm = self::CreateObjectForm($object);
$objectFormForm->handleRequest($request);
dd($persistedObjects);

SilverStripe - Using the CheckboxsetField with MultiForm Module

I have a form using the multiform module. I have a checkboxsetfield populated by a dataobject.
When saving the form I am getting strange results. For instance if I select the first and third checkboxes then this is how the array appears in the database: 1{comma}3 when I expected to see 1,3
MyDataObject.php
<?php
...
if($SomeData = DataObject::get('SomeData')->sort('SortColumn'){
$fields->push( new CheckboxSetField('SomeData', 'Field Name', $SomeData->map('ID', 'Name')
));
}
MultiForm.php
<?php
...
public function finish($data, $form){
if(isset($_SESSION['FormInfo']['MultiForm']['errors'])){
unset($_SESSION['FormInfo']['Form']['errors']);
}
parent::finish($data, $form);
$steps = DataObject::get('MultiFormStep', "SessionID = {$this->session->ID}");
$MyStep = $this->getSavedStepByClass('MyStep');
if($this->getSavedStepByClass('MyStep')){
if($MyStep->loadData()){
$MyDataObject = new MyDataObject();
$MyStep->saveInto($MyDataObject);
$MyDataObject->write();
}
}
...
Any ideas how to process the array?
CheckboxSetField does have code which refers to {comma} when saving to the DB or when calling the dataValue function. This is essentially escaping any commas that were defined as values in the string when saving to a single column.
This tells me that either your multiform isn't providing the right input to CheckboxSetField or that there is more to this situation than your code is showing.
If CheckboxSetField gets an array like array('1,3'), that is when I would expect to see that type of result. Calling map like you have returns an SS_Map object which may not automatically convert the way you are expecting. Try adding ->toArray() after the map call when you are passing the values into the CheckboxSetField.
If that doesn't solve the issue, we probably will need to see the DataObject itself and a few other bits and pieces of information.

Cakephp display view fields that is set by select elements in form

I am having problem displaying values set by select elements created by FormHelper. I have searched the internet but doesn't seem to be able to find the answer. Here is the scene:
I have a questionnaire form that has many options. In the model I put those items into an array, say ($frequencyOptions) and when formhelper is used,
$this->Form->input('frequency',array("options"=> $frequencyOptions));
Currently, the option value is the array index, which looks like:
<option value="">(choose one)</option>
<option value="0">Rare</option>
<option value="1">Frequent</option>
<option value="2">Moderate</option>
Of course I know that if I set the key as well when constructing the $frequencyOptions variable like
$frequencyOptions = array("Rare" => "Rare", ...
I will be able to store the value in text.
However, since some of these options are very very long, I would prefer to save them in INT in the database.
Yet the challenge I have at this moment is how to display those fields in the "list" in the index page. When I use the form field to display in the view or edit action, it is okay because the select element will be used again. However, if I want to display it in plain text, how should I "translate" it?
One thing I can think of is to create these "conversion" methods in the Model, but I think calling model method in views is not a good practice in MVC.
Any idea?
I'd think adding a method to your Model would be the way to go. How about this:
// In your Model class
// Store the index-to-name map in the Model as well
var $frequencyOptions = array(...);
public function translateFrequency(&$data) {
foreach ($data as &$record) {
$index = $record['ModelName']['frequency'];
$record['ModelName']['frequency'] = $this->frequencyOptions[$index];
}
}
// In your Controller action:
$data = $this->ModelName->find(...);
$this->ModelName->translateFrequency($data);
And then it should display the human-readable value when passed to the index page. If preferred, the above method could be changed so it works on $this->data inside the Model.
Note: The method has to be changed if it should work for a single record data array as well.

Zend Framework - How to modify a single parameter from the request object

A submitted form on my site returns an array of request data that is accessible with
$data = $this->getRequest();
This happens in the controller which gathers the data and then passes this array to my model for placing/updating into the database.
Here is the problem. What if I want to manipulate one of the values in that array? Previously I would extract each value, assigning them to a new array, so I could work on the one I needed. Like so:
$data = $this->getRequest();
$foo['site_id'] = $data->getParam('site_id');
$foo['story'] = htmlentities($data->getParam('story'));
and then I would pass the $foo array to the model for placing/updating into the database.
All I am doing is manipulating that one value (the 'story' param) so it seems like a waste to extract each one and reassign it just so I can do this. Additionally it is less flexible as I have to explicitly access each value by name. It's nicer to just pass the whole request to the model and then go through getting rid of anything not needed for the database.
How would you do this?
Edit again: Looking some more at your question what I am talking about here all goes on in the controller. Where your form`s action will land.
Well you have a couple of options.
First of all $_GET is still there in ZF so you could just access it.
Second there is:
$myArray = $this->_request->getParams();
or
$myArray = $this->getRequest()->getParams();
Wich would return all the params in an array instead of one by one.
Thirdly if the form is posted you have:
$myArray = $this->_request()->getPost();
Wich works with $this->_request->isPost() wich returns true if some form was posted.
About accessing all that in your view you could always just in controller:
$this->view->myArray = $this->_request->getParams();
edit: right I taught you meant the view not the model. I guess I do not understand that part of the question.
If you want to deal with the post data inside your model just:
$MyModel = new Model_Mymodels();
$data = $this->_request->getParams();
$data['story'] = htmlentities($data['story']);
$myModels->SetItAll($data);
And then inside your model you create the SetItAll() function (with a better name) and deal with it there.
Edit: oh wait! I get it. You hate sanytising your input one by one with your technique. Well then what I showed you about how to access that data should simplify your life a lot.
edit:
There is always the Zend_Form route if the parameters are really coming from a form. You could create code to interface it with your model and abstract all this from the controller. But at the end of the day if you need to do something special to one of your inputs then you have to code it somewhere.

Categories