adding multiple entry in laravel - php

Below code works adding single single entry i want to store multiple parent_id and user_id
public function test($p_id, $pl_id)
{
$CheckRelationship = UsersRelationship::where('parent_user_id', $p_id )->where('child_user_id', $pl_id )->first();
if( $CheckRelationship )
{
return Response::json( [
'ok'=> false,
'message'=> 'The profiles are currently linked '
] ,422);
}
$user = User::find( $pl_id );
$user->p_id = $p_id;
$user->updated_by = $p_id;
//$user->status = 1;
$user->save();
$UsersRelationship = new UsersRelationship;
$UsersRelationship->parent_user_id = $parent_id;
$UsersRelationship->child_user_id = $player_id;
$UsersRelationship->save();
return Response::json( [
'ok'=> true,
'message'=> 'Linked',
] ,200);
}
I want to pass multiple value
$UsersRelationship = new UsersRelationship;
$UsersRelationship->parent_user_id = $parent_id; //single value passing
$UsersRelationship->child_user_id = $player_id; //single value passing
$UsersRelationship->save();
foreach($UsersRelationship as $k=>$values){
$UsersRelationship['parent_user_id'] = $values;
$UsersRelationship['child_user_id'] = $values;
$UsersRelationship->save();
}
doesn't work for me please suggest where i am mistaking early reply highly appreciated thanks in advance

Parameters in URLs will work only for a singular user relationship. If you wish to pass multiple relationships, JSON is your friend.
JSON Sample:
[
{
'parent_user_id': 1,
'child_user_id': 2,
},
{
'parent_user_id': 2,
'child_user_id': 2,
}
]
PHP controller function:
public function test(\Illuminate\Http\Request $request) {
//Pass your information through a GET parameter or POST it through a form
// 'user_relationship' is the name of the field, expecting data in JSON format
$user_relationships = json_decode($request->get('user_relationship'));
//array to store all relationships that were not linked
$relationshipsNotLinked= [];
//Loop through each relationship, attach where possible
foreach($user_relationships as $user_relationship_row) {
$CheckRelationship = UsersRelationship::where('parent_user_id', $user_relationship_row['parent_user_id'] )->where('child_user_id', $user_relationship_row['child_user_id'] )->first();
//If exists, we don't save.
if( $CheckRelationship ) {
$relationshipsNotLinked[] = $user_relationship_row['child_user_id'];
} else {
//Else we link relationship
//Not sure what the links below does..
//users cannot have `p_id` attribute, given that they may have multiple parents. Same goes for 'updated_by' attribute
$user = User::find( $user_relationship_row['parent_user_id'] );
$user->updated_by = $user_relationship_row['parent_user_id'];
//$user->status = 1;
$user->save();
//Save relationship
$UsersRelationship = new UsersRelationship();
$UsersRelationship->parent_user_id = $user_relationship_row['parent_user_id'];
$UsersRelationship->child_user_id = $user_relationship_row['child_user_id'];
$UsersRelationship->save();
}
}
if(count($relationshipsNotlinked)) {
//Some relationships were not linked, we display an error message
return Response::json( [
'ok'=> false,
'message'=> 'The following profiles are already linked: '.implode(',',relationshipsNotLinked),
] ,422);
} else {
//Display success message
return Response::json( [
'ok'=> true,
'message'=> 'Linked',
] ,200);
}
}

Related

Laravel get data out of foreach loop

