Why am I getting this undefined index error? - codeigniter

I'm trying to list the indexes of an array, and it keeps throwing errors in my face.
I am getting this error:
A PHP Error was encountered
Severity: Notice
Message: Undefined index: sender
Now for some code details:
My print line:
<div class="left"><label>Afsender: </label><p><?=$reservation['sender'] . ' (' . $reservation['email'] . ')'?></p></div></pre>
My controller: (using phil sturgeon's template library for CodeIgniter)
public function readReservation($id)
{
$data['reservation'] = $this->reservation_model->getReservation($id);
$this->template->build('admin/readReservation_view', $data);
}
My Model:
public function getReservation($id)
{
$query = $this->db->where('id', $id)->get('ita_reservations');
if ($query->num_rows > 0)
{
return $query->result();
}
else
return false;
}
My sql:
CREATE TABLE IF NOT EXISTS `ita_reservations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sender` varchar(200) NOT NULL,
`email` varchar(200) NOT NULL,
`date` varchar(200) NOT NULL,
`time` varchar(200) NOT NULL,
`persons` varchar(200) NOT NULL,
`phone` varchar(200) NOT NULL,
`message` varchar(1000) NOT NULL,
`time_received` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
Now what baffles me, is that the same code works elsewhere, but with a different variable name. To increase my confusion, this is the var_dump from the line above my print:
array(1) { [0]=> object(stdClass)#42 (10) { ["id"]=> string(1) "1"
["sender"]=> string(7) "Kenneth" ["email"]=> string(17)
"zungate#gmail.com" ["date"]=> string(10) "23/05/2013" ["time"]=>
string(5) "18:00" ["persons"]=> string(1) "4" ["phone"]=> string(8)
"30243681" ["message"]=> string(12) "Ja nemlig ja" ["time_received"]=>
string(19) "0000-00-00 00:00:00" ["confirmed"]=> string(1) "0" } }
The sender index is clearly there, and the array is clearly loaded properly. (All indexes throw errors, not just sender).
What's going on, and what am I missing? Yes, I know I should check for isset or empty, but it exists, and the page cannot be loaded if the index doesn't exist so checks are kindof moot.

