PHP Global Multidimensional Array... Or How would I do that? - php

I'm new to PHP and trying to learn the proper way to do things, I'm currently working on a PHP / HTML form so here is my code for my globa variable:
// General Function
global $variables;
$variables = array(
'login' => array(
'visible' => 'visible',
'required' => 'required',
'position' => get_option('order_username'),
'value' => $_POST['username'],
'error_req' => __('A username is required to register.'),
'error_misspelled' => __('Your username is not properly formatted.'),
'error_unavailable' => __('This username has already been registered.')
),
'province' => array(
'visible' => get_option('show_province'),
'required' => get_option('required_province'),
'position' => get_option('order_province'),
'value' => $_POST['easyreg_province'],
'error_req' => __('You need to fill your province to register.'),
'error_misspelled' => '',
'error_unavailable' => ''
)
);
This works fine and I can access those Variables from every other functions; first I know many people says not to use GLOBAL variables, I don't really understand why because in my case those data will be used and reused inside my form, I would prefer not to redeclare new variables in every function related because those data won't change during the processing.
If it's really not the best way... What could be a good way to do that? As you can see I have about 7 "values" by form "input".
Also, for a GLOBAL variable like that can you "declare" the values from inside a function? What I mean is that if I add a new fields to my form, I would like to have those declaration beside my field, instead of having it in the main PHP (which would also make my code look cleaner).
I would have thought something like that, but it seems to be only declaring it inside the function itself:
function form_display(){
<!-- Email field -->
$GLOBALS['variables']['email'] = array(
'visible' => 'visible',
'required' => 'required',
'position' => get_option('order_email'),
'value' => $_POST['email'],
'error_req' => __('An email is required to register.'),
'error_misspelled' => __('This is not an appropriate email format.'),
'error_unavailable' => __('This email has already been registered.')
);
?>
<div class="regpage_email required"
id="order_<?php echo($GLOBALS['variables']['email']['position']) ?>">
<td id="field_email"><label
for="email"><?php _e('E-mail Address: *') ?></label><br><input
id="email"
type="email"
name="email"
value=""
placeholder=""
required>
</td>
}

Related

Foreach form in array validation

