yii active record via issue - php

Please help;
i have models:
class Service extends \yii\db\ActiveRecord{
public function getCategory()
{
return $this->hasOne(ServiceCategory::className(), ['id' => 'service_category_id']);
}
}
class ServiceOffer extends \yii\db\ActiveRecord
{
public function getService()
{
return $this->hasOne(Service::className(), ['id' => 'service_id']);
}
public function getCategory()
{
return $this->hasOne(ServiceCategory::className(), ['id' => 'service_category_id'])->via('service');
}
public function getProperties()
{
return $this->hasMany(ServiceProperty::className(), ['service_category_id' => 'id'])
->via('category');
}
}
When i do query:
$query = ServiceOffer::find()->with(['properties'])->all();
or:
$query = ServiceOffer::find()->joinWith(['properties'])->all();
i have error:
Getting unknown property: app\models\ServiceOffer::service_category_id
but if i do this for see query sql:
$query = ServiceOffer::find()->joinWith(['properties']);
echo $query->prepare(\Yii::$app->db->queryBuilder)->createCommand()->rawSql;
sql:
SELECT "service_offer".* FROM "service_offer"
LEFT JOIN "service" ON "service_offer"."service_id" = "service"."id"
LEFT JOIN "service_category" ON "service"."service_category_id" = "service_category"."id"
LEFT JOIN "service_property" ON "service_category"."id" = "service_property"."service_category_id"
query without problem and execute
Why ActiveRecord find service_category_id property in ServiceOffer model?

Related

Laravel Query Search Function

