Trying to get property of non-object in foreach loop - php

I am developing a system that uses Maatwebsite to read and write data to the database from an excel sheet, which is working fine. Now before inserting the data, the system checks for the entries in parent table. And if there is any record that matches the record of the sheet, the system inserts foreign key to the child schema and if there's not, the system creates one first and then insert it's id as foreign key.
Here's the import class:
public function collection(Collection $rows){
$sub_chap = SubChapter::where(['chap_id' => $this->chap_id])->get();
$chapter = Chapter::where(['chap_id' => $this->chap_id])->first();
$author = Author::where(['author_status' => 1])->get();
$book = $chapter->book_id;
$author_id = 0;
$sub_chap_id = 0;
/* Working perfectly fine here...
foreach($author as $a){
echo $a->a_name."\r";
}
*/
foreach ($rows as $row){
if($row['quote_english'] != ""){
foreach($sub_chap as $sub){
if(trim($sub->sub_chap_english) == trim($row['sub_chap_english'])){
$sub_chap_id = $sub->sub_chap_id;
break;
} else{
$sub_chap_id = 0;
}
}
if($author->count() > 0){
foreach($author as $athr){
$author_id = (trim($athr->author_name) == trim($row['author_name']))? $athr->author_id : $author_id = 0;
}
}
if($author_id == 0){
$author = Author::create([
'author_name' => $row['author_name'],
...
...
'author_status' => 1,
]);
$author_id = $author->author_id;
}
$quote = Quote::create([
'quote_english' => $row['quote_english'],
'author_id' => $author_id,
'sub_chap_id' => $sub_chap_id,
'chap_id' => $this->chap_id,
'book_id' => $book
]);
}
}
}
It's saying:
Trying to get property 'author_name' of non-object
I know this error comes when you try to access an object's property from a non-object instance. get() is returning the collection object as usual and working fine outside the foreach() loop. what i can't figure out is why it's not working inside the loop. Any help would be appreciated!

I still can't figure out why it's saying that and seems like no else also. So I think it's about time I post the solution I came up with. I found a way around it, So, basically what I did was I stored the whole collection to a global variable and accessed it in the loop.
Here's the code:
/**
* Global variable for raavi's data.
*/
public $author;
/**
* Construction function.
*
* #param int $id
* #param Collection $arr
*/
function __construct($arr) {
$this->author= $arr;
}
/**
* This method is responsible for inserting the excel
* sheet's rows data to the database schema.
*
* #param Collection $rows
*/
public function collection(Collection $rows){
// other code as it is...
foreach($this->author['author'] as $athr){
$author_id = (trim($athr->a_name) == trim($row['author_name']))? $athr->a_id : 0 ;
}
}
and in my importing controller's import method:
$quotes = Excel::import(new QuotesImport(compact('author')));
Working fine till now. If there's some improving or anything that needs to be change, kindly feel free. I would appreciate it.

Related

Use templates created using ckeditor in codeigniter