Thanks for reading :D
I'm creating a online order system. You will see 3 inputs. Partnumber, Quantity and Price. You will only fill in Partnumber and Quantity. Price will be checked trough my database for the right price. I tried to create that function, still not working. But anyway. I included a jQuery function so you can add extra lines into the form when you want to order more products.
A little snippet so you know what i am meaning.
$('#addpart').click(function(){
var loop = $('#loop').val();
var html;
html = '<p>';
html += '<input type="text" name="part[]" style="margin-left:20px;" class="text medium" id="part" placeholder="SP partnumber" />';
html += '<input type="text" name="qty[]" style="margin-left:20px;" class="text small" placeholder="Qty" />';
html += '<input type="text" style="margin-left:20px;" class="text small" id="price" placeholder="Price" tabindex="-1" readonly />';
html += '</p>';
for (i = 0; i < loop; i++) {
$("#form").append(html);
}
});
So when your post this form we dont know how many fields it will be. Sometimes it will be 5 order lines, sometimes 10.
So i start using [] in my input field.
The input name attribute will be like this: "part[]".
The form will be validated with the class Validation.
To show my class this page will be very long ghehe.
Here is a little snippet how to use this class/function so you know the structure.
if(toxInput::exists()){
if(toxtoken::check(toxInput::get('token'))){
$toxValidate = new toxValidate();
$toxValidation = $toxValidate->check($_POST, array(
'name' => array(
'required' => true,
'min' => 2,
'max' => 50
)
));
if($toxValidation->passed()){
etcetcetc..
So with the order form it should be something like this:
$toxValidate = new toxValidate();
$toxValidation = $toxValidate->check('$_POST', array(
'part1' => array('required' => TRUE, 'maxlength' => 14),
'part2' => array('required' => TRUE, 'maxlength' => 14),
'part3' => array('required' => TRUE, 'maxlength' => 14),
'part4' => array('required' => TRUE, 'maxlength' => 14),
'part5' => array('required' => TRUE, 'maxlength' => 14)
));
How can i print this line 'part1' => array('required' => TRUE, 'maxlength' => 14) for every filled in line. I tried serveral ways with foreach and [].
All didnt work.. :(
I suppose that you need to extend your Validation class to be able to validate arrays in the most comfortable way.
You can try to handle array variables like this (just an example):
$toxValidate->check($_POST, [
'name' => [
'required' => TRUE,
'min' => 2,
'max' => 50,
],
'qty' => [
'required' => TRUE,
'array' => TRUE,
'min' => 2,
'max' => 14,
],
]);
Under the hood of your Validation class, just loop through the values of the passed qty array if is_array($toxValue) and apply your rules to every member of that array (min, max, etc.).
Also, I suggest to refactor your Validation class: use callbacks or class member functions to call separate validation rules (not the best OOP-way, but feasible for easy cases). Like this:
class Validation
{
...
public function ruleMax($value)
{
... // Validate value max
}
public function ruleMin($value)
{
... // Validate value min
}
}
With this approach you won't need to fully rewrite your check function if you need to add more validation rules to your class (or subclass).
By the way, I suggest to see how it's made in popular frameworks like Laravel:
https://laravel.com/docs/5.4/validation#validating-arrays
And the class itself as an easy example (not the best of course) of rules decoupling: https://github.com/laravel/framework/blob/5.1/src/Illuminate/Validation/Validator.php

Zend 2 Form Validator 'InArray' - Complicated array returning invalid

I am trying to implement the 'InArray' validator in Zend 2 on a form and it keeps on returning invalid. Here is the code:
The Form Element setup:
$enquiryType = new Element\Select('enquiryType');
$enquiryType->setLabel('* What is your enquiry about?')
->setLabelAttributes(array('class' => 'sq-form-question-title'))
->setAttribute('class', 'sq-form-field required')
->setValueOptions($enquiryTypes);
The Filter/Validator setup:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes));
And here is the array that gets passed into $enquiryTypes via the module.config.php file
'enquiryCategories' => array(
'empty_option' => 'Please select an option',
array(
'label' => 'General enquiries',
'options' => array(
'skype' => 'Skype with your library feedback',
'question' => 'Ask a question',
'feedback' => 'Library feedback',
'eresource' => 'Electronic resources (e.g. e-book, e-journal, database)',
'webbridge' => 'WebBridge Problems',
'dro' => 'DRO'
)
),
array(
'label' => 'Application to review',
'options' => array(
'10400' => 'I\'ve returned the item',
'10401' => 'I didn\'t know about overdue points but now I have some',
'10402' => 'Why did I get this invoice?',
'10403' => 'The item I borrowed is lost',
'10404' => 'The item I borrowed has been damaged',
'10405' => 'I never got/had the book',
'10406' => 'Other'
)
)
),
I have tried different variations of this (using the recursive validation also) but have not been able to work this out.
One thing that I'd try, is as follows:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes['enquiryCategories']));
The reason I say that, is that it looks like you might be creating an array inside of the array perhaps. Unless I've misunderstood the description.
If that isn't working for you then maybe you might need to explore the Explode option as pointed out in the following question
ZF2: How do I use InArray validator to validate Multiselect form element?
Good luck.
I finally got a working solution for this. I feel there should be a better solution but I could not find one.
Here is the filter I used:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => array_keys(
$enquiryTypes[0]['options']+$enquiryTypes[1]['options']
)));
$enquiryType->getFilterChain()
->attach(new Filter\StringToLower())
->attachByName('StripTags');
Basically I had to disect the array options into a straight associative array. As the array remains static in this instance then this works well.
If the data becomes dynamic then something more would be required (loop through and find the 'option' key, add children to filter array etc...)

PHP Help for Echoing Variables

