CakePHP, Query from Model - php

How I can execute a SQL query in CakePHP.
I want to make some like this code
$employees = $this->Employee->find('all');
but introducing my own SQL statment.

Insert into your Model a function that executes your SQL statment,
public function get_employees() {
$sql = 'select * from employees';
$data = $this->query($sql);
return $data;
}
And call this function like this way:
$employee = new Employee();
$data = $employee->get_employees();

In model you can't write model name. Its already detected. Use only
$this->find('all');

Assuming your statement is inside EmployeesController.php
$employeeRows = $this->employee->find('all', array('conditions'=>array('id' => 100)));
if you are in another controller, you have to load the model before the find
$this->loadModel('employee');
if you are in a view, you can write a helper and use raw sql
The cakephp website also offers the following controller logic
$this->Picture->query("SELECT * FROM pictures LIMIT 2;");

Related

Database class with filters

I'm building my own CMS and I used my own Database class for it.
In some frameworks there is a way to do a function on another function
$firstValues = $this-db->query('your query')->first();
What do I kind of class do I need for the ->first().
Is there a way in php to do this? Do I need to use an Abstract class? Does anybody has an example?
If you need any more information, please ask me!
Thanks for helping!
Tom
What do I kind of class do I need for the ->first().
Most frameworks provide a "Query Builder" class to generate and execute SQL statements without writing SQL manually.
Is there a way in php to do this?
Yes, just pick a query builder:
https://github.com/cakephp/database
https://github.com/illuminate/database
Do I need to use an Abstract class?
No
Does anybody has an example?
Illuminate Database (Laravel):
$userRow = Capsule::table('users')->where('votes', '>', 100)->get();
CakePHP:
$userRow = $connection->newQuery()
->from('users')
->select('*')
->where(['votes >' => 20])
->execute()
->fetch('assoc');
Under the hood the first() method just fetches the first row.
PDO example:
$statement = $pdo->prepare("SELECT * FROM users WHERE votes > :votes LIMIT 1");
$statement->execute(['votes' => 20]);
$userRow = $statement->fetch();
You have to pass $this between methods.
Here's some example:
Class Db {
private $_query_result;
public function query($query_string = '')
{
// make your query or smth
// save for example array of results
$this->_query_result = $your_query_result;
return $this;
}
public function first()
{
return array_shift($this->_query_result);
}
}

how to reset default scope in yii2

I am using default scope in my project and it works fine.
public static function find()
{
return parent::find()->where(['is_deleted' => 0]);
}
But now, I want to show all the deleted records in the report section.
How can I skip default scope for particular query only?
Use this to clear or redefine your condition:
$model = Model::find()->where('');
If you want to make sure that you're using fresh query (without any params or conditions), you need to create new ActiveQuery object for given model.
$query = Yii::createObject(ActiveQuery::className(), [Post::class]);
Or add a helper method in model itself:
public static function freshFind()
{
return parent::find();
}
and use it instead of Post::find().
You could avoid the use of find() ..using a findBySql
$sql = 'SELECT * FROM product';
$product= Product::findBySql($sql,)->all();
in this way you all the models of product ..
and you could also use
$sql = 'SELECT * FROM ' . Product::tableName() ;
for avoid explici table name for Products

Making where clause dynamic in sql in CI

