Subquery in SELECT using Yii2 ActiveRecord - yii2

Is it possible to convert this kind of SQL into ActiveRecord query in Yii2:
SELECT
*,
(select count(*) from pendaftar where pendaftar.prodi_pilihan_1 = a.id_prodi_penerima)as jum1,
(select count(*) from pendaftar where pendaftar.prodi_pilihan_2 = a.id_prodi_penerima)as jum2
FROM prodi_penerima as a
I have two relational models that are Pendaftar and ProdiPenerima.
This is Pendaftar model:
...
* #property ProdiPenerima $prodiPilihan1
* #property ProdiPenerima $prodiPilihan2
...
/**
* #return \yii\db\ActiveQuery
*/
public function getPekerjaanIdPekerjaan()
{
return $this->hasOne(Pekerjaan::className(), ['id_pekerjaan' => 'pekerjaan_id_pekerjaan']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUserPendaftar()
{
return $this->hasOne(User::className(), ['id' => 'id_user_pendaftar']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProdiPilihan1()
{
return $this->hasOne(ProdiPenerima::className(), ['id_prodi_penerima' => 'prodi_pilihan_1']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProdiPilihan2()
{
return $this->hasOne(ProdiPenerima::className(), ['id_prodi_penerima' => 'prodi_pilihan_2']);
}
And this is ProdiPenerima model:
...
* #property Pendaftar[] $pendaftars
* #property Pendaftar[] $pendaftars0
...
/**
* #return \yii\db\ActiveQuery
*/
public function getPendaftars()
{
return $this->hasMany(Pendaftar::className(), ['prodi_pilihan_1' => 'id_prodi_penerima']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPendaftars0()
{
return $this->hasMany(Pendaftar::className(), ['prodi_pilihan_2' => 'id_prodi_penerima']);
}
prodi_pilihan_1 and prody_pilihan_2 are foreign keys in pendaftar table, that key was referenced from ProdiPenerima table.

$result = ProdiPenerima::find()
->select([
'*',
'jum1' => Pendaftar::find()
->select(['COUNT(*)'])
->where('pendaftar.prodi_pilihan_1 = a.id_prodi_penerima'),
'jum2' => Pendaftar::find()
->select(['COUNT(*)'])
->where('pendaftar.prodi_pilihan_2 = a.id_prodi_penerima')
])
->alias('a')
->asArray()
->all();
Results can be accessed by:
foreach ($result as $row) {
echo $row['jum1'];
}
That because asArray() was used, so query return array of arrays instead of array of models.
If you need models, you should add properties into your models to store result of subqueries:
class ProdiPenerima extends ActiveRecord {
public $jum1;
public $jum2;
// ...
}
Then remove isArray() from query:
$result = ProdiPenerima::find()
->select([
'*',
'jum1' => Pendaftar::find()
->select(['COUNT(*)'])
->where('pendaftar.prodi_pilihan_1 = a.id_prodi_penerima'),
'jum2' => Pendaftar::find()
->select(['COUNT(*)'])
->where('pendaftar.prodi_pilihan_2 = a.id_prodi_penerima')
])
->alias('a')
// ->asArray()
->all();
Results can be accessed by:
foreach ($result as $model) {
echo $model->jum1;
}
But note that using asArray() will be faster, so unless you need access some model methods (or rely on typecasting of values from DB) I would prefer arrays.

Related

Column 'ip' cannot be null (SQL: insert into `logins` (`ip`, `steamid`, `time`)

insert into `logins` (`ip`, `steamid`, `time`)
I use php7.0 and phpmyadmin on vmware ubuntu server 16.04.6
I tried to fix it myself but I'm not really good at those kind of things if you need any more code tell me.
any help if welcome
the site wont let me post the full code here is the full code
This is the AuthController code
<?php namespace App\Http\Controllers;
use Invisnik\LaravelSteamAuth\SteamAuth;
use Illuminate\Support\Facades\DB;
use App\User;
use Auth;
use Carbon\Carbon;
class AuthController extends Controller
{
/**
* The SteamAuth instance.
*
* #var SteamAuth
*/
protected $steam;
/**
* The redirect URL.
*
* #var string
*/
protected $redirectURL = '192.168.1.12';
/**
* AuthController constructor.
*
* #param SteamAuth $steam
*/
public function __construct(SteamAuth $steam)
{
$this->steam = $steam;
}
/**
* Redirect the user to the authentication page
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function redirectToSteam()
{
return $this->steam->redirect();
}
/**
* Get user info and log in
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function handle()
{
if($this->steam->validate())
{
$info = $this->steam->getUserInfo();
$findUser = DB::table('users')->where('steamid', $info->steamID64)->first();
if(is_null($findUser))
{
$hasThisIp = DB::table('users')->where('ip', $this->getIp())->count();
if(!is_null($hasThisIp)) {
$connections = json_decode(json_encode($hasThisIp), true);
if($connections > 3) return view('connections');
else {
$array = array('<','>');
$numele = $info->personaname;
$name = str_replace($array, '*', $numele);
DB::table('users')->insert(
[
'name' => $name,
'steamid' => $info->steamID64,
'avatar' => $info->avatarfull,
'token' => csrf_token(),
'ip' => $this->getIp()
]
);

How to rename a datatable column name and value to island names that is generated from infyom laravel generator?

I have two models for Island and Fisher. I want to use datatable to display island name instead of (island_id) fisher_first_name and fisher_last_name
As displayed in the datatable
Island Id Fisher First Name Fisher Last Name
1 Dovecot Imap
2 Jon Tim
These are my two models relationships
public function fishers(){
return $this->hasMany(Fisher::Class);
}
public function island(){
return $this->belongsTo(Island::Class,'island_id');
}
This is the getColumns fuction from FisherDatatable that I need to use to change the island_id to island_names
protected function getColumns()
{
return [
'island_id'
'fisher_first_name',
'fisher_last_name',
];
}
This is also an extract from a FisherDatatable to show Island and Fisher relationship
public function query(Fisher $model)
{
return $model->newQuery()->with(['island']);
}
This is my Controller
namespace App\Http\Controllers;
use App\DataTables\FisherDataTable;
use App\Http\Requests;
use App\Http\Requests\CreateFisherRequest;
use App\Http\Requests\UpdateFisherRequest;
use App\Repositories\FisherRepository;
use App\Models\Island;
use Flash;
use App\Http\Controllers\AppBaseController;
use Response;
class FisherController extends AppBaseController
{
/** #var FisherRepository */
private $fisherRepository;
public function __construct(FisherRepository $fisherRepo)
{
$this->fisherRepository = $fisherRepo;
}
/**
* Display a listing of the Fisher.
*
* #param FisherDataTable $fisherDataTable
* #return Response
*/
public function index(FisherDataTable $fisherDataTable)
{
return $fisherDataTable->render('fishers.index');
}
/**
* Show the form for creating a new Fisher.
*
* #return Response
*/
public function create()
{
$islands = Island::pluck('island_name','id');
return view('fishers.create')->with('islands',$islands);
}
/**
* Store a newly created Fisher in storage.
*
* #param CreateFisherRequest $request
*
* #return Response
*/
public function store(CreateFisherRequest $request)
{
$input = $request->all();
$fisher = $this->fisherRepository->create($input);
Flash::success('Fisher saved successfully.');
return redirect(route('fishers.index'));
}
/**
* Display the specified Fisher.
*
* #param int $id
*
* #return Response
*/
public function show($id)
{
$fisher = $this->fisherRepository->find($id);
if (empty($fisher)) {
Flash::error('Fisher not found');
return redirect(route('fishers.index'));
}
return view('fishers.show')->with('fisher', $fisher);
}
/**
* Show the form for editing the specified Fisher.
*
* #param int $id
*
* #return Response
*/
public function edit($id)
{
$fisher = $this->fisherRepository->find($id);
$islands = Island::pluck('island_name','id');
if (empty($fisher)) {
Flash::error('Fisher not found');
return redirect(route('fishers.index'));
}
return view('fishers.edit')
->with('fisher', $fisher)
-> with('islands', $islands);
}
/**
* Update the specified Fisher in storage.
*
* #param int $id
* #param UpdateFisherRequest $request
*
* #return Response
*/
public function update($id, UpdateFisherRequest $request)
{
$fisher = $this->fisherRepository->find($id);
if (empty($fisher)) {
Flash::error('Fisher not found');
return redirect(route('fishers.index'));
}
$fisher = $this->fisherRepository->update($request->all(), $id);
Flash::success('Fisher updated successfully.');
return redirect(route('fishers.index'));
}
/**
* Remove the specified Fisher from storage.
*
* #param int $id
*
* #return Response
*/
public function destroy($id)
{
$fisher = $this->fisherRepository->find($id);
if (empty($fisher)) {
Flash::error('Fisher not found');
return redirect(route('fishers.index'));
}
$this->fisherRepository->delete($id);
Flash::success('Fisher deleted successfully.');
return redirect(route('fishers.index'));
}
}
just need to add name, title and data array to your getColumns methos
protected function getColumns()
{
return [
['name'=>'dropdown_label','title'=>'new name of label','data'=>"dropdown_label"],
['name'=>'dropdown_value','title'=>'new name of dropdwon value','data'=>"dropdown_value"],
'active'
];
}

Symfony 4 - complex form submited with json

I try to build form with nested entities.
src/Entity/Company
/**
* #ORM\ManyToOne(targetEntity="App\Entity\CompanyAddress", inversedBy="company")
* #Serializer\Groups({"company"})
*/
private $addresses;
/**
* #ORM\OneToOne(targetEntity="App\Entity\CompanyAddress")
* #ORM\JoinColumn(name="main_address")
*
* #Assert\NotBlank()
* #Serializer\Groups({"company"})
*/
private $mainAddress;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #ORM\JoinColumn(name="owner", onDelete="SET NULL", nullable=true)
* #Serializer\Groups({"company"})
*
*/
private $owner;
public function __construct()
{
$this->addresses = new ArrayCollection();
$this->accountants = new ArrayCollection();
}
/**
* #return array
*/
public function getAddresses()
{
return $this->addresses->toArray();
}
/**
* #param $addresses
* #return Company
*/
public function setAddresses($addresses): self
{
$this->addresses = $addresses;
}
/**
* #param CompanyAddress $address
* #return Company
*/
public function addAddress(CompanyAddress $address): self
{
if ($this->addresses->contains($address)) return $this;
$this->addresses->add($address);
return $this;
}
/**
* #param CompanyAddress $address
* #return Company
*/
public function removeAddress(CompanyAddress $address): self
{
if ($this->addresses->contains($address)) {
$this->addresses->removeElement($address);
// $address->setCompany(null);
}
return $this;
}
/**
* #return mixed
*/
public function getMainAddress()
{
return $this->mainAddress;
}
/**
* #param CompanyAddress $address
* #return Company
*/
public function setMainAddress(?CompanyAddress $address): self
{
$this->mainAddress = $address;
return $this;
}
/**
* #return User
*/
public function getOwner(): ?User
{
return $this->owner;
}
/**
* #param User|null $owner
* #return Company
*/
public function setOwner(?User $owner): self
{
$this->owner = $owner;
return $this;
}
// and other entity code
src/Entity/CompanyAddress.php
/**
* #ORM\OneToMany(targetEntity="App\Entity\Company", mappedBy="addresses", orphanRemoval=true)
*/
private $company;
/**
* #return Company
*/
public function getCompany(): Company
{
return $this->company;
}
/**
* #param Company $company
* #return CompanyAddress
*/
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
// some other code
Now I build Form
src/Form/CompanyType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('shortName')
->add('nip')
->add('regon')
->add('description')
->add('addresses', CollectionType::class, ['entry_type' => CompanyAddressType::class, 'allow_add' => true])
->add('mainAddress', CompanyAddressType::class)
->add('accountants', CollectionType::class, ['entry_type' => CompanyAccountantType::class, 'allow_add' => true])
->add('owner', UserCompanyType::class, ['empty_data' => null])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Company::class,
]);
}
src/Form/CompanyAddressType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('country')
->add('city')
->add('street')
->add('house')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => CompanyAddress::class,
]);
}
src/Controller/CompanyController.php
public function new(Request $request, CompanyService $cs)
{
// $this->denyAccessUnlessGranted('new');ump($request->getContent());
$company = new Company();
$form = $this->createForm(CompanyType::class, $company);
$form->submit(json_decode($request->getContent(), true));
if (!$form->isValid()) {
return $this->json([
'message' => 'Data validation error',
'errors' => $this->normalizeFormErrors($form)
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
try {
$company = $cs->addCompany($company);
} catch (\Exception $e) {
return JsonResponse::create(['error' => $e->getMessage()], 406);
}
return JsonResponse::fromJsonString($cs->getSerializer()->serialize($company, ['id', 'company']));
}
and Service src/Services/CompanyService.php
public function addCompany(Company $company)
{
if ($this->companyRepository->findOneByNipOrRegon(['nip' => $company->getNip(), 'regon' => $company->getRegon()]))
throw new \Exception($this->translator->trans('Company with given NIP or REGON exists'));
try {
$this->em->persist($company);
$this->em->flush();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
return $company;
}
Now I'm sending json data
{
"name":"Long Company Name",
"shortName":"Short Name",
"nip":"8888888",
"regon":"1111111",
"description":"Description",
"addresses": [ {
"city":"First City",
"street":"No street Name",
"house":"44",
"country":"Country"
}, {
"country":"Country",
"city":"Another City",
"street":"",
"house":"11"
}],
"mainAddress": {
"country":"Main Country",
"city":"Main City",
"street":"Main Street",
"house":"1"
},
"accountants": [],
"owner": {
"id":1
}
}
And I got error "Expected value of type \"App\\Entity\\CompanyAddress\" for association field \"App\\Entity\\Company#$addresses\", got \"Doctrine\\Common\\Collections\\ArrayCollection\" instead."
When I send empty array of adresses and send id as owner my owner in company is null :/ isn't get from database :/ When I remove option "empty_data" I get error "Could not determine access type for property "id" in class "App\Entity\User"
I'd like to add addresses from entity Comapany when I add Company, also I'd like to remove address from Company Entity.
How to create Entities from that Form? Or what fuctions should I add to Company entity?
See here :
/**
* #ORM\ManyToOne(targetEntity="App\Entity\CompanyAddress", inversedBy="company")
* #Serializer\Groups({"company"})
*/
private $addresses;
Your property is set as ManyToOne, which means in this case that it expects an instance of CompanyAddress. Yet you're giving it an array of CompanyAddress items.
I think this relation should be either OneToMany ( one company can have multiple adresses) or ManyToMany ( One company can have multiple adresses, which can be shared with other companies )
If you're not familiar with ManyToMany relationships, a little tutorial search should do the trick.

yii2- saving datas to multiple rows from one form

I am so new to the yii2 framework, I have a form that I want to save each party score to correspond to each party abbreviation. I don't know how to go about it. here is my code.
the model -
namespace app\models;
use Yii;
/**
* This is the model class for table "announced_pu_results".
*
* #property int $result_id
* #property string $polling_unit_uniqueid
* #property string $party_abbreviation
* #property int $party_score
* #property string $entered_by_user
* #property string $date_entered
* #property string $user_ip_address
*/
class AnnouncedPuResults extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'announced_pu_results';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['polling_unit_uniqueid', 'party_abbreviation', 'party_score', 'entered_by_user', 'date_entered', 'user_ip_address'], 'required'],
[['party_score'], 'integer'],
[['date_entered'], 'safe'],
[['polling_unit_uniqueid', 'entered_by_user', 'user_ip_address'], 'string', 'max' => 50],
// [['party_abbreviation'], 'string', 'max' => 4],
];
}
public function getPollingUnit()
{
return $this->hasOne(PollingUnit::className(), ['id' => 'polling_unit_uniqueid']);
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'result_id' => 'Result ID',
'polling_unit_uniqueid' => 'Polling Unit Uniqueid',
'party_abbreviation' => 'Party Abbreviation',
'party_score' => 'Party Score',
'entered_by_user' => 'Entered By User',
'date_entered' => 'Date Entered',
'user_ip_address' => 'User Ip Address',
];
}
}
the controller action is create ---
public function actionCreate()
{
$model = new AnnouncedPuResults();
if ($model->load(Yii::$app->request->post()) ){
//&& $model->save()) {
$post = yii::$app->request->post('AnnouncedPuResults');
$party_score = $post['party_score'];
$count = count($party_score);
for($i =0 ; $i < $count; $i++) {
$model->party_abbreviation = $post['party_abbreviation'];
$model->polling_unit_uniqueid = $post['polling_unit_uniqueid'];
$model->entered_by_user = $post['entered_by_user'];
$model->date_entered = $post['date_entered'];
$model->party_score = $post['party_score'];
$model->save();
}
return $this->redirect(['view', 'id' => $model->result_id]);
}else{
return $this->render('create', [
'model' => $model,
]);
}
}
this is the partial view form for the action create----
the screenshot of my form is attached
I want to save the results from my select boxes and the inputs the number of times they are selected to multiple rows in the database at a time
this is how the database looks like
please help me out, I hope my question is understandable.

Yii mysql datetime empty

I have a problem with a Yii model, I create a MySQL table with two datetime column.
And create the model with gii. The problem is that when I get the data from the model I get the datetime fields empty.
<?php
/**
* This is the model class for table "Template".
*
* The followings are the available columns in table 'Template':
* #property string $tmpId
* #property integer $fanPageId
* #property string $name
* #property string $title
* #property string $description
* #property string $headerFile
* #property string $msgNotTlt
* #property string $msgNotMsg
* #property string $msgNotImg
* #property string $msgNotLnk
* #property string $terms
* #property string $strProm
* #property string $endProm
*/
class Template extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #param string $className active record class name.
* #return Template the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'Template';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('fanPageId', 'numerical', 'integerOnly'=>true),
array('name, title, description, headerFile, msgNotTlt, msgNotMsg, msgNotImg, msgNotLnk, terms', 'length', 'max'=>11),
array('strProm, endProm', 'safe'),
//array('endProm, strProm', 'type', 'type'=>'datetime', 'datetimeFormat'=>'yyyy/M/d H:m:s'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('tmpId, fanPageId, name, title, description, headerFile, msgNotTlt, msgNotMsg, msgNotImg, msgNotLnk, terms, strProm, endProm', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'tmpId' => 'Tmp',
'fanPageId' => 'Fan Page',
'name' => 'Name',
'title' => 'Title',
'description' => 'Description',
'headerFile' => 'Header File',
'msgNotTlt' => 'Msg Not Tlt',
'msgNotMsg' => 'Msg Not Msg',
'msgNotImg' => 'Msg Not Img',
'msgNotLnk' => 'Msg Not Lnk',
'terms' => 'Terms',
'strProm' => 'Str Prom',
'endProm' => 'End Prom',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('tmpId',$this->tmpId,true);
$criteria->compare('fanPageId',$this->fanPageId);
$criteria->compare('name',$this->name,true);
$criteria->compare('title',$this->title,true);
$criteria->compare('description',$this->description,true);
$criteria->compare('headerFile',$this->headerFile,true);
$criteria->compare('msgNotTlt',$this->msgNotTlt,true);
$criteria->compare('msgNotMsg',$this->msgNotMsg,true);
$criteria->compare('msgNotImg',$this->msgNotImg,true);
$criteria->compare('msgNotLnk',$this->msgNotLnk,true);
$criteria->compare('terms',$this->terms,true);
$criteria->compare('strProm',$this->strProm,true);
$criteria->compare('endProm',$this->endProm,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
In rules of you model add the two columns:
array('datetime_1, datetime_2', 'safe'),
array('id, <attributes>, datetime_1, datetime_2', 'safe', 'on'=>'search'),
If possible, post you code/model...