I am creating the templates using CKEditor. I need to replace the keys with its value, the keys are stored with its table name and columns to fetch in a table
e.g
tbl_template_bindings
id key table column
1 StudentFirstName tbl_User fname
2 StudentLastName tbl_User lname
3 TotalAmount tbl_payment due
and the user is bound to use those keys only, a kind of template. so consider we have created below template using CKEditor
Date: {{CurrentDate}}
Dear {{StudentFirstName}} {{StudentLastName}}, Your total amount is {{TotalAmount}}
please suggest any ideas will be helpful
Well, I just made this code for you, because I love CodeIgniter. Unfortunately I didn't test this code, but I am pretty sure #dEL, you will enjoy :)
CodeIgniter Helper File: Templatebuilder_helper.php
if ( ! function_exists('build_ck_template')) {
/**
* #param $template_txt
*/
function build_ck_template($template_txt)
{
// get all {{DATA}} as DATA in assoc array
preg_match_all('/{{(.*?)}}/', $template_txt, $matches);
// trim data & make array
$config = array_map('trim', $matches[1]);
// get CI instance
$CI = &get_instance();
// assuming you have user id in session - just for demo
$uid = $CI->session->userdata('uid');
// temp array var
$result = [];
// get data from table key, table & column
$query = $CI->db->query("SELECT * FROM tbl_template_bindings");
// collect all data
foreach ($query->result_array() as $row) {
array_push($result, $row);
}
// check one by one array key
foreach ($config as $key => $value) {
// skip date because its not in table
if ($value != 'CurrentDate') {
// first check if key exist in db data, get index
$found_at_index = array_search($value, array_column($result, 'key'));
// yes we got the key
if (false !== $found_at_index) {
// get data for requested key
$CI->db->select($result[$found_at_index]['column']);
// where clause
$CI->db->where('uid', $uid);
// query
$query = $CI->db->get($result[$found_at_index]['table']);
// if uid is unique, we want to return just one row
$query_result = array_shift($query->result_array());
// get key column data
$replace_value = $query_result[$result[$found_at_index]['column']];
// replace with original value
$template_txt = str_replace('{{'.$value.'}}', $replace_value, $template_txt);
}
}
}
// return Woah!!!
$template_txt = str_replace('{{CurrentDate}}', date('Y-m-d'), $template_txt);
return $template_txt;
}
}
/* End of file Templatebuild_helper.php */
/* Location: ./application/helpers/Templatebuilder_helper.php */
Example Uses:
<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Class Controller
*/
class ControllerName extends CI_Controller {
public function __construct()
{
parent::__construct();
// load own template helper
$this->load->helper('Templatebuilder');
}
public function index()
{
// content template
$content = "Date: {{CurrentDate}}, Dear {{StudentFirstName}} {{StudentLastName}}, Your total amount is {{TotalAmount}}";
// build with real values
$this->load->view('template', array('temp_data' => build_ck_template($content)));
}
}
/* End of file data.php */
/* Location: ./application/controllers/ControllerName.php */
i'm not sure, but if i understand you correctly you simply need to parse some values and replace it with others
just create a model
class Template_Model extends CI_Model
{
public function build($strTemplate, $obj)
{
$arrData = (is_object($obj)) ? get_object_vars($obj) : $obj;
foreach($arrData AS $key => $val)
{
$strTemplate = str_replace("{{".$key."}}",$val,$strTemplate);
}
return $strTemplate;
}
}
and your controller
$this->load->model("template_model");
$str = "Date: {{CurrentDate}}, Dear {{StudentFirstName}} {{StudentLastName}}, Your total amount is {{TotalAmount}}";
echo $this->template_model->build($str, ["CurrentDate" => "2017-05-02", "StudentFirstName" => "Jon", "StudentLastName" => "Doe", "TotalAmount" => 100.22]);
You can use CI parsing library to parsing your DB to HTML page.
CI parsing example

Extbase: Modified object does not saved in the repository correctly

I am using TYPO3 7.6.10 and I build my first extension.
I want to add a property to my object in the createAction function of my controller.
But the modifications are nt saved.
Here is my code:
/**
* action create
*
* #param \Typo3\LpSurvey\Domain\Model\Sigil $newSigil
* #param array $answers
* #internal param Survey $newSurvey
*/
public function createAction(Sigil $newSigil, Array $answers)
{
$newSurvey = $this->objectManager->get('Typo3\LpSurvey\Domain\Model\Survey');
$this->userID = $GLOBALS['TSFE']->fe_user->user['uid'];
//this modifications are saved
foreach ($answers as $key => $answer) {
$newSurveyItem = $this->objectManager->get('Typo3\LpSurvey\Domain\Model\SurveyItem');
$newSurveyItem->setQuestionId($key);
$newSurveyItem->setValue($answer);
$newSurvey->addAnswer($newSurveyItem);
}
//BUT this modification is not saved
$newSigil->setUserID($this->userID);
$newSigil->setSurvey($newSurvey);
$this->sigilRepository->add($newSigil);
$this->redirect('list');
}
If I debug my object $newSigil the userID is set, but after adding to the repository the default value will be saved.
I dont understand why.
I also try to persist manually with following code, but no solution:
/**
* #var \typo3\CMS\Extbase\Persistence\Generic\PersistenceManager
* #inject
*/
protected $persistenceManager;
public function createAction(Sigil $newSigil, Array $answers)
{
$newSurvey = $this->objectManager->get('Typo3\LpSurvey\Domain\Model\Survey');
$this->userID = $GLOBALS['TSFE']->fe_user->user['uid'];
foreach ($answers as $key => $answer) {
$newSurveyItem = $this->objectManager->get('Typo3\LpSurvey\Domain\Model\SurveyItem');
$newSurveyItem->setQuestionId($key);
$newSurveyItem->setValue($answer);
$newSurvey->addAnswer($newSurveyItem);
}
$newSigil->setUserID($this->userID);
$newSigil->setSurvey($newSurvey);
$this->persistenceManager->persistAll();
$this->sigilRepository->add($newSigil);
$this->redirect('list');
}
I hope the question is understandable
Best regards Felix
Maybe UserID is not correct named? If your database field is called user_id your property for the domain should userId. Only if your database field is called user_i_d it should userID.

