Cakephp 3 How to make session array - session

I am trying to write session in controller. My structure is
$_SESSION['a'][0] = 1;
$_SESSION['a'][1] = 2;
$_SESSION['a'][2] = 3;
And I am trying this
Configure::write('Session', ['a' =>'1'])
But it is not working. How do this in cakephp 3 way

To write variable in Session in CakePHP 3 you need to write following code :
$this->request->session()->write('Your Key',Your_array);
To know more information you can visit here :
http://book.cakephp.org/3.0/en/development/sessions.html
To make things perfectly clear:
// code writing array to session
$a = [ "abc" => "word", "123" => 42, "?" => $b ];
$a["more"] = "if you need to add";
$a[] = "whatever";
$this->request->session()->write( 'my_array', $a );
// code reading array from session
$recall = $this->request->session()->read( 'my_array' );
debug( sprintf( "What's the word? [%s]", $recall["abc"] ) );

You can simply use
$session->write([
'key1' => 'blue',
'key2' => 'green',
]);
I am refering to
http://book.cakephp.org/3.0/en/development/sessions.html#reading-writing-session-data

The answer is that this cannot be done in CakePHP 3.x
In vanilla PHP, it's possible to do this:
<?php
session_start();
$_SESSION['a'][0] = 1;
$_SESSION['a'][1] = 2;
$_SESSION['a'][2] = 3;
var_dump($_SESSION);
?>
Which will output:
array(1) {
["a"]=> array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
}
This is correct, and what should happen.
In CakePHP, you cannot specify arrays in the session key. For example:
$this->request->session()->write('a[]', 1);
$this->request->session()->write('a[]', 2);
$this->request->session()->write('a[]', 3);
Will not work.
If you remove the [] the value will get overwritten. For example:
$this->request->session()->write('a', 1);
$this->request->session()->write('a', 2);
$this->request->session()->write('a', 3);
The value of $this->request->session()->read('a') would be 3. The values 1 and 2 have been overwritten. Again, this is to be expected because you're overwriting the key a each time. The equivalent vanilla PHP for this is:
$_SESSION['a'] = 1;
$_SESSION['a'] = 2;
$_SESSION['a'] = 3;
Due to the lack of an indexed array, $_SESSION['a'] gets overwritten each time. This is normal behaviour. It needs to have the indexes (e.g. ['a'][0], ['a'][1], ...) to work!
The other answers where they have given things like key1 and key2 are not appropriate. Because there are many situations where you want everything contained within an indexed array. Generating separate key names is wrong for this type of scenario.

My edit of the accepted answer was rejected, so I present the - seemingly necessary - explicit code example, for the benefit of #Andy and others.
// code to write to session
$a = [ 0 => "zero", 1 => "one", 2 => "two" ];
$a[] = "three";
$this->request->session()->write( 'my_array', $a );
// code to read from session
$z = $this->request->session()->read( 'my_array' );
debug( $a[3] ); // outputs "three"

Related

Laravel: Access Rules::in variable items

How to access the items listed in an Illuminate\Validation\Rules\In variable ?
use Illuminate\Validation\Rules\In;
$foo = Rule::in('a', 'b');
$foo->toString() // error
The only way I found to show it is:
>>> dump($foo)
Illuminate\Validation\Rules\In^ {#3512
#rule: "in"
#values: array:2 [
0 => "a"
1 => "b"
]
}
you can convert that Illuminate\Validation\Rules\In to collection then take the result array:
$foo = Rule::in('a', 'b');
$values = collect($foo)->values()[1];
to get the string Representation from it:
$stringRepresentation=$foo->__toString();

Check if a value is present in a comma separated varchar string