I want to display the content of page dynamically this following code is working fine but it only shows the content of specific id...how can i make that dynamic??
Model
public function getAllDepartment() {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID=15");
return $join->result_array();
}
Controller
public function reportDisplay(){
$data['clubs'] = $this->labdoc_model->getAllDepartment();
$this->load->view('SystemAdminUser/labreport', $data);
}
There is simple work around for this using Query Builder class of CI.
So this is how your code will look like,
$id=15;
$this->db->select('*');
$this->db->from('labreport_db');
$this->db->join('patient_db', 'labreport_db.P_ID = patient_db.id');
$this->db->where('labreport_db.P_ID', $id);
$query = $this->db->get();
This is standard approach in CI to make database operation using query builder class in which you can perform dynamic WHERE condition.
For which just change the value of $id and the query will do the needful.
Reference: https://www.codeigniter.com/userguide3/database/query_builder.html#selecting-data
Hold the id in some variable like:
$pid = $_REQUEST['p_id'];
// $_REQUEST['p_id'] will contain the dynamic value in it
and put this variable in your query like:
where labreport_db.P_ID = $pid;
It will show the data for the value contained in $pid, and make sure it contains the dynamic value in it.
You can used this code for you solution.
Model.php
public function getAllDepartment($pId) {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID=".$pId);
return $join->result_array();
}
Controller.php
public function reportDisplay(){
$pid = $_REQUEST['pid']; //OR $_GET['pid']; OR $_POST['pid']; You can pass your id for get content
$data['clubs'] = $this->labdoc_model->getAllDepartment($pid);
$this->load->view('SystemAdminUser/labreport', $data);
}
There are a couple of ways doing it. One of them is through CI routing ability.
Model
public function getAllDepartment($p_id = 0) {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID={$p_id}");
return $join->result_array();
}
Comment: I added $p_id as a variable to fetch the ID dynamically.
Controller
public function reportDisplay($p_id = 0){
$data['clubs'] = $this->labdoc_model->getAllDepartment($p_id);
$this->load->view('SystemAdminUser/labreport', $data);
}
Comment: We also add a variable called $p_id in the reportDisplay function and pass it to your model's getAllDepartment()function.
How to fetch the report dynamically
I don't know your URL structure, but for example purposes let's say it's http://localhost/yourcontrollername/reportDisplay/
To access it dynamically, simply add an ID after the reportDisplay
For example:
http://localhost/yourcontrollername/reportDisplay/15
http://localhost/yourcontrollername/reportDisplay/10

Codeigniter safe queries and xss clean

I try to remake methods which got queries from ids to methods which work with slugs.
So basically this:
public function view($id)
{
$id = (int)$id;
$this->db->where('id', $id)->get('recipes')
}
To this:
public function view($slug)
{
$this->db->where('slug', $slug)->get('recipes')
}
In the second method I'm aware that this is a xss not safe. I think that it will be best to remake all queries with query bindings.
Like so:
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));
But I have too munch queries to remake is it possible to have some function whic to clean the slug from the codeigniter or something in the second method example?
Is it ok to use the security xss-clean method to the slug before to use it in the query:
$this->security->xss_clean($slug)
I guess all insert or update data come from a form, if you go to application/config/config.php and set
$config['csrf_protection'] = FASLE;
to
$config['csrf_protection'] = TRUE;
this helpyou to filter all inputs (xss_clean)
public function view($slug)
{
$slug_new=$this->db->escape_str(trim($slug));
$this->db->where('slug', $slug_new)->get('recipes')
}

Does get_where() allow multiple parameters?

I am passing a parameter from model to view like this
Model
class school_model extends CI_Model{
function employee_get($student_id){
$query = $this->db->get_where('students', array('student_id'=>$student_id));
return $query->row_array();
}
}
Controller
function bret($student_id){
$this->load->model('school_model');
$data = $this->school_model->employee_get($student_id);
echo $data['student_gender'];
}
This obviously translates to select * from students where id=id given for example and seen through the browser like http://example.com/env/at/index.php/frontpage/bret/306
I am wondering if the get_where() is suitable if i wanted to have this query
select student_gender,student_has_a_medical_condition from students where (student_gender = 'female' && student_has_a_medical_condition = 'no') LIMIT 40;
Will i need to extend get_where() for it to work?.
First,I suggest reading the excellent documentation for CodeIgniter on the ActiveRecord class.
You don't have to extend get_where() but just use the existing methods to define your query:
function employee_get($student_id){
$this->db->select('student_gender','student_has_a_medical_condition');
$query = $this->db->get_where('students', array('student_id'=>$student_id,'student_has_a_medical_condition'=>'no','student_gender'=>'female'),40);
return $query->row_array();
}
Of course you can pass in the additional parameters to the function so they are not hardcoded, and you can also pass in the desired columns as a paremeter, too. But start with the documentation.

Categories