replicate() method not found in laravel 5.2

I am trying to replicate table row and its relationship.
but I am getting error message that replicate() does not exist,
I have seen on stackoverflow that many have used replicate() without any issue, but i am getting this error
my controller code
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->get();
$newshowtime=$movieshowtime->replicate();
return $newshowtime;
}
Is there any namespace i have to use for using replicate() , I am unable to get solution from laravel website also.
help is appreciated.
You can use replicate() on a model but not on a collection.
By fetching your records using get() you are returning a collection.
If you are just expecting one record to be returned then replace get() with first() and then replicate() should exist as it will be returning an instance of the model rather than a collection:
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->first();
$newshowtime=$movieshowtime->replicate();
return $newshowtime;
}
You will also need to save() the $newshowtime.
This code worked perfectly for me
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->get();
foreach ($movieshowtime as $item)
{
$item->show_date=$next_show_date;
$item->show_id=NULL;
$newshowtime=$item->replicate();
$newshowtime->push();
foreach ($item->showdata as $sd)
{
$newshowdata = array(
'showdata_id' => NULL,
'show_id'=>$newshowtime->id,
'category_id'=>$sd->category_id,
'showdata_category'=>$sd->showdata_category,
'showdata_rate'=>$sd->showdata_rate
);
// print_r($newshowdata);
Movies_showdata::create($newshowdata);
}
}
return redirect()->back();
}
Any suggestions to improve this code will be appreciated.
This type of function would help to clone multiple records and add those records in the same table. I tried a similar code flow and worked.
/**
* Clone multiple records in same table
*
* #params int $cinemaId
* #params string $showDate
*
* #return bool $status
*
* #access public
*/
public function copyShowTime($cinemaId, $showDate)
{
$date = new Carbon($showDate);
$currentShowDate = $date->format('Y-m-d');
// Cloned & Create new records
$moviesShowTimeCollection = Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinemaId],['show_date','=',$currentShowDate]])->get();
// Please check that Model name should change according to camelCases - Movies_showtimes to MoviesShowtimes
if(!$moviesShowTimeCollection->isEmpty()) {
$moviesShowTimeData = $moviesShowTimeCollection->toArray();
foreach ($moviesShowTimeData as $key => $value) {
$primaryKey = 'show_id'; // Needs to check the table primary key name
$primaryId = $value[$primaryKey];
$moviesShowTimeObj = Movies_showtimes::find($primaryId);
// below code can modify while cloaning
//$clonedMoviesShowTimeObj = $moviesShowTimeObj->replicate()->fill([
// 'column_name' => $updatedValue
//]);
$clonedMoviesShowTimeObj = $moviesShowTimeObj->replicate(); // just to clone a single record
$status = $clonedMoviesShowTimeObj->save();
}
}
}
Cheers!
You can easily replicate rows with new changes in that rows
$apcntReplicate = TrademarkApplicantMap::where('trademark_id', $trdIdForPostAssesment)->get();
foreach($apcntReplicate as $oldapnctdata)
{
$apcntreplicated = $oldapnctdata->replicate() ;
//update row data which will newly created by replicate
$apcntreplicated->row_name = $newrowdata;
//save new replicated row
$apcntreplicated->save();
}
Don't use toArray() then each element in the foreach loop will be an Eloquent object.

