I'm not understanding why this is not working?
I am working in php and specifically laravel.
When I run it I get an undefined variable exception.
I would think I would get the array of bad_rows?
Also on a side question, how could I refactor this to be cleaner? Should I extract the Excel method to its own function?
I basically am trying to import the list, add it to the database and then I will redirect to the main page with the list of rows that were not imported by flashing it.
Thanks!
public function subscriberImportList(Request $request)
{
\Excel::filter('chunk')->load($request->file('import_list'))->chunk(100, function($rows) use($request)
{
$bad_rows = [];
foreach($rows as $row)
{
if (is_null($row->name) || is_null($row->street_address) || is_null($row->city)){
array_push($bad_rows, $row->name);
}
else {
//New Subscriber Instance
$subscriber = new Subscriber;
//Set the name
$subscriber->name = $row->name;
//Set the street address
$subscriber->street_address = $row->street_address;
//Set the city,state zip
preg_match('/([^,]+),\s*(\w{2})\s*(\d{5}(?:-\d{4})?)/', $row->city, $city_state_zip_seperated);
if (!$city_state_zip_seperated) {
array_push($bad_rows, $row->name);
}
else {
$subscriber->city = $city_state_zip_seperated[1];
$subscriber->state = $city_state_zip_seperated[2];
$subscriber->zipcode = $city_state_zip_seperated[3];
//Persist the subscriber to the database
$subscriber->save();
}
}
}
return $bad_rows;
});
dd($bad_rows);
}
You have:
public function subscriberImportList(Request $request) {
\Excel::[..snip..], function($rows) use($request) {
$bad_rows = [];
^^^^^^^^^^------defined here
blah blah blah
});
dd($bad_rows);
^^^^^^^^---used here
}
$bad_rows is only ever defined INSIDE that function($rows) closure, which means it's a local variable inside the closure, and exists nowhere else. So when you try dd($bad_rows), you are using an undefined variable.
What you should have is
public function .... {
$bad_rows = [];
^^^^^^^^^^^^^^^^
\Exce..... function($row) use($request, $bad_rows) {
^^^^^^^^^^^^
blah blah blah
});
dd($bad_rows);
}
Related
I'm trying to understand the reason of this error message from postman when test API.
When I am testing my REST API from postman, it gives me error
ErrorException (E_NOTICE)
Trying to get property 'staff' of non-object
I try to find the problem but i can't find it. I kept searching for this but couldn't find an answer that will make this clear.
Anyone can help me on this?
Thanks!
This my code snippet
public function updatestatus($request, $leave, $is_api=0)
{
$status = $request->get('status');
$user = $is_api? JWTAuth::parseToken()->authenticate():Auth::user();
// $user = Auth::user();
$staff= $user->ref_user;
$applying_staff = $leave->staff;
$applying_user = $applying_staff->main_user;
//Approved
if($status==2 && $leave->status==1)
{
$leave->status =2;
$leave->approved_by_staff_id = $staff->staff_id;
$leave->approved_date = new Carbon('today');
$leave->save();
if($user->centre_id)
Helper::ClearObjective(10,$user->centre_id);
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr)))
->onConnection('database')
->onQueue('emails');
return response()->json(['Success'=>'Success']);
//send email
}
// Rejected
else if($status==3 && $leave->status==1)
{
$leave->status =3;
$leave->status_rejected_reason = $request->get('reason',null);
$leave->save();
if($user->centre_id)
Helper::ClearObjective(10,$user->centre_id);
$leave_cat = LeaveCategory::find($leave->leave_type);
if($leave_cat->leave_status!=0)
{
$leave_ent = $applying_staff->leaves()->where('leave_type',$leave->leave_type)->first();
if($leave_ent)
{
$leave_ent->leave_remaining += $leave->leave_days;
$leave_ent->save();
}
}
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr, $leave->status_rejected_reason)))
->onConnection('database')
->onQueue('emails');
//send email
}
//Cancelled
else if(($status==4 && $leave->status==2) || ($status==4 && $leave->staff_id == $staff->staff_id))
{
$leave->status =4;
$leave->status_rejected_reason = $request->get('reason',null);
$leave->save();
$leave_cat = LeaveCategory::find($leave->leave_type);
if($leave_cat->leave_status!=0)
{
$leave_ent = $applying_staff->leaves()->where('leave_type',$leave->leave_type)->first();
if($leave_ent)
{
$leave_ent->leave_remaining += $leave->leave_days;
$leave_ent->save();
}
}
dispatch(new EmailJob($applying_user->email,new LeaveNotification(route('staff.leave.show',$leave->id), $leave->statusStr,$leave->status_rejected_reason)))
->onConnection('database')
->onQueue('emails');
//send email
}
// return reponse()->toJson(compact('leave'));
return $leave;
}
Calling API
public function update(Request $request)
{
return $this->leaveApplicationRepository->updatestatus($request,1);
}
your updatestatus() need 3 parameter and your update() function pass only 2 paramenter;
public function update(Request $request)
{
// please provide you leave data
$leave = "your data is here";
return $this->leaveApplicationRepository->updatestatus($request,$leave, 1);
}
From the context that I can see, it is trying to reference the staff variable in:
$applying_staff = $leave->staff;
The non-object message will mean that $leave itself is the problem. Since you are passing in 1 to the call:
return $this->leaveApplicationRepository->updatestatus($request,1);
the 1 becomes the $leave parameter, and that is not an object, hence the error.
Maybe you think that by passing in 1, it will find the correct model automatically? This is not the case. You need to load that model explicitly.
OctoberCMS BackendForm-Widget "Repeater" stores my data as an array in the database which looks like so:
{
"topic":"title",
"topic_description":"description",
}
{
"topic":"title",
"topic_description":"description",
}
I need to add a unique ID to each array so the json looks like this:
{
"topic_id":"1",
"topic":"title",
"topic_description":"description",
}
{
"topic_id":"2",
"topic":"title",
"topic_description":"description",
}
I have added this formBeforeSave function to my controller:
public function formBeforeSave($model)
{
$model->topics = array_map(array($model, 'topics'), function ($topic) {
$topic['id'] = uniqid();
});
}
But when trying to save the form OctoberCMS throws this error:
“array_map(): Argument #2 should be an array”
Adding this to the controller instead:
public function formBeforeSave($model)
{
$model->topics = array_map($model->topics, function ($topic) {
$topic['id'] = uniqid();
});
}
Throws the error:
array_map() expects parameter 1 to be a valid callback, array must have exactly two members
Has anyone experienced this and found a solution he/she could share please?
Each topic has a (unique) key already. So you could just copy this key as additional value while walking through the array:
// mocking test-data:
// $model->topics = [["topic"=>"title"], ["bar"=>"foo"]];
array_walk($model->topics, function(&$topic, $key) {
$topic['topic_id'] = $key;
});
As per the docs first argument should be callback, replace your code with following and try if it works.
public function formBeforeSave($model)
{
$model->topics = array_map(function ($topic) {
$topic['id'] = uniqid();
return $topic;
}, $model->topics);
}
Reference: http://php.net/manual/en/function.array-map.php
Applaus goes to LukeTower who pointed me to the right direction on Github.
The solution is putting the logic in the beforeSave() method on the model:
public function beforeSave()
{
$this->_FieldName_ = array_map(function ($miau) {
$miau['id'] = uniqid();
return $miau;
}, $this->_FieldName_);
}
I am writing a method that uses POST variables posted by AJAX to add a user to a certain course in the database, but I can't get the callback to work correctly:
public function enroll()
{
$package = array();
$this->load->library('form_validation');
$this->form_validation->set_rules('course', 'Vak', 'required|callback_not_enrolled');
$fields = array("course");
if ($this->form_validation->run($this) === FALSE) {
$errors = array();
$success = array();
foreach ($fields as $field) {
$error = form_error($field);
if ($error !== "") {
$errors[$field] = $error;
} else {
$success[$field] = True;
}
}
$package["field_errors"] = $errors;
$package["field_success"] = $success;
$package["success"] = False;
} else {
$package["database"] = $this->course_model->enroll_user($this->data["user"], $this->input->post("course"));
$package["success"] = True;
}
echo json_encode($package);
}
I wrote the callback not_enrolled to check if the user is not already enrolled to the database. Note that I can't use is_unique because I have to test the combined uniqueness of two fields (so just one or two separate ones don't do the trick) and the id of the user is not included in the form (because it's part of the Code Igniter session).
The callback function:
public function _not_enrolled($course)
{
$exists = ($this->user->is_enrolled($course, $this->data["user_id"]) != False);
if ($exists != False) {
$this->form_validation->set_message("not_enrolled", "Already enrolled");
return False;
} else {
return True;
}
}
And finally the method is_enrolled from the model:
public function is_enrolled($course, $user=False) {
if($user==False){
$user = $this->data["user_id"];
}
$this->db->select()->from("course_participant")->where("user_id", $user)->where("course_id", $course);
$query = $this->db->get();
return($query->num_rows()>0);
}
Through a call to var_dump($this->_not_enrolled($existing_course_id)); I know that both the callback function and the method from the model work, as it correctly returned true.
When I var_dump the $package array or validation_errors() I don't get any validation errors except that it says Unable to access an error message corresponding to your field name Vak(not_enrolled).
I tried removing the initial _ from the function name but that gives me a Server Status 500 error.
I have another setup exactly like this, albeit other database calls, with a callback using the same syntax. This method works perfectly.
I do not know how to set a callback function for the view record page in codeigniter.
I use the callback_column function and it does what I need in the grid view, but on the view record page it does not work.
I searched their site and forum and did not found anything that could help me.
My code looks like:
$zeus = new grocery_CRUD();
$zeus->set_theme('bootstrap');
// $zeus->set_language('romanian');
$zeus->set_table('programari');
$zeus->columns(array('id_client', 'id_sala', 'denumire', 'numar_persoane', 'observatii'));
$zeus->callback_column('id_sala',array($this,'_test_function'));
$cod = $zeus->render();
$this->_afiseaza_panou($cod);
public function _test_function($row, $value)
{
return '0';
}
write this lines in \libraries\Grocery_CRUD.php
at line number 3530
protected $callback_read_field = array();
than put this function after constructor call
public function callback_read_field($field, $callback = null)
{
$this->callback_read_field[$field] = $callback;
return $this;
}
//Now update this function to manage the field outputs using callbacks if they are defined for the same
protected function get_read_input_fields($field_values = null)
{
$read_fields = $this->get_read_fields();
$this->field_types = null;
$this->required_fields = null;
$read_inputs = array();
foreach ($read_fields as $field) {
if (!empty($this->change_field_type)
&& isset($this->change_field_type[$field->field_name])
&& $this->change_field_type[$field->field_name]->type == 'hidden') {
continue;
}
$this->field_type($field->field_name, 'readonly');
}
$fields = $this->get_read_fields();
$types = $this->get_field_types();
$input_fields = array();
foreach($fields as $field_num => $field)
{
$field_info = $types[$field->field_name];
if(isset($field_info->db_type) && ($field_info->db_type == 'tinyint' || ($field_info->db_type == 'int' && $field_info->db_max_length == 1))) {
$field_value = $this->get_true_false_readonly_input($field_info, $field_values->{$field->field_name});
} else {
$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
}
if(!isset($this->callback_read_field[$field->field_name]))
{
$field_input = $this->get_field_input($field_info, $field_value);
}
else
{
$primary_key = $this->getStateInfo()->primary_key;
$field_input = $field_info;
$field_input->input = call_user_func($this->callback_read_field[$field->field_name], $field_value, $primary_key, $field_info, $field_values);
}
switch ($field_info->crud_type) {
case 'invisible':
unset($this->read_fields[$field_num]);
unset($fields[$field_num]);
continue;
break;
case 'hidden':
$this->read_hidden_fields[] = $field_input;
unset($this->read_fields[$field_num]);
unset($fields[$field_num]);
continue;
break;
}
$input_fields[$field->field_name] = $field_input;
}
return $input_fields;
}
than call same as other callback functions
As far as I'm aware GroceryCRUD doesn't provide callbacks or another means of overriding the default output in the view state.
The solution to customising this would be to create a custom view to which you will insert the data from your record. This way you can customise the layout and other presentation.
What you would then do is unset the default read view with:
$crud->unset_read();
And add a new action where there are details on how to do this here.
What to do with the new action is point it to a URL that you map in routes.php if necessary and handle it with a new function in your controller. You'll either have to write a model function to retrieve the data since this isn't passed from GC or you can use the action to target a callback and feed $row to it via POST or something so that the data for the record is accessible in the view. (Look at the example in the link above).
I have a quick question that's killing my head.
I'm trying to make a Form Validation System with Method Chaining in PHP
What I want to do is to be able to call for example (please check the code comments):
$firstname = $OBJECT->Forms->Field("First Name", "firstname"); //This one doesn't validate, but just puts what's on firstname field on to $firstname. But this way doesn't work for me, because I have to return the object so it can be chainable and not the variable of the POST. How can I do this?
$firstname = $OBJECT->Forms->Field("First Name", "firstname")->Validate(); //this one validates if the field is not empty and if it's empty it'll insert the first parameter ("First Name") onto an array to display the errors.
$email = $OBJECT->Forms->Field("Email", "email")->Validate()->Email(); //This one does the same as above but validates Email and inserts the value of the email field onto $email
but I prefer the next one...
$email = $OBJECT->Forms->Field("Email", "email")->Validate->Email(); //I'd rather prefer this method but I don't know how to do it without using the parenthesis on the Validate method.
I can only make it work like this
$firstname = $OBJECT->Forms->Field("First Name", "firstname")->Validate();
and
$firstname = $OBJECT->Forms->Field("First Name", "firstname")->Validate()->Email();
Without ->Validate(); I can't seem to make it work (Like this: $firstname = $OBJECT->Forms->Field("First Name", "firstname");)
The code is kinda mess to share. But the code is simple... I have a forms.class.php and a validate.class.php.
The forms.class.php creates an instance of Validate class from validate.class.php and the Forms Object is passed through the Validate class on the constructor.
I want to be able to do:
$OBJECT->Forms->Field();
$OBJECT->Forms->Field()->Validate();
$OBJECT->Forms->Field()->Validate()->Email;
$OBJECT->Forms->Field()->Validate()->Telephone;
or this preferebly:
$OBJECT->Forms->Field();
$OBJECT->Forms->Field()->Validate;
$OBJECT->Forms->Field()->Validate->Email;
$OBJECT->Forms->Field()->Validate->Telephone;
Only figured out:
$OBJECT->Forms->Field()->Validate();
$OBJECT->Forms->Field()->Validate()->Email();
$OBJECT->Forms->Field()->Validate()->Telephone();
But any form is OK
Thank you.
See if this is what you are trying to do:
<?php
class FormValidate
{
protected $args;
public $valid;
public function Forms()
{
// Don't know what this function is supposed to do....
return $this;
}
public function Validate()
{
$numargs = func_num_args();
$this->args = array();
if($numargs == 2) {
$vals = func_get_args();
$this->args[$vals[1]] = $vals[0];
$this->valid = true;
}
else
$this->valid = false;
if(isset($this->args['firstname']) && !empty($this->args['firstname']))
return true;
return $this;
}
public function Email()
{
if(isset($this->args['email'])) {
if(filter_var($this->args['email'],FILTER_VALIDATE_EMAIL))
return $this->valid = $this->args['email'];
}
return $this->valid = false;
}
public function Telephone()
{
if(isset($this->args['telephone'])) {
if(preg_match('/^[0-9]{3}-[0-9]{3}-[0-9]{4}$/',$this->args['telephone']))
return $this->valid = $this->args['telephone'];
}
return $this->valid = false;
}
}
$test = new FormValidate();
// These will throw a fatal error on the base Validate('First Name','firstname')
// if you add another method to the chain like so: ->Validate('First Name','firstname')->Email();
echo $test->Forms()->Validate('123-876-0987','telephone')->Telephone();
?>