This is my controller:
public function index($mid,$payload){
$search = $payload['search'];
$users = DB::select('SELECT a.id, a.alternate_id, a.setujuterma, a.mykad, a.nama, a.email, a.notel, a.etunai,
b.ranktitle, c.ranktitle AS appointed_rank, d.nama as hirarki, e.alternate_id as placement,
e.nama as leadername, a.akses, a.suspendreason, a.regstamp,
a.matagajet, f.display as hirarkidisplay, IF(a.mykadverify = "3","1","0") as mykadverifydecode
FROM pengguna as a
LEFT JOIN penggunarank b ON a.effective_rank = b.id
LEFT JOIN penggunarank c ON a.appointed_rank = c.id
LEFT JOIN hirarki d ON a.userrank = d.id
LEFT JOIN pengguna e ON a.placement = e.id
LEFT JOIN hirarkimid f ON a.userrank = f.hirarki AND a.mid = f.mid
WHERE a.mid ='. $mid .' AND a.akses != -1'
);
$sortUser = collect($users)->sortByDesc('alternate_id')->toArray();
$collection = collect($sortUser);
$count = count($users);
// SEARCH BOX
if ($search) {
$collection->where(function ($q) use ($search) {
$q->where("alternate_id","LIKE","%{$search}%")
->orWhere("nama","LIKE","%{$search}%")
->orWhere("mykad","LIKE","%{$search}%")
->orWhere("notel","LIKE","%{$search}%")
->orWhere("email","LIKE","%{$search}%");
});
}
return [
$user,
$count
];
}
So,
$users return an array.
$collection return collection
for the search box, if I use $users, I get error
"Call to a member function where() on Array"
and if I use $collection, I get
message: "explode() expects parameter 2 to be string, object given", exception: "ErrorException",…}
Any help would be greatly appreciated. Thanks.
public function search(Request $payload){
$search = $payload['search'];
if($search == "")
{
$users = Payee::whereNotNull('payee_name')->take(10)->get();
}
else
{
$users = Payee::whereNotNull('payee_name')
->where(function ($q) use ($search) {
$q->where("payee_name","LIKE","%$search%")
->orWhere("payee_nick_name","LIKE","%$search%");
})->take(10)->get();
}
return [
$users,
];
}
I found an answer to my question. All I need is to change the query into eloquent model class. There is no other way if I want to use the where() function for my search. First I create model User.php:
<?php
namespace App;
use App\WithdrawEcash;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Propaganistas\LaravelPhone\PhoneNumber;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable, HasFactory;
protected $table = 'pengguna';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $guarded = ['id'];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// user registered by
public function userRegby()
{
return $this->belongsTo(User::class, 'regby');
}
// user leader
public function userPlacement()
{
return $this->belongsTo(User::class, 'placement');
}
public function penggunaRank()
{
return $this->belongsTo(PenggunaRank::class, 'effective_rank');
}
public function appointedRankUser()
{
return $this->belongsTo(PenggunaRank::class, 'appointed_rank');
}
public function penyatabonus()
{
return $this->belongsTo(User::class, 'id', 'pengguna');
}
//Hirarkimid userrank
public function userHirarki()
{
return $this->belongsTo(Hirarkimid::class, 'userrank', 'hirarki');
}
public function userhirarchy()
{
return $this->belongsTo(Hierarchy::class, 'userrank')->select('id', 'nama');
}
public function systemHirarki()
{
return $this->belongsTo(Hierarchy::class, 'userrank');
}
// user order
public function userOrders()
{
return $this->hasMany(Order::class, 'pengguna');
}
// user order for registration report
public function userOrder()
{
return $this->hasOne(Order::class, 'pengguna');
}
public function hierarchy()
{
$hirarki = $this->belongsTo(Hirarkimid::class, 'userrank', 'hirarki')
->select('hirarki', 'display', 'shownilaibelian', 'show_harga_ketika_pesanan')
->where('mid', auth()->user()->mid);
if ($hirarki) {
return $hirarki;
} else {
return $this->belongsTo(Hierarchy::class, 'userrank')->select('id', 'nama');
}
}
public function myCartLists()
{
return $this->hasMany(AddToCart::class, 'user_id');
}
public function bonusStatement()
{
return $this->hasMany(PenyataBonus::class, 'pengguna');
}
public function currentBonusStatement()
{
return $this->hasMany(PenyataBulanSemasa::class, 'pengguna');
}
public function withdrawEcash()
{
return $this->hasMany(WithdrawEcash::class, 'pengguna');
}
public function fileupload()
{
return $this->morphOne(FileUpload::class, 'file_upload');
}
public function fileuploads()
{
return $this->morphMany(FileUpload::class, 'file_upload');
}
public function voucherdetail()
{
return $this->hasMany(Voucherdetail::class, 'pengguna');
}
public function countryCode()
{
return $this->hasOne(Negara::class, 'nama', 'negara')->value('kod');
}
public function setNotelAttribute($value)
{
if (!is_null($value)) {
$country_code = $this->countryCode() != '' ? $this->countryCode() : 'MY';
$this->attributes['notel'] = PhoneNumber::make($value, $country_code)
->formatForMobileDialingInCountry($country_code);
} else
$this->attributes['notel'] = $value;
}
public function setNotelcsAttribute($value)
{
if (!is_null($value)) {
$country_code = $this->countryCode() != '' ? $this->countryCode() : 'MY';
$this->attributes['notelcs'] = PhoneNumber::make($value, $country_code)
->formatForMobileDialingInCountry($country_code);
} else
$this->attributes['notelcs'] = $value;
}
}
And in my controller I simply call the user model:
$user = User::query()->select('id', 'alternate_id', 'setujuterma', 'mykad', 'nama', 'email', 'notel', 'etunai',
'effective_rank','appointed_rank', 'akses', 'suspendreason', 'regstamp',
'matagajet', 'userrank','mykadverify','placement')
->with([
'penggunaRank' => function($q) use ($mid){
$q->select('id','ranktitle')->where('mid',$mid);
},
'appointedRankUser' => function($q) use ($mid){
$q->select('id','ranktitle')->where('mid',$mid);
},
'systemHirarki'=> function($q){
$q->select('id', 'nama');
},
'userHirarki' => function($q) use ($mid){
$q->select('hirarki','display')->where('mid',$mid);
},
'userPlacement' => function($q){
$q->select('id','alternate_id','nama');
}
])
->where('mid',$mid)
->where('akses','!=',-1);
if ($search) {
$user->where(function($q) use ($search){
$q->where("alternate_id","LIKE","%{$search}%")
->orWhere("nama","LIKE","%{$search}%")
->orWhere("mykad","LIKE","%{$search}%")
->orWhere("notel","LIKE","%{$search}%")
->orWhere("email","LIKE","%{$search}%");
});
}
return $user->orderBy('alternate_id','desc')
Hope everyone can get benefits from this. Thank you.

Yii2 get data with join table