Codeigniter load query into an array

I have been trying to figure out how to load the data in a query to an array.
$query->row() //only brings back a single row of data when there are more entries in the database.
If I just use a foreach loop and echo in the model code below, The data is simply displayed on the screen. It's not in a variable or an array. It is just text on the screen all jammed together.
I had a really hard time trying to find a code example that would show me how to use the
$this->db->get_where('table' array('column' => $var);
I finally found it but then the example on codeigniters site only echos the query back to the screen.
http://ellislab.com/codeigniter/user-guide/database/results.html
This is not useful for production.
My controller code is:
public function record(){
/*
* Here the id is being passed to the record
* function to retieve the parent and childrens data
*
*/
$getid['id'] = $this->uri->segment(3);
$accld = $getid['id'];
$data = array();
$this->load->model('account');
$account = new Account();
$account->load($getid['id']);
$data['account'] = $account;
$this->load->model('children');
$children = new Children();
$children->accld($getid['id']);
$data['children'] = $children;
$this->load->view('childeditdisplay', $data );
}
}
My Model code is this:
public function accld($id)
{
$query = $this->db->get_where($this::DB_TABLE, array('accId' => $id));
$c_data = array();
foreach ($query->result() as $row){
$c_data[] = $row ;
}
return $c_data;
/*
* Note:
* I need to figure out how to load to an array to pass back to the
* controller to pass to the display
* I can echo to the screen the results but that is uncontrolled.
*
*/
}
If I do this:
public function accld($id)
{
$query = $this->db->get_where($this::DB_TABLE, array('accId' => $id));
foreach ($query->result() as $row){
echo $row->id ;
// and all the other fields below here
}
}
My rows are echoed to the screen. But there is no control. So any help in getting control of my data would be greatly appreciated.
ANSWER
This is finally what worked to bring back all the results and not just one row.
/**
* Populate from an array or standard class.
* #param mixed $row
*/
public function populate($row) {
foreach ($row as $key => $value) {
$this->$key = $value;
}
}
public function accld($id) {
$query = $this->db->get_where($this::DB_TABLE, array('accId' => $id));
$this->populate($query->result());
}
Just do
$query = $this->db->get_where($this::DB_TABLE, array('accId' => $id));
$_array = $query->result_array();
Do whatever with $_array.

CakePhp does update instead of insert new data

i started using cakephp, but now i encountered a problem which i am not able to solve.
I have got the following model relations which are relevant:
Exercise hasMany Points
Student hasMany Points,
now i want to check in the studentsController if for every exercise there is a Point data set, and iff not insert a new one.
When starting with no Point datasets, the function adds a new Point dataset for the first exercise correct, but after this it only updates the erxercise_id of this dataset, instead of creating new ones.
The controller function looks like this:
public function correct($id = null) {
$this->Student->id = $id;
$this->Student->recursive = 2;
if ($this->request->is('get')) {
$data = $this->Student->Exam->Exercise->find('all');
foreach($data as $exercise)
{
$exerciseID = $exercise['Exercise']['id'];
$this->Student->Point->recursive = 0;
$foundPoints = $this->Student->Point->find('all', array('conditions' => array('exercise_id' => $exerciseID)));
if($foundPoints == null)
{
$emptyPoints = array ('Point' => array(
'exercise_id' => $exerciseID,
'student_id' => $id
)
);
$this->Student->Point->save($emptyPoints);
}
else{
}
}
}
else //POST
{
}
}
if you have to insert a data you to use create() method like this:
This is only an example, with this line you create every time a new record into your database
and save data
$this->Student->Point->create();
$this->Student->Point->save($emptyPoints);
$this->Student->Point->id = '';
$this->Student->Point->save($emptyPoints);
or
$this->Student->Point->saveAll($emptyPoints);

Categories