I have a record "id_zone" in database that store cites id like this $abilitato->id_zone = '1, 2, 3, 9, 50'
From laravel i need to check if a value passed from url is present in this field. The following work only if i have a single value
$abilitato = \App\Models\Servizi::where('id', $servizio)->('id_zone', $verifica->id_citta)->first();
if(!empty($abilitato) && empty($verifica->multicap)) {
$json = ['CAP' => '1' , 'DEB' => $cap ];
}else{
$json = ['CAP' => '0' , 'DEB' => $cap];
}
i need to check if
If you want to know if a value is in your array you can use this functiĆ³n to know it.
here is a example:
// First convert your string to array
$myString = $abilitato->id_zone; // Here your string separate with comas
$array = explode(',', $myString); // Here convert it to array
$value = 7; // Here you put the value that you want to check if is in array
// Check if exist a value in array
if (in_array($value, $array)){
echo "Exist in array";
}else{
echo "No exist in array";
}
This is the documentation of these functions: explode , in_array
Regards!

Laravel Eloquent: getDictionary with object value as value of result

Currently, $mymodel->getDictionary(); returns:
What I am looking for is this:
"7gct5YaTvuxBmY2" => "Leadership",
"7NrXZepqczMSHqM" => "...",
"..." => "...",
...
The only way I have managed to do this is:
$construct_obj = OrganizationalConstruct::where('is_root', 0)->where('organization_id', $this->current_company->company_id)->get();
$constructs = [];
$constructs[''] = '';
for ($i = 0; $i < count($construct_obj); $i++) {
$constructs[$construct_obj[$i]->organizational_construct_id] = $construct_obj[$i]->construct_name;
}
Is there an easier way of getting the format "key" => "speific-column-value" ?
I have tried:
keyBy
lists
getDictionary
map
You should call pluck directly on the query, so that you don't pull down all attributes for all models:
$dictionary = OrganizationalConstruct::where('is_root', 0)
->where('organization_id', $this->current_company->company_id)
->pluck('construct_name', 'organizational_construct_id');
Note: lists is deprecated, and will be removed in Laravel 5.3. Use the pluck method instead.
Quite a simple answer actually. It looks like the lists methods can accept more than 1 argument, allowing me to pass through the id as parameter 1 and name as parameter 2 giving me the required result of key => value in one line.
So this:
$construct_obj = OrganizationalConstruct::where('is_root', 0)->where('organization_id', $this->current_company->company_id)->get();
$constructs = [];
$constructs[''] = '';
for ($i = 0; $i < count($construct_obj); $i++) {
$constructs[$construct_obj[$i]->organizational_construct_id] = $construct_obj[$i]->construct_name;
}
becomes this:
$construct_obj = OrganizationalConstruct::where('is_root', 0)->where('organization_id', $this->current_company->company_id)->get();
$construct_obj->lists('construct_name', 'organizational_construct_id');
Hope this helps someone else.

CodeIgniter - Insert a new row in db with a boolean value

When CodeIgniter is inserting a row into a DB, it doesn't encode PHP booleans into a form MySQL needs.
For example:
$new_record = array(
"name" => "Don",
"is_awesome" => true
);
This will enter into MySQL as this:
name (varchar) is_awesome (tinyint)
Don 0
Anyone know a good way to deal with this? I've been writing (is_awesome == true) ? 1 : 0; then setting the array value, but that sucks.
you can't add true or false to a TINYINT in mysql. you should do 1 or 0 like this
$new_record = array(
"name" => "Don",
"is_awesome" => 1 //1 means it's true
);
$query = $this->db->insert('table_name', $new_record);
then just when you fetch it consider 0 as false and 1 as true
Update:
you can create a function called tinyint_decode like this:
public function tinyint_decode($result = array(), $decode_set = array())
{
//$result is what you got from database after selecting
//$decode_set is what you would like to replace 0 and 1 for
//$decode_set can be like array(0=>'active', 1=>'inactive')
//after fetching the array
$result->is_awesome = ($result->is_awesome == 1 ? $decode_set[1] : $decode_set[0]);
return true;// or anything else
}
this way you can interpret 0 and 1 by anything you like whether it's true and false, active and inactive, or anything else just by passing $decode_set array.
MySQL doesn't have boolean values. What I usually do is:
1) Have a field of length char(1) and say 'Y' or 'N'
OR
2) Have a numeric field and say '1' or '0'
The one method to encode you mentioned is the only way to do it. If it's an extra step, I would just get rid of boolean in the PHP code itself and make it a '1-0' or 'Y-N'

