I have a project that I need to finish before July, it's for school.
It was all going well until I started having problems with an array that comes from my database.
Please keep in mind that this is my first time with PHP and I'm learning as I am doing:
My database has a table named "Pessoas" and another named "Pessoas_Pessoas". The second was to keep the record of relationships between entries on the "Pessoas" table ( for example, if the ID 1 had a relationship with the ID 2, the information would be kept on "Pessoas_Pessoas" ).
The tricky part is that I am supposed to use PHP to prevent the user from duplicating a relationship.
A good example would be Facebook's friend system:
If I would be friend's with John, it wouldn't appear his profile on the "People you might know" section.
Since I am using MVC and Slim Framework, I managed to get what I want from the database on the model, but I have this problem on the Controller:
This is an image from the table "Pessoas_Pessoas", being id_PessoasA the id of the profile being visualized and id_PessoasB the id of the profile I'm trying to make a relationship with
I managed to get 5 profiles to test this feature and I managed to get those relationships as well, but the problem is that when I try to verify if the id of each profile is the same has id_PessoasB to then unset from the array, but it only works one time even if the condition is true. Here's the code:
foreach ($resultadoRelacao as $key => $value) {
foreach ($resultadoRelacao0 as $key0 => $value0) {
if ($value0['id'] == $value['id_PessoasB']) {
$indice = array_search($value0['id'], $resultadoRelacao0);
unset($resultadoRelacao0[$indice]);
}
}
}
Thanks for your time and please ask anything if needed. I'm not really sure what's needed anymore, I'm stuck for 2 weeks.
As you are using the foreach() to go through the array and you have matched the element against the one your looking for, you can then use the key value (in this case $key0) of the foreach() to remove the element your currently looking at...
foreach ($resultadoRelacao as $key => $value) {
foreach ($resultadoRelacao0 as $key0 => $value0) {
if ($value0['id'] == $value['id_PessoasB']) {
unset($resultadoRelacao0[$key0]);
}
}
}
foreach ($resultadoRelacao as $key => $value) {
foreach ($resultadoRelacao0 as $key0 => $value0) {
if ($value0['id'] == $value['id_PessoasB']) {
if(($indice = array_search($value0['id'], $resultadoRelacao0)) !==false){
unset($resultadoRelacao0[$indice]);
}
}
}
}
Related
I'm having a CRUD issue. I'm not sure of the right syntax to make my Controller create table rows with the right relationships to other tables, namely while in a loop.
I'm creating a dictionary where a Term hasMany Glosses, a Gloss belongsToMany Sentences (many Sentences may have a particular Term->Gloss) & a Sentence belongsToMany Glosses (a Sentence has several Term->Glosses).
In the Entry Creator, I have the field "term[term]" & several like "glosses[0][gloss]". In the store() method in the TermController, I have:
$term = Term::create($term);
foreach ($request->glosses as $gloss) {
if ($gloss['gloss'] == true) {
$gloss = array_merge($gloss, ['term_id' => $term->id]);
$gloss = Gloss::create($gloss);
}
}
So far, so good. Now, I think in theory I would link a Sentence to a Gloss like this:
foreach ($request->sentences as $sentence) {
if ($sentence['sentence'] == true) {
$sentence = Sentence::create($sentence);
$sentence->glosses()->attach($gloss);
}
}
However, I know this would only work if I were trying to attach every Sentence in the form to a single Gloss. In reality, any Term may have >1 Gloss & each one may have >1 Sentence that I only want to associate with the Gloss that is currently being looped through. I was thinking the following could be a solution:
foreach ($request->glosses as $glossKey => $gloss) {
if ($gloss['gloss'] == true) {
$gloss = array_merge($gloss, ['term_id' => $term->id]);
$gloss = Gloss::create($gloss);
}
foreach ($request->sentences as $sentence) {
if ($request->input('glossKey') == $glossKey) {
$sentence = Sentence::create($sentence);
$sentence->glosses()->attach($gloss);
}
}
}
In the HTML, I would have:
<div class="auth-field">
<x-label for="sentences[0][sentence]" :value="__('Sentence')" />
<x-input id="sentences[0][sentence]" name="sentences[0][sentence]" ... glossKey="1" />
</div>
My thought was that if we are on the first loop ($glossKey == 1), the Controller would scan every sentence & only create the ones that are identified in the HTML as belonging to the first loop. However, I'm not sure if it's even allowed to add this sort of custom identifier to the HTML input, because when I dd($request->sentences), the result is very odd: it only shows me the very last sentence, even if I specify $request->sentences[0]. In any case, the glossKey attribute doesn't seem to be part of the object at all.
Any ideas on how I can accomplished the desired behavior?
This is a bit hard to solve for me. I want to prevent duplication between same id's item in DB. But it's ok to duplicate between different id.
For example when the scraping bot run. It scrapes a website. Taking "plan names" from different pages. Some times different pages has same plan name. it means duplication is ok for the different id. But not the same page's item(I mean same id)
The code block below. It prevent all duplication. I am not sure how to improve it.
foreach($planNames as $k => $names)
{
$database = [];
$database = [
"place_id" => $insertedPlaceId,
"plan_name" => $names,
"plan_price" => $planPrice[$k],
"people" => $people[$k]
];
if ($place = Plan::where("plan_name", "=", $names)->first()) {
} else {
Plan::insertGetId($database);
$this->line("Plans inserted.");
}
}
If I understand correctly you want to prevent same plan_name in same place_id therefore you should query this
$place = Plan::where("plan_name", "=", $names)->where("place_id", $insertedPlaceId)->first();
then check if its empty or not.
Hope it helps. If my understanding on your question is wrong then kindly correct me. Thanks
webform_get_submissions() in Drupal 7 return all the Webform submissions, the problem is that I want to return the submission that falls between 2 date
ex:
get webform submissions that have been submitted between 16 April 2018 and 28 April 2018.
Let me share a workaround that I came up with, maybe it will help you to find a full-size solution.
You actually can use a filter in the function webform_get_submissions not only by nid or sid but apparently by any other field. In this case, there is possible to use a filter by a field named submitted:
$submissions = webform_get_submissions(array('nid' => $node->nid, "submitted" => "1503753434"));
It will result in recieiving a submission which field submitted is exactly equal to 1503753434. To get all submissions which are, for example, newer than 1503753434 one way is inside a file includes/webform.submissions.inc for the function webform_get_submissions_query change this part:
foreach ($filters as $column => $value) {
$pager_query->condition($column, $value);
}
to this part:
foreach ($filters as $column => $value) {
if ($column == "submitted") {
$pager_query->condition($column, $value, ">");
} else {
$pager_query->condition($column, $value);
}
}
This would result in getting submissions which are newer than 1503753434. By analogy we can add < filter or any other filters.
The problem with this workaround is that it requires to change a source file of Drupal and also it requires implementing a simple parsing by hand in case we want to have several conditions for one field name.
Again I find myself at the mercy of the stackoverflow community!
I've gone over to use CodeIgniter for my PHP projects and it's been a breeze so far, hoever I've gotten stuck trying to update a database field with some post data.
My array is the usual: array(name => value, name => value, name => value);
which again is populated from the submitted $_POST data.
Similarly to the array, I have a database table with 2 fields: setting and value, where the names under setting corresponds to the array keys and value to the array keys' value.
(Did I explain that right?)
Nonetheless, I've been trying for a little while now to get this to work as it should, but, I'm really just waving my hands around in the dark.
I hope some of you bright minds out there can help me with this annoying issue!
Edit:
Thanks to everyone who replied! I managed to produce the result that I wanted with the following code:
foreach ($form_data as $key => $val)
{
$this->db->where ('setting', $key);
$this->db->set ('value', $val);
$this->db->update ('recruitment');
}
Now, I tried following up with this by adding:
if ($this->db->affected_rows() >= '1') { return true; }
return false;
To my model, and
if ($this->RecruitmentSettings->Update($form_data) == TRUE)
{
redirect('recruitment/success');
}
to my controller, but it's not working as expected at all. Any ideas what I'm doing wrong?
There are a lot of questions here. Do you already have values in the database and you want to update them? Or do you want to put in new data every time? The answer depends on that.
What you want is the insert_batch() or update_batch() methods of the active record class (if that's what you're using for the db).
foreach($post_array as $key => $value)
{
$settings[] = array(
'setting' => $key,
'value' => $value
);
}
$this->db->insert_batch('your_db_table', $settings);
OR, for updates:
$this->db->update_batch('your_db_table', $settings, 'setting');
You could do a query to check for settings and do insert_batch or update_batch depending on if there are results. If you wanted to insert every time, you could delete the rows in the table before you do the insert. I wouldn't do that without a transaction, however.
So you want to store the array data in the database? You could do this
Model
foreach ($data as $key => $item)
{
$this->db->set ('setting', $key);
$this->db->set ('value', $item);
$this->db->insert ('table_name');
}
return ($this->db->affected_rows() > 0);
Controller
if ($this->RecruitmentSettings->Update($form_data))
{
redirect('recruitment/success');
}
else
{
echo "error";
}
Attached code taken from cakephp bakery, where someone uploaded a sample about custom validation rules.
class Contact extends AppModel
{
var $name = 'Contact';
var $validate = array(
'email' => array(
'identicalFieldValues' => array(
'rule' => array('identicalFieldValues', 'confirm_email' ),
'message' => 'Please re-enter your password twice so that the values match'
)
)
);
function identicalFieldValues( $field=array(), $compare_field=null )
{
foreach( $field as $key => $value ){
$v1 = $value;
$v2 = $this->data[$this->name][ $compare_field ];
if($v1 !== $v2) {
return FALSE;
} else {
continue;
}
}
return TRUE;
}
}
In the code, the guy used a foreach to access an array member which he had its name already!
As far as I understand - it's a waste of resources and a bad(even strange) practice.
One more thing about the code:
I don't understand the usage of the continue there. it's a single field array, isn't it? the comparison should happen once and the loop will be over.
Please enlighten me.
In the code, the guy used a foreach to access an array member which he had its name already! As far as I understand - it's a waste of resources and a bad(even strange) practice.
The first parameter is always an array on one key and its value, the second parameter comes from the call to that function, in a block named as the key... So, all you need is to send the key and no need to iterate
The code uses foreach to iterate through $field, which is an array of one key value pair. It all starts when the validation routine invokes identicalFieldValues, passing it two values - $field, which would be an array that looks like:
array (
[email] => 'user entered value 1'
)
The second parameter $compare_field would be set to the string confirm_email.
In this particular case, it doesn't look like it makes a lot of sense to use foreach since your array only has one key-value pair. But you must write code this way because CakePHP will pass an array to the method.
I believe the reason why CakePHP does this is because an array is the only way to pass both the field name and its value. While in this case the field name (email) is irrelevant, you might need in other cases.
What you are seeing here is one of the caveats of using frameworks. Most of the time, they simplify your code. But sometimes you have to write code that you wouldn't write normally just so the framework is happy.
One more thing about the code: I don't understand the usage of the continue there. it's a single field array, isn't it? the comparison should happen once and the loop will be over. Please enlighten me.
Indeed. And since there are no statements in the foreach loop following continue, the whole else block could also be omitted.
A simplified version of this would be:
function identicalFieldValues($field=array(), $compare_field=null)
{
foreach ($field as $field) {
$compare = $this->data[$this->name][$compare_field];
if ($field !== $compare) {
return FALSE;
}
}
return TRUE;
}
And I agree with you, the loop only goes through one iteration when validating the email field. regardless of the field. You still need the foreach because you are getting an array though.