I am building a web app that will have the option to assign an array item to be visible by a group (or groups). This all would be passed through to Wordpress to update_option but for the basics it is a PHP question.
To me it would be a checkbox that would be a true or false for that group and if they have permission:
| Title 1 //$array['label']
-------------------------
Opt1 | x
-------------------------
Opt2 | x
-------------------------
Opt3 |
-------------------------
Opt4 |
-------------------------
Opt5 | x
Where the $array would have the values pulled from here:
$array = array(
array( 'label' => 'Title 1', 'class' => 'loc01' ),
array( 'label' => 'Title 2', 'class' => 'loc02' ),
array( 'label' => 'Title 3', 'class' => 'loc03' ),
array( 'label' => 'Title 4', 'class' => 'loc04' ),
array( 'label' => 'Title 5', 'class' => 'loc05' ),
);
The $array is created by array_merge() with the original, and whatever new array is created by the user on the front end.
$old_array = $array;
$new_array = array( array( 'x' => $array_label, 'y' => $array_class ) );
$new_array = array_merge( $old_array, $new_array );
What would be the best way to add the permission to the $array?
Should it be this:
$array = array(
array( 'label' => 'Title 1', 'class' => 'loc01', 'permission' => array( 'Opt1', 'Opt2', 'Opt3' ) ),
...
array( 'label' => 'Title 5', 'class' => 'loc05' ),
);
And how would I best be able to verify permission on the front end when looping the output?
foreach( $array as $item )
if( in_array( 'current_group', $item[permission] )
...
Hope this makes sense!
The best way for you to do this is below:
foreach($array as $key => $val)
{
$array[$key]['permission'] = 'true or false(your choice)';
}
Related
I'm trying to add associated data to during cakePHPs beforeSave() but it looks like cakePHP is ignoring it.
<?php
App::uses("AppModel", "Model");
class Recipe extends AppModel {
public $hasMany = array('Ingredient');
public function beforeSave($options=array()) {
if(!isset($this->data["Ingredient"])) {
Debugger::log("data[Ingredient] didn't exist! adding some ingredients...");
$this->data["Ingredient"] = array(
array(
'Ingredient' => array(
'name' => 'Gluten Free Flour',
'amount' => '12 cups'
)
),
array(
'Ingredient' => array(
'name' => 'Sugar',
'amount' => '50 cups'
)
),
array(
'Ingredient' => array(
'name' => 'A shoe',
'amount' => 'Just one'
)
),
);
}
Debugger::log("Saving Data: ");
Debugger::log($this->data, 7, 10);
return true;
}
}
In my RecipesController I have this:
public function test_save() {
//Test saving With the ingredients in the recipe
Debugger::log("Saving w/ ingredients");
Debugger::log($this->Recipe->saveAssociated(array(
'Recipe' => array(
'name' => 'Test Recipe 1'
),
'Ingredient' => array(
array(
'name' => 'Test Ingredient 1 for Test Recipe 1',
'amount' => 'a few'
),
array(
'name' => 'Test Ingredient 2 for Test Recipe 1',
'amount' => 'a lot'
)
)
)));
Debugger::log("Saving w/o ingredients");
Debugger::log($this->Recipe->saveAssociated(array(
'Recipe' => array(
'name' => 'Test Recipe 2'
)
)));
}
The save with ingredients works, but the save without ingredients doesn't, the data in Recipe->data before beforeSave returns is this:
array(
'Recipe' => array(
'name' => 'Test Recipe 1'
),
'Ingredient' => array(
(int) 0 => array(
'Ingredient' => array(
'name' => 'Test Ingredient 1 for Test Recipe 1',
'amount' => 'a few'
)
),
(int) 1 => array(
'Ingredient' => array(
'name' => 'Test Ingredient 2 for Test Recipe 1',
'amount' => 'a lot'
)
)
)
)
And when Ingredient is added in the before save:
array(
'Recipe' => array(
'name' => 'Test Recipe 1'
),
'Ingredient' => array(
(int) 0 => array(
'Ingredient' => array(
'name' => 'Gluten Free Flour',
'amount' => '12 cups'
)
),
(int) 1 => array(
'Ingredient' => array(
'name' => 'Sugar',
'amount' => '50 cups'
)
),
(int) 2 => array(
'Ingredient' => array(
'name' => 'A shoe',
'amount' => 'Just one'
)
)
)
)
When the data is in the array before I call a save method, it'll work just fine, only when I try and add the associated data in the beforeSave.
From the documentation:
Be sure that beforeSave() returns true, or your save is going to fail.
http://book.cakephp.org/2.0/en/models/callback-methods.html#beforesave
Edited: I tested your code and you are right, related data added in beforeSave() is being ignored. This is happening because you cannot add or modify related data in a model's beforeSave(). It means that, in your Recipe's beforeSave(), you cannot neither add Ingredients nor modify the Ingredients you previously attached to Recipe in your controller.
In your Recipe's beforeSave() you can only modify Recipe data.
Is this a bug? It is not, according to Mark Story (creator of CakePHP):
Its a feature, as currently saveAll only lets you use beforeSave to
modify the record that's about to be saved, not the full data set. I
personally don't feel that should change, but its something that could
be discussed.
This statement is about saveAll() but the important part is what he said about beforeSave(). Check the full thread: https://github.com/cakephp/cakephp/issues/1765
I have a model called Category which hasMany Expense. I am trying to generate an accordion type interface where a user can expand a category and edit the expenses. I can generate the input fields but they don't seem to be in "edit" mode because they are not pre-populated.
I've searched online and found a few related articles such as this one CakePHP: How to update multiple records at the same time with the Form helper and also this one CakePHP: Form helper with saveMany() to edit multiple rows at once. I have tried to emulate their code but with no success.
My CategoriesController Index function looks like this ...
public function index($project_id) {
$data = $this->Category->find('all', array(
'conditions'=>array('Category.project_id' => $project_id),
'order'=>array('Category.category_name')
));
$this->set('categories', $data);
$this->request->data = $data;
}
I have read that cakephp2 requires $this->request->data to be set for FormHelper to work. But in the examples I have found online everyone seems to use the plural of the model name so I tried that as well.
My Categories\index.ctp looks like this. I'm not at the "accordion" stage yet. I'm just trying to get input boxes on the screen that are pre-populated.
$i=0;
foreach ($categories as $category)
{
echo $this->Form->input("Category.$i.category_id");
echo $this->Form->input("Category.$i.category_name");
$j=0;
foreach($category['Expense'] as $expense)
{
echo $this->Form->input('Expense.' . $j . '.expense_id');
echo $this->Form->input('Expense.' . $j . '.expense_name');
echo $this->Form->input('Expense.' . $j . '.dollar_amount');
echo $this->Form->input('Expense.' . $j . '.sqft_amount');
$j++;
}
$i++;
}
This code seems to be iterating properly because it spits out the correct input fields. The big problem right now is just getting the fields to pre-populate. It doesn't seem to be in "edit" mode and I'm worried that that will be a problem down the road when I try to save the data.
Also, I have tried it with and without $this->form->create('Category') at the top. It doesn't seem to make a difference.
The $categories array looks like this ...
array(
(int) 0 => array(
'Category' => array(
'category_id' => '1',
'category_name' => 'Category 1',
'category_index' => '1',
'project_id' => '1'
),
'Project' => array(
'project_id' => '1',
'project_name' => '131 Anndale Dr',
'project_sqft' => '1700',
'project_cost' => '318',
'project_cost_per_sqft' => '0'
),
'Expense' => array(
(int) 0 => array(
'expense_id' => '2',
'expense_name' => 'Nails',
'category_id' => '1',
'dollar_amount' => '50',
'sqft_amount' => '1',
'expense_index' => '2'
),
(int) 1 => array(
'expense_id' => '1',
'expense_name' => 'Wood',
'category_id' => '1',
'dollar_amount' => '99',
'sqft_amount' => '1',
'expense_index' => '1'
)
)
),
(int) 1 => array(
'Category' => array(
'category_id' => '3',
'category_name' => 'Category 2',
'category_index' => '2',
'project_id' => '1'
),
'Project' => array(
'project_id' => '1',
'project_name' => '131 Anndale Dr',
'project_sqft' => '1700',
'project_cost' => '318',
'project_cost_per_sqft' => '0'
),
'Expense' => array(
(int) 0 => array(
'expense_id' => '3',
'expense_name' => 'Bed',
'category_id' => '3',
'dollar_amount' => '99',
'sqft_amount' => '2',
'expense_index' => '1'
),
(int) 1 => array(
'expense_id' => '4',
'expense_name' => 'Chair',
'category_id' => '3',
'dollar_amount' => '70',
'sqft_amount' => '1',
'expense_index' => '2'
)
)
)
)
Any help would be greatly appreciated. Thanks!!
Coincidentally, I've been doing almost exactly the same thing today.
In order to automatically populate the form, you need to have your data in $this->data in the view. You can do this by assigning to $this->request->data in your controller.
Then you need to have your field names reflect the structure of that array exactly. So using your example, you might have:
echo $this->Form->input("$i.Category.category_name");
for the category fields, and
echo $this->Form->input("$i.Expense.$j.expense_id");
for your expense fields.
I want to set the multi selection to my multi list box.
I have two results in my view page.
$inr1 = 0;
$arr1 = array();
$str_arr = '';
foreach ($result as $rows){
$inr1 = $rows['Employees']['employee_id'];
$arr1[$inr1] = $rows['Employees']['first_name'].' '.$rows['Employees']['last_name'];
$str_arr = $str_arr.$inr1.',';
}
$str_arr = substr($str_arr,0,-1);
//print_r($arr1);
$inr = 0;
$arr = array();
foreach ($options as $option){
$inr = $option['Employee']['employee_id'];
$arr[$inr] = $option['Employee']['first_name'].' '.$option['Employee']['last_name'];
}
//print_r($arr);
echo $this->Form->input('emp_id_one', array( 'options' => array( $arr),
'empty' => '(choose one)',
'div'=>'formfield',
'error' => array( 'wrap' => 'div',
'class' => 'formerror'
),
'label' => 'Team Members',
'type' => 'select', 'multiple' => true,
'selected' => $arr1,
'style' => 'width:210px; height:125px;',
));
But the values in $arr1 not selected in the list box.
The $arr1 have the selected values.
The $arr have the options to the list.
The problem is that the selction is not working..There have no selection...
How can i do this?
If there is any problem in my code..?
Finally i solved my problem by chaing some code:
Add the one line of code after this $str_arr = substr($str_arr,0,-1);'.
That is....
$str_arr = substr($str_arr,0,-1);
$sel = explode(',',$str_arr);
Then change the name of variable as like this :
echo $this->Form->input('emp_id_one', array( 'options' => array( $arr),
'empty' => '(choose one)',
'div'=>'formfield',
'error' => array( 'wrap' => 'div',
'class' => 'formerror'
),
'label' => 'Team Members',
'type' => 'select', 'multiple' => true,
'selected' => $sel,
'style' => 'width:210px; height:125px;',
));
Now the values in $sel is selected in the multi list
I have a nested associated model based on
Project=>ProjectDocument=>ProjectDocumentSection=>ProjectDocumentSectionVariable=>Codeset=>Code
I am using containable behaviour to get a specific array with these elements (for a single project).
I have set up associations for these models in their respective models.
Using foreach I am able to interrogate all the data up to an including the ProjectDocumentSectionVariable level.
However, once I try to go to the Codeset level, I get errors.
The pertinent code is:
foreach ($project['ProjectDocument'] as $project_document):
if ($project_document['document_type'] == 1)
{
foreach ($project_document['ProjectDocumentSection'] as $project_document_section):
echo "<h4>" . $project_document_section['title']. "</h4><div><table><th>Variable</th><th>Full text</th><th>Type</th><th>Format</th><th>Codeset</th>" ;
foreach ($project_document_section['ProjectDocumentSectionVariable'] as $project_document_section_var):
echo "<tr><td>" . $project_document_section_var['variable_name']
. "</td><td>".$project_document_section_var['variable_description']
. "</td><td>".$project_document_section_var['variable_type']
."</td><td>".$project_document_section_var['variable_format']
."</td><td>".$project_document_section_var['codeset_id'] ;
foreach($project_document_section_var['Codeset'] as $codeset):
foreach($codeset['Code'] as $pcode):
echo $pcode['codevalue'].", ";
endforeach;
endforeach;
echo "</td></tr>";
endforeach;
echo "</table></div>";
endforeach;
}
endforeach;
But I get Illegal string offset 'Code', and Invalid argument supplied for foreach() at the line echo $pcode['codevalue'].", ";
I have looked at the array for $project_document_section_variable and I think there is a problem with the codeset array, but I cannot work out why it is doing this.
Here is an example of some output for the array $project_document_section_variable:
array(
'id' => '32',
'project_id' => '05a',
'project_document_id' => '3',
'project_document_section_id' => '2',
'variable_id' => '2',
'variable_name' => 'Respondent Education',
'variable_description' => 'B1. What is your highest level of education?',
'variable_type' => 'Categorical',
'variable_format' => 'Quantitive',
'codeset_id' => '43',
'Codeset' => array(
'id' => '43',
'title' => 'Educational level',
'Code' => array(
(int) 0 => array(
'id' => '96',
'codeset_id' => '43',
'codevalue' => '1',
'title' => 'No education'
),
(int) 1 => array(
'id' => '97',
'codeset_id' => '43',
'codevalue' => '2',
'title' => 'Primary'
),
(int) 2 => array(
'id' => '98',
'codeset_id' => '43',
'codevalue' => '3',
'title' => 'Secondary'
),
(int) 3 => array(
'id' => '99',
'codeset_id' => '43',
'codevalue' => '4',
'title' => 'Tertiary'
),
(int) 4 => array(
'id' => '100',
'codeset_id' => '43',
'codevalue' => '7',
'title' => 'Other (describe)'
),
(int) 5 => array(
'id' => '101',
'codeset_id' => '43',
'codevalue' => '8',
'title' => 'Refuses to answer'
),
(int) 6 => array(
'id' => '102',
'codeset_id' => '43',
'codevalue' => '9',
'title' => 'Don’t know'
)
)
)
)
You may notice that the codeset array does not have an (int) 0. perhaps this is because only one array is returned for codeset (which is correct, each project_document_section_variable has only one associated codeset.
Is there something blindingly obvious I am missing here?
This line -> foreach($project_document_section_var['Codeset'] as $codeset): is making php assign ['id'], ['title'], and ['Code'] to $codeset.
This line -> foreach($codeset['Code'] as $pcode): is making php looks for ['id']['Code'], ['title']['Code'], and ['Code']['Code'] which don't exists and raise the error.
Try replacing this:
foreach($project_document_section_var['Codeset'] as $codeset):
foreach($codeset['Code'] as $pcode):
echo $pcode['codevalue'].", ";
endforeach;
endforeach;
For this:
foreach($project_document_section_var['Codeset']['Code'] as $pcode):
echo $pcode['codevalue'].", ";
endforeach;
I'm struggling to find the answer to this. I have only been using CakePHP for a month and I've hit a problem. It's something I can fix by manually inserting the values but I expected my data to pre-populate. Here is what is happening:
The Model is Product which hasMany 'Dynamicprice'
I'm testing a product with the id of 7 (/products/edit/7).
the first part of my edit function is:
public function edit($id = null) {
$this->Product->id = $id;
if (!$this->Product->exists()) {
throw new NotFoundException('Invalid Product');
}
if ($this->request->is('get')){
$this->request->data = $this->Product->read();
}
debug($this->request->data);
//other stuff setting vars for drop-down lists
}
the
debug($this->request->data);
gives me the following:
array(
'Product' => array(
'id' => '7',
'category_id' => '70',
'name' => 'Full Test',
'description' => 'This is to test all features',
'price' => '0.00',
'aesthetic' => true,
'image' => '',
'price_structure' => '2',
'suggest_for' => '',
'created' => '2012-06-28 12:49:06',
'modified' => '2012-06-28 12:49:06'
),
'Dynamicprice' => array(
(int) 0 => array(
'id' => '15',
'product_id' => '7',
'drop' => '600',
'prices' => '6000:9.99, 12000:18.99 '
),
(int) 1 => array(
'id' => '16',
'product_id' => '7',
'drop' => '1200',
'prices' => '6000:19.99, 12000:28.99 '
),
(int) 2 => array(
'id' => '17',
'product_id' => '7',
'drop' => '2400',
'prices' => '6000:29.99, 12000:38.99 '
)
)
)
However, whilst everything in ['Product'] pre-populates the ['Dynamicprice'] array does not pre-populate the following:
<?php
echo $this->Form->input('Dynamicprices.0.id');
echo $this->Form->input('Dynamicprices.0.drop', array('label' => 'Drop 1 (mm). Enter "0" for "Any Drop"'));
echo $this->Form->input('Dynamicprices.0.prices', array('label' => 'Prices 1', 'type' => 'textarea', 'rel' => 'dynamic'));
?><hr><?php
echo $this->Form->input('Dynamicprices.1.id');
echo $this->Form->input('Dynamicprices.1.drop', array('label' => 'Drop 2 (mm).'));
echo $this->Form->input('Dynamicprices.1.prices', array('label' => 'Prices 2', 'type' => 'textarea', 'rel' => 'dynamic'));
?><hr><?php
echo $this->Form->input('Dynamicprices.1.id');
echo $this->Form->input('Dynamicprices.2.drop', array('label' => 'Drop 3 (mm).'));
echo $this->Form->input('Dynamicprices.2.prices', array('label' => 'Prices 3', 'type' => 'textarea', 'rel' => 'dynamic'));
?>
Am I right to expect them to populate automatically and if so what have I done wrong?
I have created /Model/Dynamicprice.php with the following just to make sure:
class Dynamicprice extends AppModel {
public $name = 'Dynamicprice';
public $belongsTo = 'Product';
But as I expected it didn't change anything.
This is the second time I've done this this week; ask a stupid question. Yes I was right to expect them to pre-populate. The problem is I got my naming conventions mixed up. "Dynamicprices.1.drop" shouldn't have the 's' at the end. Silly me!