The below code shows the error (on the line if ($response) {):
Undefined variable: response
I am checking the if condition inside the foreach because I wanted to check whether each id in the UserEnabledNotifications table exists in notifications table. Also dump($response); inside the if condition of foreach shows data.
Can I get the data in $response outside the foreach loop? What shall I try?
$notificationData = UserEnabledNotifications::all();
foreach ($notificationData->where('status', 'true') as $user => $value) {
if (Notifications::where('userEnabledNotificationsId', $value['id'])->exists() == false) {
$notificationTypeName = NotificationTypes::where('id', $value['notificationTypesId'])
->value('notificationTypeName');
$userData = User::where('id', $value['userId'])
->get()
->toArray();
$data = [];
$data['notificationTypesId'] = $value['notificationTypesId'];
$data['notificationTypeName'] = $notificationTypeName;
$data['userId'] = $value['userId'];
$data['email'] = $userData[0]['email'];
$data['recipientName'] = $userData[0]['FullName'];
$data['userEnabledNotificationsId'] = $value['id'];
$response = Notifications::create($data);
//dump($response);
$tags[] = $response;
}
}
if ($response) {
return response()->json([
'message' => 'success',
'data' => $tags,
'statusCode' => 200,
'status' => 'success'
], 200);
}
You define $response in first if body but you need $response = null above that.
You might create a private or protected variable, and put it outside, and then access it directly or via functions
$notificationData = UserEnabledNotifications::all();
private $reponse = null;
foreach ($notificationData->where('status', 'true') as $user => $value) {
if(Notifications::where('userEnabledNotificationsId',$value['id'])->exists()==false){
$notificationTypeName = NotificationTypes::where('id', $value['notificationTypesId'])->value('notificationTypeName');
$userData = User::where('id', $value['userId'])->get()->toArray();
$data = [];
$data['notificationTypesId'] = $value['notificationTypesId'];
$data['notificationTypeName'] = $notificationTypeName;
$data['userId'] = $value['userId'];
$data['email'] = $userData[0]['email'];
$data['recipientName'] = $userData[0]['FullName'];
$data['userEnabledNotificationsId'] = $value['id'];
$response = Notifications::create($data);
$tags[] = $response;
}
}
if ($response) {
return response()->json([
'message' => 'success',
'data' => $tags,
'statusCode' => 200,
'status' => 'success'
], 200);
}
But now each place you would need to check whether responses are null or not.
Why private or protected or public?
Check this answer : What is the difference between public, private, and protected?
I quote
public scope to make that property/method available from anywhere, other classes, and instances of the object.
private scope when you want your property/method to be visible in its own class only.
protected scope when you want to make your property/method visible in all classes that extend current class including the parent class.
Simply declare a null or an empty array in a $response variable and you will be able to get the data out of the loop!

How to set multi select value from array object in yii2 while updating

I have table which have multiple reference to ohter tables like
user
id name email
categories
id title
user_categories
user_id category_id
Here a user will have multiple category associated with him/her
I am able to save these successfully with new records like following
View File:
echo $form->field($package_categories, 'category_id')->dropDownList( ArrayHelper::map(
StudyMaterialCategories::find()->all(), 'id', 'title'),
['multiple' => true]
);
Save New record:
$model = new Packages();
$package_categories = new PackageCategories();
$request = Yii::$app->request;
if ($request->isPost) {
$transaction = Yii::$app->db->beginTransaction();
try {
$post = $request->post();
$model->load($post);
$model->save();
foreach ($post['PackageCategories']['category_id'] as $key => $value) {
$package_categories = new PackageCategories();
$package_categories->category_id = $value;
$package_categories->package_id = $model->id;
$package_categories->save();
}
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
} catch (Exception $ex) {
$transaction->rolback();
Yii::$app->session->setFlash("error", $ex->getMessage());
}
}
Till now It's running successfully.
But I'm stuck when going to update the table. The problem part is dropdown list. How to set multiple selected option as per database if I'm coming with array of object.
Have a look on the following code
$package_categories = PackageCategories::find()
->where('package_id=:package_id', ['package_id' => $id])->all();
if (count($package_categories) < 1) {
$package_categories = new PackageCategories();
}
$request = Yii::$app->request;
if ($request->isPost) {
$transaction = Yii::$app->db->beginTransaction();
try {
$post = $request->post();
$model->load($post);
$model->save();
$package_categories = new PackageCategories();
$package_categories->deleteAll(
"package_id=:package_id",
[':package_id' => $model->id]
);
foreach ($post['PackageCategories']['category_id'] as $key => $value) {
$package_categories = new PackageCategories();
$package_categories->category_id = $value;
$package_categories->package_id = $model->id;
$package_categories->save();
}
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
} catch (Exception $ex) {
$transaction->rolback();
Yii::$app->session->setFlash("error", $ex->getMessage());
}
}
if I try to get first object of the array $package_categories of only able to set selected one option
This is an example code of a model class Permit which has a many to many relationship with Activity through PermitActivity (pivot table model).
Model Class Activity
public class Permit extends \yii\db\ActiveRecord {
public $activities_ids;
...
public function rules() {
return [
...
[['activities_ids'], 'safe'],
...
];
}
...
// Method called after record is saved, be it insert or update.
public function afterSave($insert, $changedAttributes) {
// If this is not a new record, unlink all records related through relationship 'activities'
if(!$this->isNewRecord) {
// We unlink all related records from the 'activities' relationship.
$this->unlinkAll('activities', true);
// NOTE: because this is a many to many relationship, we send 'true' as second parameter
// so the records in the pivot table are deleted. However on a one to many relationship
// if we send true, this method will delete the records on the related table. Because of this,
// send false on one to many relationships if you don't want the related records deleted.
}
foreach($this->activities_ids as $activity_id) {
// Find and link every model from the array of ids we got from the user.
$activity = Activity::findOne($activity_id);
$this->link('activities', $activity);
}
parent::afterSave($insert, $changedAttributes);
}
...
// Declare relationship with Activity through the pivot table permitActivity
public function getActivities(){
return $this->hasMany(Activitiy::className(), ['id' => 'activity_id'])
->viaTable('permitActivity',['permit_id' => 'id']);
}
...
public function afterFind(){
parent::afterFind();
$this->activities_id = ArrayHelper::getColumn($this->activities, 'id');
}
}
This way the model class is the one responsible for creating and updating the relationship using the pivot table.
The most important thing is to have the relationship method declared correctly.
Edit
This is an example of the view using kartikv\widgets\Select2. I don't really know if dropDownList supports multiple select, however Select2 has so many useful features i usually use it over other options.
echo $form->field($model, 'activities')->widget(Select2::classname(), [
'data' => $data,
'options' => [
'placeholder' => '...'
],
'pluginOptions' => [
'allowClear' => true,
'multiple' => true,
],
]);

custom validation phalcon without library

I'm beginner in PHP and phalcon, I want to use custom validation and creating default value.
My controller is:
use Phalcon\Mvc\Controller;
class OspoController extends Controller
{
public function indexAction()
{
}
public function createAction()
{
$ospo = new Ospos();
// Store and check for errors
$success = $ospo->save(
$this->request->getPost(),
array('isEmailConfirmed', 'email', 'password', 'salt' ,'phoneNum', 'verifiedPhoneStatus', 'languageId', 'firstName', 'lastName', 'address', 'cityId', 'provId', 'countryId', 'postCode')
);
$data = array();
if ($success) {
$data[] = array(
'status' => 'success'
);
echo json_encode($data);
} else {
foreach ($ospo->getMessages() as $message) {
$msg = $message->getMessage();
$data[] = array(
'message' => $msg
);
}
echo json_encode($data);
}
$this->view->disable();
}
I want if isEmailConfirmed is null - I want to create value that isEmailConfirmed = 0;
How to change array value of getPost()?
(can I do this) Should i change the code with
$isEmailConfirmed = $_POST['isEmailConfirmed'];
and
$ospo->save($isEmailConfirmed, $etc, $etc)?
Thank you.
First of all, you can just store POST data in a variable. Then just check for null and assign default value if needed before saving.
$data = $this->request->getPost();
if (!isset($data['isEmailConfirmed']) {
$data['isEmailConfirmed'] = 0;
}
Another way is to save null value, but in that case you should set up DEFAULT for that column in your database table.

Inserting a JSON array from Laravel

I'm wondering how I can loop insert an array value to database through Laravel.
A sample of a Json is here:
[{"rid":"252","recipient_id":"1","email_type":"Body","to_cc_bcc":"to","start_dte":"2016-05-18","end_dte":""},{"rid":"252","recipient_id":"5","email_type":"Body","to_cc_bcc":"to","start_dte":"2016-05-18","end_dte":""}]
And my controller for storing such is this:
public function store()
{
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
'name' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return Redirect::to('reports')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
//Dump Recipient array
$cleanRecipients = json_decode(Input::get('test'), true);
foreach($cleanRecipients AS $value)
{
$report_recipient = new ReportRecipients;
$report_recipient->recipient_id = $value['recipient_id'];
$report_recipient->rid = $value['rid'];
$report_recipient->email_type = $value['email_type'];
$report_recipient->to_cc_bcc = $value['to_cc_bcc'];
$report_recipient->start_dte = !empty($value['start_dte']) ? $value['start_dte'] : null;
$report_recipient->end_dte = !empty($value['end_dte']) ? $value['end_dte'] : null;
}
$report_recipient->save();
// redirect
Session::flash('message', 'Report was Successfully Saved!');
return Redirect::to('reports');
What happens is that, it only stores the last set of values into the table and not all of them. I appreciate any help and thanks in advance.
Put your save() inside your loop. Also, you should do it in one transaction, to be atomic.
\DB::transaction(function() use($cleanRecipients) {
foreach($cleanRecipients AS $value) {
$report_recipient = new ReportRecipients;
$report_recipient->recipient_id = $value['recipient_id'];
$report_recipient->rid = $value['rid'];
$report_recipient->email_type = $value['email_type'];
$report_recipient->to_cc_bcc = $value['to_cc_bcc'];
$report_recipient->start_dte = !empty($value['start_dte']) ? $value['start_dte'] : null;
$report_recipient->end_dte = !empty($value['end_dte']) ? $value['end_dte'] : null;
$report_recipient->save();
});
You need to put $report_recipient->save(); inside your foreach loop.

Avoid similar controller actions

I am building a bundle for private messages between my users.
Here is my inbox action from my controller. What it does is fetches the current user's messages, it passes the query to KNPpaginator to display a part of them. I also save how many results to be displayed on the page in the database. One form is a dropdown that sends how many results to display per page. The other form is made of checkboxes and a dropdown with actions. Based on which action was selected, I pass the id's of the messages(selected checkboxes id's) to another function called markAction(which is also a page that can mark one single message by going to the specific url)
public function inboxAction(Request $request)
{
$messages = $this->getDoctrine()->getRepository('PrivateMessageBundle:Message');
$mymsg = $messages->findMyMessages($this->getUser());
$message_settings = $this->getDoctrine()->getRepository('PrivateMessageBundle:MessageSettings');
$perpage = $message_settings->findOneBy(array('user' => $this->getUser()));
$pagerform = $this->createForm(new MessageSettingsType(), $perpage);
$pagerform->handleRequest($request);
if ($pagerform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($perpage);
$em->flush();
}
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$mymsg,
$request->query->get('page', 1)/*page number*/,
$perpage ? $perpage->getResPerPage() : 10/*limit per page*/,
array('defaultSortFieldName' => 'a.sentAt', 'defaultSortDirection' => 'desc')
);
$form = $this
->createForm(
new ActionsType(),
$mymsg->execute()
);
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
$ids = array();
foreach ($data['checkboxes'] as $checkbox) {
$ids[] = $checkbox->getId();
}
$action = $data['inboxactions'];
$this->markAction($action, $ids);
return $this->redirectToRoute('private_message_inbox');
}
return $this->render(
'#PrivateMessage/inbox.html.twig',
array(
'messageList' => $pagination,
'form' => $form->createView(),
'pagerform' => $pagerform->createView(),
)
);
}
And the mark action user in my inbox controller. Based on one parameter, I apply the respective action to the second parameter, which is one message if the page was called through routing, and can be an array of messages if called through my inboxAction. I do a few consistency checks, and then mark my message.
public function markAction($action, $msgs)
{
if (!$msgs) {
$this->addFlash(
'error',
'Select at least one message!'
);
return;
} else {
if (!$action) {
$this->addFlash(
'error',
'Select one action to apply to your items!'
);
return;
} else {
$messages = $this->getDoctrine()->getRepository('PrivateMessageBundle:Message');
$em = $this->getDoctrine()->getManager();
$msg = $messages->findBy(array('receiver' => $this->getUser(), 'id' => $msgs));
$good = 0;
foreach ($msg as $isforme) {
$good++;
switch ($action) {
case 'spam': {
if ($isforme->getIsSpam() == false) {
$isforme->setIsSpam(true);
if (!$isforme->getSeenAt()) {
$isforme->setSeenAt(new \DateTime('now'));
}
$em->persist($isforme);
}
break;
}
case 'unspam': {
if ($isforme->getIsSpam() == true) {
$isforme->setIsSpam(false);
$em->persist($isforme);
}
break;
}
case 'viewed': {
if ($isforme->getSeenAt() == false) {
$isforme->setSeenAt(new \DateTime('now'));
$em->persist($isforme);
}
break;
}
case 'unviewed': {
if ($isforme->getSeenAt() != false) {
$isforme->setSeenAt(null);
$em->persist($isforme);
}
break;
}
default: {
$this->addFlash(
'error',
'There was an error!'
);
return;
}
}
$em->flush();
}
$this->addFlash(
'notice',
$good.' message'.($good == 1 ? '' : 's').' changed!'
);
}
}
if ($action == 'unspam') {
return $this->redirectToRoute('private_message_spam');
} else {
return $this->redirectToRoute('private_message_inbox');
}
}
Being kind of new to symfony, I'm not sure how good my markAction function is. I feel like it can be simplier, but I'm not sure how to make it.
Now, my actual question. How can I render other pages of my bundle, like Sent or Spam messages? The only lines from the inboxAction that I have to change are
$mymsg = $messages->findMyMessages($this->getUser());
to have it return spam or sent messages by the user, for instance.
and
return $this->render(
'#PrivateMessage/inbox.html.twig',...
so I actually return the respective page's view. I have already made the other pages and copied the code in the other actions, but I think I can make it so I write this code a single time, but don't know how.
Everything else is EXACTLY the same. How can I not copy and paste this code in all of the other actions and make it a bit more reusable?
You could strart to change your routing more dynamic:
# app/config/routing.yml
mailclient:
path: /mailclient/{page}
defaults: { _controller: AppBundle:Mailclient:index, page: "inbox" }
Resulting that this routes:
/mailclient
/mailclient/inbox
/mailclient/sent
/mailclient/trash
will all call the same action.
Now your method (Action) will get an extra parameter:
public function indexAction($page, Request $request)
{
// ...
}
Through this parameter you know what the user likes to see. Now you can start to write your code more dynamic. You can consider to add some private functions to your controller class that you can call from the indexAction or
you could simply create your own classes too.

Categories