I want to get all data from main table with left join relation with its own conditions
MainTableSearch.php
class MainTableSearch extends MainTable
{
public $table_two;
public $table_three
public function search($params)
{
$query = MainTable::find();
$query->joinWith(['table_two']);
$query->joinWith(['table_three']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
....
MainTable.php
class MainTable extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'main_table';
}
public function getTableTwo()
{
return $this->hasOne(TableTwo::className(), [main_id' => 'id'])->andWhere(['table_two.something' => 2]);
}
public function getTableThree()
{
return $this->hasOne(TableThree::className(), ['main_id' => 'id'])->andWhere(['table_three.something' => 2]);
}
I want to see all data from main table in grid view and if table_two.something or table_three.something doesn't meet requirement to return null in that field.
I also tried
return $this->hasOne(TableThree::className(), ['main_id' => 'id'])->andWhere(['table_three.something' => 2])->orWhere(['table_three.something' => NULL]);
[SOLVED]
$query->leftJoin('table_two','main_table.id = table_two.main_id
AND (table_two.something=1 OR table_two.something IS NULL)');

How to avoid ambiguous field while reusing query shorthand in Yii2?

I have table like below.
CREATE TABLE A (
id INT,
relationId INT,
status INT
)
CREATE TABLE B (
id INT,
status INT
)
The class file is like below
class A extends \yii\db\ActiveRecord {
public function getB() {
return $this->hasOne(B::class, ['id' => 'relationId']);
}
public function find() {
return new AQuery(__CLASS__);
}
}
class AQuery extends \yii\db\Query {
public function isActive() {
return $this->andWhere(['status' => 1]);
}
public function isNotActive() {
return $this->andWhere(['status' => 0]);
}
}
class B extends \yii\db\ActiveRecord {
public function find() {
return new BQuery(__CLASS__);
}
}
class BQuery extends \yii\db\Query {
public function isActive() {
return $this->andWhere(['status' => 1]);
}
public function isNotActive() {
return $this->andWhere(['status' => 0]);
}
}
I'm doing something like this
$model = A::find()
->joinWith([
'b' => function(BQuery $query) {
$query->isNotActive();
}
])
->isActive()
->one();
This will produce error
Column 'status' in where clause is ambiguous"
The only way I know is to manually add alias to $query->from and rewrite the $query->andWhere. But is there any easier way to reuse the query shorthand?
Use ActiveRecord::tableName() instead of aliasing (which doesn't seem to be an active record feature in Yii2). The tableName() can be accessed through the modelClass property of \yii\db\ActiveQuery.
public function isActive() {
$modelClass = $this->modelClass;
return $this->andWhere([$modelClass::tableName().'.status' => 1]);
}
You can enhance your isActive() method to accept aliases with an optionnal parameter. You can try something like this:
class AQuery extends \yii\db\Query {
protected function getAlias($alias = null) {
return $alias !== null ? $alias : A::tableName();
}
public function isActive($alias = null) {
$alias = $this->getAlias($alias);
return $this->andWhere(["{$alias}.status" => 1]);
}
public function isNotActive($alias = null) {
$alias = $this->getAlias($alias);
return $this->andWhere(["{$alias}.status" => 0]);
}
}

How to do join query in laravel

Business Model
public function groupTag()
{
return $this->belongsTo('GroupTag');
}
Group Tag Model
public function tag()
{
return $this- >belongsToMany('Tag','group_tag_tags','group_tag_id','tag_id')
->withTimestamps();
}
public function business()
{
return $this->hasOne('Business');
}
Tag Model
public function groupTag()
{
return $this->belongsToMany('Group','group_tag_tags','group_tag_id','tag_id')->withTimestamps();
}
Now how do i run this query into a laravel project
SELECT * FROMbusinesses` as b,
group_tags as gt,
group_tag_tags as gtt,
tags as t
where b.group_tag_id = gt.id and gt.id = gtt.group_tag_id and gtt.tag_id = t.id and t.id = 36 or b.name like '%a%' and b.city_id = 5 group by b.id'
DB::table('businesses')
->join('group_tags','group_tags.id','=','businesses.group_tag_id')
->join('group_tag_tags','group_tag_tags.group_tag_id','=','group_tags.id')
->join('tags','tags.id','=','group_tag_tags.tag_id')
->where('tags.id',"=",36)
->where('b.name',"LIKE",'%a%')
->where('b.city_id',"=",5)
->select('businesses.id','businesses.name','businesses.description','businesses.image')
->groupBy('businesses.id')

TableGateway with multiple FROM tables

I would like to do a simple INNER JOIN between two tables in Zend2.
Concretely, I would like to do this in Zend2:
SELECT * FROM foo, bar WHERE foo.foreign_id = bar.id;
I have a FooTable:
class FooTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function get($id)
{
$rowset = $this->tableGateway->select(function (Select $select) {
$select->from('foo');
});
}
}
The $select->from('foo'); returns an error:
==> Since this object was created with a table and/or schema in the constructor, it is read only.
So, I can't tweak my FROM statement to match a simple inner join between FooTable and BarTable.
I hope this will help you along your journey as this is a working example I have:
namespace Pool\Model;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;
class IpaddressPool extends AbstractTableGateway
{
public function __construct($adapter)
{
$this->table = 'ipaddress_pool';
$this->adapter = $adapter;
$this->initialize();
}
public function Leases($poolid)
{
$result = $this->select(function (Select $select) use ($poolid) {
$select
->columns(array(
'ipaddress',
'accountid',
'productid',
'webaccountid'
))
->join('account', 'account.accountid = ipaddress_pool.accountid', array(
'firstname',
'lastname'
))
->join('product_hosting', 'product_hosting.hostingid = ipaddress_pool.hostingid', array(
'name'
))
->join('webaccount', 'webaccount.webaccountid = ipaddress_pool.webaccountid', array(
'domain'
))->where->equalTo('ipaddress_pool.poolid', $poolid);
});
return $result->toArray();
}
}

Categories