You have an object inside an array (see your var_dump), so to get the reservation sender you have to use the following:
$reservation[0]->sender
Or better yet, instead of returning the whole result set from your function, you should only return one row (assuming id's are unique, your query will return only one row anyway):
public function getReservation($id)
{
$query = $this->db->where('id', $id)->get('ita_reservations');
if ($query->num_rows > 0)
{
return $query->row();
}
else
return false;
}
With this you can use:
$reservation->sender

Related

Laravel Polymorphic Relationship - Many to Many issue

Have students, that can have documents.
Documents can either be 'just documents' that belong to students (normal one to many relationship)
However, Students can also have 'passports' and 'visas' (amongst others). Each passport and visa can have a document too. A single document can belong to many things (eg, one document can be associated with a passport and a visa). For the purpose of this troubleshooting, lets keep it simple and between Student / Passport (I've also left out other class stuff like fillable just to keep this brief).
Student Model:
class Student extends Model
{
public function documents() {
return $this->hasMany('App\StudentDocument');
}
public function visas() {
return $this->hasMany('App\StudentVisa');
}
public function passports() {
return $this->hasMany('App\StudentPassport');
}
}
Student Passport Class
class StudentPassport extends Model
{
public function student_documents()
{
return $this->morphToMany(StudentDocument::class, 'student_documentable');
}
}
Student Passport Store:
public function store(StudentPassportRequest $request, $student_id)
{
$student = Student::findOrFail($student_id);
$passport = $student->passports()->create($request->all());
if ($request->file('student_document_file')->isValid()) {
$uploaded_file = $request->file('student_document_file');
$filename = time().'-'.$uploaded_file->getClientOriginalName();
Storage::disk('local')->putFileAs(
'student_document_files/'. \Auth::user()->userable_id .'/'. $student_id .'/',
$uploaded_file,
$filename
);
$student_document = new StudentDocument;
$student_document->filename = $filename;
$student_document->student_document_type_id = StudentDocumentType::where('student_document_type','Passport')->first()->id;
$student_document->original_filename = $uploaded_file->getClientOriginalName();
$student_document->mime = $uploaded_file->getMimeType();
$student_document->student_id=$student_id;
$passport->student_documents()->save($student_document);
}
return redirect('/baadmin/students/'. $student_id .'#kt_tabs-passports')->with('flash_message', ['success','Created Successfully','Student Passport "'. $request->input('passport_number') .'" created successfully!']);
}
Error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'student_documentables' doesn't exist
INSERT INTO `student_documentables` (
`student_document_id`,
`student_documentable_id`,
`student_documentable_type`
)
VALUES
(5, 503, App \ StudentPassport)
I took the example as found in the Laravel Documentation here and just renamed 'tag' to student_documents' essentially. The student_documentable table doesnt exist of course, as it should be plugging it into the student_documents table.
Schema:
CREATE TABLE `student_documents` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`student_id` bigint(20) unsigned NOT NULL,
`student_document_type_id` bigint(20) unsigned NOT NULL,
`filename` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`mime` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`original_filename` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`primary_date` datetime NOT NULL DEFAULT current_timestamp(),
`secondary_date` datetime DEFAULT NULL,
`student_documentable_id` bigint(20) DEFAULT NULL,
`student_documentable_type` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `student_id_index` (`student_id`),
KEY `student_document_type_id_index` (`student_document_type_id`),
KEY `student_documentable_id_index` (`student_documentable_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
What am I doing wrong or is Laravel just not understanding 'student_documents'?
I can of course change the Student Passport Class to not plug into 'student_documentable' and use 'student_document' then it would try put in the data to the correct table, but I dont know if this is right since all documentation refers to adding an 'able' at the end...
You should first create a pivot table for that MorphMany relation,
Schema::create('student_documentables', function (Blueprint $table)
{
// optional depends if you want an id or not
$table->id();
// here singular is used, to generate student_documentable_type and student_documentable_id fields
$table->morphs('student_documentable');
// the foreign key to student_document
$table->unsignedInteger('student_document_id');
$table->foreign('student_document_id')->on('student_documents')->references('id')->onUpdate('cascade')->onDelete('cascade');
});
In your StudentDocument :
// we define a relation to retrieve all documentables like passport that are linked to that document
public function student_documentables()
{
return $this->morphTo('student_documentables');
}
In your StudentPassport :
// we define a relation to retrieve all documents linked to that passport
public function student_documents()
{
return $this->morphMany(StudentDocument::class, 'student_documentables');
}

Laravel Eloquent: belongsToMany collection get value

I have following relation
Tasks has many to many relation with Categories
Categories has one to many relation with Types
I'm using this in my task controller currently to get all the data I want, which works almost as wanted:
$type = Type::with('categories.tasks')
->where('slug', $type)
->first();
This returns type, with a categories collection, each category has a tasks collection, and each tasks have a category collection. This structure is correct by design, problem is the category child collection to task returns all categories, but I want it to be limited to the same condition as the parent category collection which is where('slug', $type) and I want the collection return not to be an array since the result will always only return one category if condition is applied.
I've tried using scope but with no success. Any help would be much appreciated.
My table and respective models
Type Table
CREATE TABLE `types` (
`id` int(11) NOT NULL,
`slug` varchar(60) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
)
Type Model
class Type extends Model{
public function categories()
{
return $this->morphMany(Category::class, 'categorize');
}
public function project()
{
return $this->belongsTo(Project::class);
}
}
Category Table
CREATE TABLE `categories` (
`id` int(10) NOT NULL,
`title` varchar(128) NOT NULL,
`color` varchar(10) NOT NULL,
`content` varchar(128) NOT NULL,
`categorize_id` int(6) NOT NULL,
`categorize_type` varchar(256) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
)
Category Model:
class Category extends Model
{
public function categorize(){
return $this->morphTo();
}
public function tasks(){
return $this->belongsToMany(Task::class,'task_category');
}
public function types(){
return $this->belongsTo(Type::class);
}
}
Tasks Table
CREATE TABLE `tasks` (
`id` int(10) UNSIGNED NOT NULL,
`project_id` int(11) NOT NULL,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`desc` text COLLATE utf8mb4_unicode_ci NOT NULL,
`is_completed` tinyint(1) NOT NULL DEFAULT 0,
`start` timestamp NOT NULL DEFAULT current_timestamp(),
`end` timestamp NULL DEFAULT NULL,
`allDay` tinyint(1) NOT NULL DEFAULT 0,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`updated_at` timestamp NULL DEFAULT current_timestamp(),
`deleted_at` timestamp NULL DEFAULT NULL
)
Pivot table
CREATE TABLE `task_category` (
`task_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL
)
Task Model
class Task extends Model
{
public function category(){
return $this->belongsToMany(Category::class,'task_category','task_id','category_id');
}
}
Edit: I have rephrased my question and added all information about models and tables
When using the data from
$type = Type::with('categories.tasks')
->where('slug', $type)
->first();
if you get the category from the task like this
foreach($type->categories as $category) {
foreach($category->tasks as $task) {
$wantedCategory = $task->categories; //like this
}
}
then yes, it will get you all the categories linked to that task,
what you need is just use the variable $category from your loop (or index)
we could help you more if you provide database structure and how you try to recover the category in question.

Access a column from another table in laravel eloquent

I have 2 tables as Page and Country in many to many relationship. I have to display a page according to slug and locale passed in my route. The locale field is in Country table. How can i access it in PageController
Here are my Schemas for both tables
CREATE TABLE `countries` ( `id` int(11) NOT NULL, `cname` varchar(255) NOT NULL, `lname` varchar(255) NOT NULL, `locale` varchar(255) NOT NULL, `status` tinyint(1) DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` varchar(45) DEFAULT NULL, `slug` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) )
CREATE TABLE `pages` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) NOT NULL, `slug` varchar(255) DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, `status` tinyint(1) DEFAULT NULL, PRIMARY KEY (`id`) )
Here is the method i am using
public function findBySlugAndLocale($slug,$locale)
{
return $this->model->where('slug', str_slug(trim($slug)))->where('countries',str_slug(trim($locale)))->first();
}
In above method the slug and locale are coming from route so here is my route
Route::get('/{slug}/{locale}', ['as' => 'show','uses' => 'HomeController#findBySlugAndLocale']);
I want a query something like this
select * from `pages` where `slug` = home and `countries` = en
Here are my Models:
class Country extends Basemodel {
protected $table = "countries";
public function pages() {
return $this->belongsToMany('App\Models\Page', 'country_page', 'country_id', 'page_id')->withTimestamps();
}
}
class Page extends Basemodel {
protected $table = "pages";
public function countries() {
return $this->belongsToMany('App\Models\Country', 'country_page', 'page_id', 'country_id')->withTimestamps();
}
}
Well I solved the above using join... Here is the query... It may help someone with the same issue
public function findBySlugAndLocale($slug,$locale)
{
$results = $this->model
->join('country_page', 'pages.id', '=', 'country_page.page_id')
->join('countries', 'countries.id', '=', 'country_page.country_id')
->where('pages.slug', '=', $slug)
->where('countries.locale', '=', $locale)
->first();
return $results;
}
If I'm understanding your question correctly and you want to query the pages table based on a locale in the countries table you'll need to use whereHas:
return $this->model
->where('slug', str_slug(trim($slug)))
->whereHas('countries', function ($query) use ($locale) {
$query->where('locale', str_slug(trim($locale)));
})->first();
Hope this helps!

where_not_in not return match by array value as param

trying to get TraineeID where $arrTID not in tbl_attendance_processed but my code below return all TraineeID from tbl_attendance_processed.
If I use where_in then the query return absolute result those TraineeID are really matched. Just not returning appropriate when I use where_not_in.
Model:
public function getNotMatch_TID($arrTID,$atnDate){
$this->db->select('TraineeID');
$this->db->where_not_in('TraineeID', $arrTID);
$this->db->where('attnDate', $atnDate);
$query = $this->db->get('tbl_attendance_processed');
return $query->result();
}
controller:
$arrTID = $this->input->post('Present');
$atnDate = $this->input->post('attnDate');
$nonMatch= $this->AttendanceModel->getNotMatch_TID($arrTID,$atnDate);
print_r($nonMatch);
echo last query:
table schema:
CREATE TABLE `tbl_attendance_processed` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`TraineeID` varchar(7) CHARACTER SET utf8 NOT NULL,
`attnDate` date NOT NULL,
`inTime` time NOT NULL,
`outTime` time NOT NULL,
`Status` varchar(10) NOT NULL,
`ClassCount` tinyint(1) NOT NULL DEFAULT '1',
`Reason` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3186 DEFAULT CHARSET=latin1

Codeigniter get sum of goals a player has made

I got a database. This is the mysql script of it. A player can appear more in the table what I want to do is get the sum of all the goals this player has made.
Script:
CREATE TABLE IF NOT EXISTS `spelerswedstrijden` (
`Id` int(5) NOT NULL AUTO_INCREMENT,
`spelerId` int(2) NOT NULL,
`wedstrijdId` int(5) NOT NULL,
`goals` int(5) DEFAULT NULL,
`assisten` int(5) DEFAULT NULL,
`gelekaarten` int(5) DEFAULT NULL,
`rodekaarten` int(5) DEFAULT NULL,
PRIMARY KEY (`Id`)
)
My Model code:
function getGoals($id) {
$this->db->where('spelerId', $id);
$this->db->from('spelerswedstrijden');
$goals = $this->db->select_sum('goals');;
return $goals;
}
Using this code gives me following error: Object of class CI_DB_mysql_driver could not be converted to string
Any Ideas how I can fix this?
Thanks in advance
function getGoals($id)
{
$this->db->select('COUNT(id) as TotalGoals');
$this->db->where('spelerId', $id);
$this->db->group_by('spelerId');
$goals = $this->db->get('goals');;
return $goals->row();
}
In controller access it like this
$result = $this->mymodel->getGoals($id);
echo $result->TotalGoals;
try;
function getGoals($id) {
$this->db->select_sum('goals');
$this->db->where('spelerId', $id);
$this->db->from('spelerswedstrijden');
$goals = $this->db->get();
return $goals;
}
Another Appraoch:
$this->db->select('sum(goals) AS total_goals');

Resources