Simple Math based captcha

reCaptcha is now difficult to read (decipher actually). So I am looking for an alternative captcha system to use.
I am thinking of using a simple Math based system, for example : "What is 2+5".
Are there any such plugins, or, ideas on how to build my own?
(Not complicated math like this one)
PHP - Generates a simple addition or subtraction math question, randomly alternating between displaying numbers (10 - 3) and words (seven plus five) and accepts answers numerically (14) or as words (fourteen). Returns an array representing the components of the equation
[0] - first variable value, as string, like either '4' or 'four'
[1] - second value, the operator, like '+' or 'plus'
[2] - third value, the second variable, like 'ten' or '10'
[3] - the answer, in numerical form, like '14'
[4] - the answer, in text form, like 'fourteen'
So just print the equation to the page, store the array in $_SESSION, and then check the answer the user provides.
<?php
// array of numbers and their corresponding word versions
// you can simply do $wordNumbers[6] and get 'six'
$wordNumbers = array(
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty'
);
/*
*
* returns an array representing components of a math captcha
* [0] - first variable value, as string, like either '4' or 'four'
* [1] - second value, the operator, like '+' or 'plus'
* [2] - third value, the second variable, like 'ten' or '10'
* [3] - the answer, in numerical form, like '14'
* [4] - the answer, in text form, like 'fourteen'
*/
function getMathCaptcha(){
global $wordNumbers;
$equation = array();
// get first number, between 7 and 13 inclusive
$n1 = rand(7, 13);
$r = rand(0,1);
// return $n1 as digit or text
if ($r == 0) {
$equation[0] = $n1;
} else {
$equation[0] = $wordNumbers[$n1];
}
// get operator
$o = rand(0,1);
$r = rand(0,1);
if ($o == 0){
// subtraction
if ($r == 0) {
$equation[1] = '-';
} else {
$equation[1] = 'minus';
}
} else {
// addition
if ($r == 0) {
$equation[1] = '+';
} else {
$equation[1] = 'plus';
}
}
// get second number, between 0 and 7 inclusive, so no negative answers
$n2 = rand(1,7);
$r = rand(0,1);
// return $n2 as digit or text
if ($r == 0) {
$equation[2] = $n2;
} else {
$equation[2] = $wordNumbers[$n2];
}
// get answer
if ($o == 0){
$answer = $n1 - $n2;
} else {
$answer = $n1 + $n2;
}
// answer as digit and text
$equation[3] = $answer;
$equation[4] = $wordNumbers[$answer];
return $equation;
}
?>
have you tried a captcha method like mine below?
what are the downpoints of this captcha method
or are you specifically wanting to use a user-entry method?
How about using Captchator?
It's easy to implement and it just works! There are also code samples for PHP and Ruby out there, shouldn't be difficult to implement in other languages.
Math based captchas are weak and easy to pass, there are many spambots out there that know how to do the math :)
If I were to make a simple one, it would go along the lines of:
Make different items of categories, such as flowers, fruits, vegetables, and meats. Then design the captcha to ask for a total of a category.
For example:
Randomize the categories, choose 2 unique ones. So perhaps we got flowers and fruits.Next, ask the user: "If you have 3 roses, 4 oranges, and 6 apples, then how many fruits do you have?"
Simple pattern:
Get n-1 unique categories. Show n items, where each item belongs to one of the unique categories. Ask for a total from one category.
you can create a captcha like this on your own. All you have to do is create a function which will pick up a random number between the given list of numbers and call the function twice to pick up two random numbers.
Store the result in a session variable or any other variable so that you can verify it later.
below is an example coded in c#
Random a=new Random();
a.Next();//it will return you a non negative number
a.Next(min value,maximum value);//it will return you a number between the range specified.
Hope this helps

Resources