I have created two tables as, forum_post and gallery.
forum_post table:
id user_id ststus photo_id
1 1 hi...! NULL
2 1 hello! NULL
3 1 NULL 1
4 1 NULL 2
user_gallery table:
id user_id image video
1 1 1.jpg NULL
2 1 new.gif NULL
When, user upload the image file in the user_gallery table, i want to create one row in the forum_post table and store the gallery id into the forum_post-> image field. as well as the user id also stored in the forum_post table.
My model code in the ForumPost is:
public static function addForumImage($id, $user_id) {
$forumImage = ForumPost::model()->find('LOWER(photo_id) = ?', array( strtolower($image)));
if (!$forumImage) {
$forumImage = new ForumPost;
$forumImage->photo_id = $image;
$forumImage->save(false);
}
UserGallery beforeSave function is:
protected function beforeSave() {
if (parent::beforeSave()) {
ForumPost::addForumImage($this->id, $this->user_id);
// var_dump($forumPost->photo_id);
return true;
}
return false;
}
My table relationship is, user_gallery->image refers the forum_post->photo_id.
Now, the image is stored in the user_gallery folder and i dint get the id in the ForumPost model...
Please any one help me.. :(
try this
protected function beforeSave() {
if (parent::beforeSave()) {
ForumPost::addForumImage($this->id, $this->user_id, $this->forum_image);
// var_dump($forumPost->photo_id);
return true;
}
return false;
}
Model
public static function addForumImage($id, $user_id,$image) {
$forumImage = ForumPost::model()->find('photo_id = :image', array( ':image'=>strtolower($image)));
if (empty($forumImage)) {
$forumImage = new ForumPost;
$forumImage->user_id=$user_id;
$forumImage->content= NULL
$forumImage->photo_id = $image;
$forumImage->save(false);
}
}
Related
LEADS TABLE
id
title
owner_id
from_table
EMPLOYEE TABLE
id
first_name
last_name
role
ADMIN TABLE
id
first_name
last_name
role
$users = Leads::query();
return Datatables::make($users)
->editColumn('owner_id', function ($user) {
if($user->from_table == 'employee'){
$emp = Employee::where('id',$user->owner_id)->first();
return $emp->first_name.' '.$emp->last_name.' ('.$emp->role.')';
}
if($user->from_table == 'admin'){
$admin = Admin::where('id',$user->owner_id)->first();
return $admin->first_name.' '.$admin->last_name.' ('.$admin->role.')';
}
})
the above solutions is working fine but we are unable to search column wise induvidual searching in datatables.
what i want is join query something like:
if(leads.from_table == employee)
// fetch data from EMPLOYEE TABLE i.e. LEADS TABLE + EMPLOYEE TABLE
id
title
owner_id
from_table
first_name
last_name
role
if(leads.from_table == admin)
// fetch data from ADMIN TABLE i.e. LEADS TABLE + ADMIN TABLE
id
title
owner_id
from_table
first_name
last_name
role
I think you should change your database structure to use polymorphic relations, they fully comply with your needs - https://laravel.com/docs/5.8/eloquent-relationships#polymorphic-relationships
from_table column should contain the class name of the parent model.
Add in Leads model
public function fetchOwner()
{
return $this->morphTo();
}
Add In Employee Model
public function employee()
{
return $this->morphOne('App\Employee', 'fetchOwner');
}
Add In Admin Model
public function employee()
{
return $this->morphOne('App\Admin', 'fetchOwner');
}
$users = Leads::with('fetchOwner');
return Datatables::make($users)
->editColumn('owner_id', function ($user) {
return $user->fetchOwner->name;
})
thanks to all who tried to help..
I'm answering my own question as i found the answer after 9 days digging everywhere..
so here is the answer:
you may want to replace owner_code by owner_id in your business table.
so i changed the from_table to owner_type & owner_type now should contain the class name as value ex: changed admin to App\Admin & employee to App\Employee in Database
App\Admin.php
public function employee()
{
return $this->morphOne('App\Leads', 'owner');
}
App\Employee.php
public function employee()
{
return $this->morphOne('App\Leads', 'owner');
}
App\Leads.php
public function owner()
{
return $this->morphTo();
}
Thanks to: laravel morphTo how to use custom columns? (EddyTheDove) for pointing out the exact problem..
Very new to symfony and Doctrine. I have the following tables in my database.
mo_user
id | email | password
__________________________________
9144 | summer#h.com | !password!
mo_user_role
user_id| role_id
_________________
9144 | 5
mo_permission
id | namespace | name | description
______________________________________________
1 | admin | - | -
2 | users | - | -
3 | view_summary_report | - | -
4 | view_user_statement | - | -
mo_role_permission
role_id | permission_id
________________________
5 | 3
5 | 4
I am trying to return an array of the permissions of the current user in this case user with id = 9144 which should be array('view_summary_report','view_user_statement').
I have mapped all the tables to their corresponding entity classes. and in MoUser.php entity class which corresponds to mo_user table, I have a
permissions method which should return the array but my join from annotations is failing,
My getPermissions() method in MoUser.php
/**
* #var Collection|MoPermission[]
* #ORM\ManyToMany(targetEntity="App\Entity\MoPermission")
* #ORM\JoinTable(
* name="mo_user_role",
* joinColumns={#ORM\JoinColumn(name="user_id",referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id",referencedColumnName="id")}
* )
*/
private $permissions;
public function getPermissions()
{
$currentPermissions = array();
foreach ($this->permissions->toArray() as $index => $permission) {
$currentPermissions[] = $permission->getNamespace();
}
//Return default role if Roles are not assigned to this user.
if(count($currentPermissions)>0) {
return $currentPermissions;
} else {
return array('DEFAULT_PERMISSION');
}
}
So I figured out the raw sql to achieve what I wanted which is below, but I would like to know the Symfony/Doctrine annotated way of achieving the following raw SQL.
SELECT t0.id AS id_1, t0.namespace AS namespace_2, t0.name AS name_3, t0.description AS description_4
FROM mo_permission t0
LEFT JOIN mo_role_permission ON t0.id = mo_role_permission.permission_id
LEFT JOIN mo_user_role ON mo_role_permission.role_id = mo_user_role.role_id
WHERE mo_user_role.user_id = 9144;
I don't think there is a proper way to achieve what you're trying to do directly through property annotations with your current setup.
You could achieve what you want with one of these solution though :
One of mo_user_role and mo_role_permission is not needed, since none of them have additional field. You should just have a mo_user_permission table generated by a ManyToMany relationship between MoUser and MoPermission, which would grant you direct access to MoPermission from MoUser's getPermissions()
Another way would be to create a service which would have a GetPermissionsFromUser(MoUser $moUser) method (for example), calling the proper query from the entity's repository, which you would call when needed.
You could still achieve what you want in your getPermissions() method with your current setup, but you would have to loop through each relation's items to build your new result array manually.
e.g. for last point :
public function getPermissions() {
$permissions = [];
foreach($this->roles as $role) {
foreach($role->getPermissions() as $permission) {
permissions[] = $permission->getNamespace();
}
}
return $permissions;
}
This would assume you have a MoRole entity, which would make sense regarding your current setup, but you didn't mention it. Otherwise, same logic could still be applied though, it's just a naming matter.
I'm pretty sure that you could do that query using Doctrine (and a QueryBuilder) like...
use Doctrine\ORM\EntityRepository
class PermissionRepository extends EntityRepository
{
//....
/**
* #param UserInterface $user
* #return array|Permission[]
*/
public function getPermissionsForUser(UserInterface $user)
{
$queryBuilder = $this->createQueryBuilder('permission');
/**
* permissions will be in a multi-dimensional array
* with a single key per array of 'namespace'
*/
$permissions = $queryBuilder
->select('permission.namespace')
->join('permission.role', 'role')
->join('role.user', 'user')
->where($queryBuilder->expr()->eq('user', ':user'))
->setParameter('user', $user)
->getQuery()
->getArrayResult();
if (count($permissions) > 0) {
/**
* If there are any permissions found just return
* the 'namespace' property from each "sub-array"
*/
return array_column($permissions, 'namespace');
}
return ['DEFAULT_PERMISSION'];
}
//...
}
And then you would call it like..
$permissions = $repository->getPermissionsForUser($user);
Here i have a list of same category names which comes under different parent category.when i fetch the data according to the id am getting result because id is different for all but when i fetch by category name am getting only the first results even though i have two same category names under different parent category..here is my category table
id category_name parent_id
8 men 0
9 kids 0
10 T-shirts 8
11 Shirts 8
12 Jeans 8
13 Pants 8
14 Shorts 8
15 Tees 9
16 Shirts 9
17 Jeans 9
18 Pants 9
Here am having shirts as the category name under different parent_id.when i select the id of 16-shirts am getting the value of of id 11-shirts because of the same category name.
Here is the controller am using
public function men_clothing_image($category=null)
{
$category_id =$this->roxmodel->get_category_id($category);
$data['active_mn']='men_clothing';
$data['men']=$this->roxmodel->get_category_by_parent($p_id=8);
$data['kids']=$this->roxmodel->get_category_by_parent($p_id=9);
$config['base_url'] = base_url().'men-'.$category;
$config['per_page'] = 2;
$config['uri_rsegment'] = 4;
$config['use_page_numbers'] = TRUE;
$config['total_rows'] = $this->roxmodel->count_category_images($category_id);
$data['galllery']=$this->roxmodel->get_gallery_men_images($category_id,$config['per_page'],$this->uri->rsegment(4));
$this->load->library('pagination',$config);
$data['page_links'] = $this->pagination->create_links();
$this->load->view('men_clothing_image',$data);
}
Here is the model am passing
public function get_category_id($category_name)
{
$this->db->select('category.id');
$this->db->where('category.category_name',$category_name);
$result = $this->db->get('category')->row();
if($result)
{
return $result->id;
}
}
i had done self join for connecting the id and category name but the output was null
public function get_category_id($category_name)
{
$this->db->select('c.id');
$this->db->join('category c1','c.id=c1.category_name');
$this->db->where('c1.category_name',$category_name);
$result = $this->db->get('category c')->row();
if($result)
{
return $result->id;
}
}
count image function as follows..
public function count_category_images($p_id)
{
$this->db->select('gallery.*','category.category_name');
$this->db->join('category', 'category.id = gallery.category_id');
$this->db->where('category.id',$p_id);
$this->db->order_by('gallery.id','desc');
return $this->db->count_all_results('gallery');
}
You have to use result() or result_array(). Because there are several rows in result.
row() - This function returns a single result row.
result() - This function returns the query result as an array of objects, or an empty array on failure.
So, try
public function get_category_id($category_name)
{
$this->db->select('category.id');
$this->db->join('category c1','c.id=c1.category_name');
$this->db->where('category.category_name',$category_name);
$result = $this->db->get('category')->result();
return $result;
}
Also you can use
if ($query->num_rows() > 0)
to check if there are rows.
If you use, search, and use part of category name, use LIKE interms of WHERE.
try to use like query
If you want to control where the wildcard (%) is placed, you can use an optional third argument. Your options are 'before', 'after' and 'both'
and try group by
public function get_category_id($category_name)
{
$this->db->select('category.id');
$this->db->like('category.category_name',$category_name,'both');
$this->db->group_by(array("category.id", "category.category_name","category.parent_id"));
$result = $this->db->get('category')->result_array();
if($result)
{
print_r($result);
exit;
// return $result;
}
}
I want to create image galleries for stuffs. So in Mysql I created two tables:
table 1 multiples contained field name (id, stuff_id, images ) which id is primary key and auto increment, stuff_id is index.
table 2 stuffs contained field name (stuff_id, name, detail) which stuff_id is primary key and auto increment.All I want is to upload a new stuff with 4 images,and be able to get stuff_id in table multiples.
Ex: If I upload a new stuff with 4 images with stuff_id =1 in table multiples should look like this::
|id||stuff_id||images|
|1| |1| |image1.jpg|
|2| |1| |image2.jpg|
|3| |1| |image3.jpg|
|4| |1| |image4.jpg|
And this is my code but it dose not do what I want (I have 2 models Stuffs and Multiple). It just insert record to tables but, in table multiples stuff_id it gets '0' 4 times.
public function upload_multiple(Request $request){
$stuff = new Stuffs();
$stuff->name = $request->input('name');
$stuff->detail = $request->input('detail');
$stuff->save();
$files = $request->file('images');
foreach ($files as $file){
$multiple = new Multiple(); //Multiple is a 'Model' not a table name
$destinationPath = 'uploads/';
$filename = $file->getClientOriginalName();
$upload_success = $file->move($destinationPath, $filename);
$multiple->images =$destinationPath.$filename;
$multiple->save();
}
So how can I do this in Laravel 5?
Many thank for help!
What you need is a One to Many relationship. Here's how you can set it up:
In your Model classes, add the following:
class Stuffs {
...
// A Stuff has many Mutliples
public function multiples() {
return $this->hasMany('App\Multiple');
}
}
class Multiple {
...
// A Multiple belongs to only one Stuff
public function stuff() {
return $this->belongsTo('App\Stuffs');
}
}
Then, while adding a Stuff, you can simply attach Multiples to it:
public function upload_multiple(Request $request) {
$stuff = new Stuffs();
$stuff->name = $request->input('name');
$stuff->detail = $request->input('detail');
$stuff->save();
$files = $request->file('images');
$multiples = [];
foreach ($files as $file) {
$multiple = new Multiple(); //Multiple is a 'Model' not a table name
...
$multiples[] = $multiple;
}
$stuff->multiples()->saveMany($multiples);
}
I have a db table named Student, with columns as id, name, age.
id is the Primary Key, name is not null, and age can be null
I want to implement the following in php, Zend:
Only add a duplicate student name in db if the age value is different.
Inside the function/action addStudentAction, I am calling the Student model's function -findStudent to implement the requirement:
public function findStudent($name)
{
$result = null;
$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->setIntegrityCheck(false)
->where('student.name = ?', $name);
//error_log($select->assemble());
$result = $this->getAdapter()->fetchRow($select);
return $result;
}
public function addStudentAction() {
$data = $_POST;
$studentModel = new Application_Model_Student;
$result = $studentModel->findStudent($data['name']);
if(!empty($result)) {
error_log("found student name in db, going to get age");
//Check for age
if( (!empty($result['age'] )) {
if( $result['age'] != $data['age']) {
error_log("going to add student as new record");
return $this->insert($data);
}
else {
error_log("not adding new student record ");
}
}
}
}
Now, there could be multiple records of Students with same name but different age values. Therefore, when adding a new student, I need to compare the ages of all records(if name matches) with the incoming value of age.
What could be best way to implement this requirement? Any help is greatly appreciated.
Thanks
The easiest way would be to create a compound UNIQUE index on the name, then age field. UNIQUE allows multiple NULL values, so that won't be an issue. Depending on your database size and usage, this might not be the most preferred option, in which case a simple SELECT of the student information before an INSERT to check if he/ she is already in there would be the best solution.
Let me know if I need to elaborate on this. I'd be happy to give you some examples.
How about you do a new SELECT with name and age:
public function findStudentWithAge($name, $age =null)
{
$result = null;
$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->setIntegrityCheck(false)
->where('student.name = ?', $name);
if($age) $select->where('student.age = ?', $age);
//error_log($select->assemble());
$result = $this->getAdapter()->fetchRow($select);
return $result;
}
Now in the addStudentAction:
public function addStudentAction() {
$data = $_POST;
$studentModel = new Application_Model_Student;
$result = $studentModel->findStudent($data['name'], $data['age']);
if(!empty($result)) {
error_log("found student with this age, cannot add the record");
} else {
$this->insert($data);
}
}