I'm a beginner in writing PHP, but working on developing themes in WordPress.
I have no idea how to echo my style option within my front-page.php.
My meta.php:
$meta_style = array();
$meta_style['meta_style'] = array(
'dash_icon' => 'list-view',
'title' => __('Section Settings', 'fluent'),
'description' => __('These are general section settings.','fluent'),
'context' => 'normal',
'priority' => 'high',
'option_name' => 'meta_style',
'caps' => array(),
'fields' => array(
'style' => array(
//...
'type' => 'select',
'options' => array(//option value = option label
'value' => 'white',
'value2' => 'black'
),
'multiple' => false,//allow multiple values to be selected - default false
'placeholder' => 'white'//placeholder text for the element
),
),
);
My front-page.php (it's wrapped in a BUTTON just a see if the variable echoes):
<button>
<? if($meta = get_post_meta($post->ID)){ if($meta['style'] == true){ echo $meta['value']; } } ?>
</button>
Can anyone provide an additional examples on how to echo other types, such as 'type' => 'text'?
I dont know exactly what you want, but you should:
1 - See if you're echoing the right information
2 - Use var_dump()
In your first code example you have a variable $meta_style which is a map. It has one key, 'meta_style' that leads to a next map. Inside that inner map you have the keys 'dash_icon' and so on. So for example this should echo the string 'normal':
echo $meta_style['meta_style']['context'];
However, in your second example, you have a variable $meta which is also a map, having keys 'style' and 'value'. You could echo those with:
echo $meta['style'];
echo $meta['value'];
Based on your example, I have no idea what these should do or how they should be related, or what their meaning should be.

setting Default Text inside Yii textarea

I'm new to Yii and i am facing issues with it. Hope some pros here can help me solve this. I bought a script online and i am editing it to my needs.
I want to have a text area with default texts. Example;
Name:
Age:
Sex:
what it is generating now:
<textarea class="span vertical medium" name="MAccount[accountInfo]" id="MAccount_accountInfo"></textarea>
what i want it to generate,or something like this :
<textarea class="span vertical medium" name="MAccount[accountInfo]" id="MAccount_accountInfo">Name: <br> Age: <br> Sex:</textarea>
something like above. But i only able to produce a textarea with blank/no content.below is my code,it is located inside a worklet.;
public function properties() {
$properties = array(
'elements' => array(
'accountInfo' => array(
'type' => 'textarea',
'class' => 'span vertical medium',
),
'email' => array(
'disabled' => true,
'append' => $this->model()->role == 'unverified' ? $this->t('unverified') : $this->t('verified'),
'hint' => $this->model()->role == 'unverified' ? $this->resendBtn() : '',
),
wm()->get('project.edit.buttons', array('step' => $this->step, 'projectId' => $this->project->id))->render('tools', array(), true),
),
'model' => $this->model(),
'class' => 'projectEditForm',
);
return $properties;
}
Default values are set in your model, not in your view. So you have to look in your model/ directory and locate the right model there. There you can add
public $accountInfo = "Name:\nAge:\nSex:";
<?php echo CHtml::activeTextArea($form,'abc',array('value'=>"12"));?>
$form->abc="Your text goes here"
it may help you

Retain Checkbox values in Yii gridview pagination

I have a gridview which contains a checkbox column and also uses pagination. When I check some checkboxes in the first page and navigate to the second page and check another one in the second page, the options I checked in the first page is not retained there. Is it posssible to retain the checkbox values during pagination?
Code for Gridview is
$widget = $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
//'filter' => $model,
'ajaxUpdate' => true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header' => 'Selected',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
array(
'name' => 'demo',
'type' => 'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
),
));
Edit:
Extension for remembering the selected options in gridview,check this link Selgridview
Thanks to bool.dev
You could use sessions/cookies to store the checked values. I'm not very sure how to make cookies work, so i'll tell you how to do it with sessions. Specifically the user session that yii creates.
Now to use sessions we need to pass the checked (and unchecked) ids to the controller, therefore we'll modify the data being sent to the controller on every ajax update(i.e between paginations), to do this we exploit the beforeAjaxUpdate option of CGridView.
I'm also using CCheckBoxColumn instead of the following in your code(of course you can modify the solution to suit your own needs):
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
GridView Changes:
<?php $this->widget('zii.widgets.grid.CGridView', array(
// added id of grid-view for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'id'=>'first-grid',
'dataProvider'=>$model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
// added this piece of code
'beforeAjaxUpdate'=>'function(id,options){options.data={checkedIds:$.fn.yiiGridView.getChecked("first-grid","someChecks").toString(),
uncheckedIds:getUncheckeds()};
return true;}',
'ajaxUpdate'=>true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
/* replaced the following with CCheckBoxColumn
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' =>'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
*/
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header'=>'Selected',
'id'=>'someChecks', // need this id for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'checked'=>'Yii::app()->user->getState($data->email_id)', // we are using the user session variable to store the checked row values, also considering here that email_ids are unique for your app, it would be best to use any field that is unique in the table
),
),
));
?>
Pay special attention to the code for beforeAjaxUpdate and CCheckBoxColumn, in beforeAjaxUpdate we are passing checkedIds as a csv string of all the ids(in this case email_ids) that have been checked and uncheckedIds as a csv string of all the unchecked ids, we get the unchecked boxes by calling a function getUncheckeds(), which follows shortly. Please take note here, that when i was testing i had used an integer id field (of my table) as the unique field, and not an email field.
The getUncheckeds() function can be registered like this anywhere in the view file for gridview:
Yii::app()->clientScript->registerScript('getUnchecked', "
function getUncheckeds(){
var unch = [];
/*corrected typo: $('[name^=someChec]') => $('[name^=someChecks]') */
$('[name^=someChecks]').not(':checked,[name$=all]').each(function(){unch.push($(this).val());});
return unch.toString();
}
"
);
In the above function pay attention to the selectors and each and push function.
With that done, we need to modify the controller/action for this view.
public function actionShowGrid(){
// some code already existing
// additional code follows
if(isset($_GET['checkedIds'])){
$chkArray=explode(",", $_GET['checkedIds']);
foreach ($chkArray as $arow){
Yii::app()->user->setState($arow,1);
}
}
if(isset($_GET['uncheckedIds'])){
$unchkArray=explode(",", $_GET['uncheckedIds']);
foreach ($unchkArray as $arownon){
Yii::app()->user->setState($arownon,0);
}
}
// rest of the code namely render()
}
That's it, it should work now.
For developing that scheme you would need to know working of what happens when you navigate.
When ever you navigate to a pagination page ajax calls are made and new data is received and it is fetched from CActive Record or what ever the data source. New data is in accordance of database records or source records. when you come back to previous page again Ajax call is made and content is updated so same comes as it is in database.
what i feel is you should save data of checked items temporary and make it permanent if action is made.
You can do something like this
<script type="text/javascript">
$("input:checkbox").click(function () {
var thisCheck = $(this);
if (thisCheck.is (':checked')){
// do what you want here, the way to access the text is using the
// $(this) selector. The following code would output pop up message with
// the selected checkbox text
$(this).val());
}
});
</script>
you can save temporary storage somewhere
Also make this work on normal form submit:
I wanted to add this as a comment on bool.dev's answer, but I do not have enough reputation to do that yet. So I had to put it in a separate answer.
bool.dev, your answer is great and it works well, thanx.
However, as intended, it only works when ajax calls update the gridview. I have the gridview forming part of a form, so I wanted it to also work on normal submission of the form, otherwise the checkboxes are not loaded again when there are other validation errors on the form.
So, in ADDITION to what you did, I added hidden fields on my form e.g.:
<input type="hidden" name='checkedBox1' id='checkedBox1' value=''>
<input type="hidden" name='uncheckedBox1' id='uncheckedBox1' value=''>
Then, before submitting the form, my sumbit button runs your getChecked() and getUncheckeds() functions and store their results in the hidden fields:
if ($('#checkedBox1').length >0) {$('[name=checkedBox1]').val(getChecked());}
if ($('#uncheckedBox1').length >0) {$('[name=uncheckedBox1]').val(getUncheckeds());}
In the controller, besides from checking for $_GET['checkedIds'], you also check for $_POST['checkedBox1'] and store its values to session in the same way you do for $_GET['checkedIds'], using the same session variable.
Do the same with $_POST['uncheckedBox1'].
That should work.

Categories