How to iterate through object array with form helpes in cakephp? - cakephp

I have an object CuratedPage with property pageName.
I am creating an array of CuratedPage objects in controller and setting it for the view like this:
$this->set('curatedPages', $curatedPages);
In the view I am creating a dropdown of page names like this:
$pageNames = array();
foreach($curatedPages as $curatedPage) {
array_push($pageNames, $curatedPage->getPageName());
}
echo $this->Form->input('curatedPage', array('options' => $pageNames));
Is there a way in cakephp that will allow me to pass the array of CuratedPage objects to the Form->input(...) instead of creating an array of scalar values.

I'm not sure what you would expect the form helper to do in that case. However, depending on your PHP version (>= 5.2.0 required) the magic __toString() method might do it. If you implement it to return the pagename, then you would end up with the same result as with your posted snippet, ie an numerical indexed (the value attribute) HTML option list with the page names as labels.
However, implementing this only for that purpose in this specific view seems wrong to me, you're probably better of utilizing a custom helper, or as #BrianGlaz suggested prepare the data in the controller.

Related

Laravel Eloquent - Working with an array of JSON objects

I have an array of JSON objects within my database (as depicted by the image below)
How do I search for a specific value within it? Say I want the record where the "ends_at" field is equal to "2018-11-24 08:00:00"
I've tried using
->where('column->starts_at', '2018-11-24 08:00:00')
or even tried
->whereJsonContains('column->starts_at', '2018-11-24 08:00:00').
Within the model I've cast the column to an array - am I missing something, or can this not be done?
Use this:
->whereJsonContains('column', ['starts_at' => '2018-11-24 08:00:00'])

How to append to multidimensional array in a smarty template?

I can append to a single array using
{append var='name' value='Bob' index='first'}
However, if I have a multi-dimensional array such as:
$name[first][last] = ['this','array']
and I want to append another value to the array at $name[first][last] e.g. to make the array like this:
$name[first][last] = ['this','array','appended']
how can I do this in the smarty template?
You can do this without using append:
{$name[first][last][] = 'this'}
{$name[first][last][] = 'array'}
{$name[first][last][] = 'appended'}
I must highlight though - templates should be used for specific purpose: to display prepared data; having to do the above is a code smell
I've tested many cases to try achieve it and I think it's not possible (in documentation there is also no info or example of multidimensional key or var)
You should also really think do you need it at all. Logic should be in PHP and role of Smarty is only displaying data not manipulating them

How to use (find)where in backbone to get a specific field of an array

I use to use the where method from the Collections in backbone. But I don't see how to fetch this result:
MyCollection.Group[x].id
As you can guess, MyCollection is the collection, Group is an array, and id is the field I would like to match for a specific value, something like:
MyCollection.findWhere(Group[x].id: 34);
I have seen the "contains" function of underscore but it doesn't seems to work with associative arrays
Is there a way to do it or should we parse the collection manually using Javascript ?
Collection.where and Collection.findWhere are convenience functions for simple filters. In your case, you would use the more complex Collection.find (proxied to _.find)
find _.find(list, iterator, [context])
Looks through each value in the list, returning the first one that passes a truth test
(iterator). The function returns as soon as it finds an acceptable
element, and doesn't traverse the entire list.
And if I understand correctly your condition, it could look like
MyCollection.find(function(model) {
return _.findWhere(model.get('Group'), {id: 34});
})
you can choose to use jQuery .find() . see examples here: http://api.jquery.com/find/

Invalidate Fields from Multiple Models

I have a form with multiple models in it. The validates in the models seems correct and the models are associated properly. But how do I invalidateFields from two models and pass the display error back to the form?
Code in my users)_controller.php is:
$errors = $this->User->invalidFields(array('fieldList' => array('password','cpassword','firstname','lastname','email')));
$this->User->set('errors',$errors);
But I have a Profile model chained like this:
$this->User->Profile
and want it to invalidFields to Profile.zip.
you can use chained if clauses like described at
http://www.dereuromark.de/2010/10/09/about-php-basics-and-pitfalls/
basically, you use & instead of &&
so if you got a main model and related data:
$this->User->set($this->data);
$this->User->Profile->set($this->data);
if ($this->User->validates() & $this->User->Profile->validates()) {
//continue
}
the single & makes sure that both conditions are executed (with && you would only trigger the first one if there was an error and therefore the validation rules would not get rendered for the related model)
you could also do:
$val1 = $this->User->validates();
$val2 = $this->User->Profile->validates();
if ($val1 && $val2) {}
this way they both get executed before you go into the if clause.
Instead of manually setting errors in the invalid fields array, I would suggest to use the $validate array to set up validation rules.
You can define your own, complex rules if the built in ones are not enough.

CakePHP: Use Inflector Class over whole array

I need to use Inflector::slug() over all results fetched from my database, which are, of course, retrieved in an array. Is it possible somehow, or I'll need to loop each result and slugify it?
Thanks!
PHP's array_map() function might do what you need (although it assumes a simple indexed array).
array_map( 'Inflector::slug', $your_result )
If you're looking at something more complex, CakePHP's Set utility class may be helpful in a multi-step implementation.
I haven't tried this in a CakePHP context (i.e. mapping through a CakePHP class method), but I can't think of any reason it wouldn't work off the top of my head. Maybe it'll at least get you started.
Depending on the array you can use array_walk or array_walk_recursive.
Something like this should work.
This is for 5.3+;
array_walk_recursive($posts, function(&$value) {
$value = Inflector::slug($value);
});
If you wanted to limit it to a certain field you could also do something like this:
array_walk_recursive($posts, function(&$value, $key) {
if ($key == 'title') {
$value = Inflector::slug($value);
}
});
I haven't used Cake in a while but like Rob Wilkerson said, you might find that the Set class could make lighter work of this.

Resources