passing values to custom find in Model - php

I have the following custom find in my model which I'd like to re-use depending on values that are passed to it.
public function _findActive($state, $query, $result = array()) {
if ($state === 'before') {
$query['conditions'] = array('WebRequest.status' => false, 'WebRequest.read_status' => false);
$query['contain'] = false;
$query['limit'] = 25;
$query['order'] = array('WebRequest.created' => 'asc');
return $query;
}
return $result;
}
I can call this function from my controller and it will paginate the results as 25 per page. However, I would like to be able to pass the limit value to the function and limit by this volume per page as required. I can add an extra field $limit to the function parameters ($state, $query, $result = array(), $limit) which is passed into the function. If I debug at the start of the function atif($state === 'before') then the value remains as it was passed in, but as this function is called automatically twice, it by default gets reset back to null the second time the function is called, so I lose the value that was passed in. Is there any way around this?

Try this:
public function _findActive($state, $query, $result = array()) {
if ($state === 'before') {
$query['conditions'] = array(
'WebRequest.status' => false,
'WebRequest.read_status' => false
);
$query['contain'] = false;
$query['limit'] = 25;
$query['order'] = array('WebRequest.created' => 'asc');
return $query;
} elseif ($state == 'after') {
return $results;
}
}`

You can store the original $limit value in a private class variable in your model and use it for the limit. Something like:
class YourModel extends AppModel {
private $_originalLimit;
public function _findActive($state, $query, $result = array, $limit) {
....
if (!empty($limit))
$this->_originalLimit = $limit;
$query['limit'] = $this->_originalLimit;
....
}
}
When this function is called for the second time with a null $limit, your class variable, which has the original $limit value, will be used for the limit.

Related

How to pass multiple parameters from different controller functions on single model function

I have two controller functions both need one model function but when I pass parameters to single model function it shows me an error, I need help if there is another method to pass parameters
Controller
public function view_files()
{
$assignment_id='1255';
$data['files'] = $this->AdminModel->getRows111();
$this->load->view('admin/view_files', $data);
}
function download_test1(){
$id = $this->uri->segment(3);
if (empty($id)){
redirect(base_url());
}
$data = $this->AdminModel->getRows111($id);
$filename =$data['assignment_file_name'];
$fileContents = file_get_contents(base_url('upload/'.
$data['assignment_file_name']));
force_download($filename, $fileContents);
}
Model
public function getRows111($id=''){
$this->db->select('*');
$this->db->where('assignment_id','1255');
$this->db->from('tbl_assignments_files');
if($id){
$this->db->where('assignment_file_id',$id);
$query = $this->db->get();
$result = $query->row_array();
}else{
$query = $this->db->get();
$result = $query->result_array();
}
return !empty($result)?$result:false;
}
}
function 1
$data['files'] = $this->AdminModel->getRows111(assignment_id);
function 2
$data = $this->AdminModel->getRows111($id);
model by doing this, shows error
public function getRows111($id='',$assignment_id){
public function getRows111($id='',$assignment_id=""){
$this->db->select('*');
$this->db->from('tbl_assignments_files');
//if assignment_id is not empty it will add where clause to statement
if($assignment_id != ""){
$this->db->where('assignment_id',$assignment_id);
}
//if id is not empty it will add where clause to statement
if($id != ""){
$this->db->where('assignment_file_id',$id);
}
$query = $this->db->get();
$result = $query->result_array();
return !empty($result)?$result:false;
}
}
To call model function first parameter will be $id and second will be $assignment_id
To call model function by $id
$data = $this->AdminModel->getRows111($id);
OR
$data = $this->AdminModel->getRows111($id,'');
To call function by $assignment_id
$data = $this->AdminModel->getRows111("",$assignment_id);
To call function by both $id and $assignment_id
$data = $this->AdminModel->getRows111($id,$assignment_id);
Hope this helps!
you are using your function wrong,
base on the function getRows111 it does have 2 parameters need the $id and $assignment_id
proper used would be like this,
$this->AdminModel->getRows111($id, $assignment_id);
I suggest for your function to make it more flexible is this.
public function getRows111($array){
$id = $array[0];
$assignment_id = $array[1];
}
then call the function using with array parameter
$this->AdminModel->getRows111([$id, $assignment_id]);
to handle the array and you want it to be more flexible.
public function getRows111($array){
$id = isset($array['id']) ? $array['id'] : "";
$assignment_id = isset($array['assignment_id']) ? $array['assignment_id'] : "";
}
call the function like this
$this->AdminModel->getRows111(
['id' => $id,
'assignment_id' => $assignment_id
]);
// if you want just the id
$this->AdminModel->getRows111(['id' => $id]);
// or the the assignment id
$this->AdminModel->getRows111(['assignment_id' => $assignment_id]);

How to print max() value in JSON

How can I print highest value in JSON form result of 3 functions.
Controller :
class TimeFrameStatisticsController extends Controller
{
public function one()
{
return 3;
}
public function two()
{
return 1;
}
public function three()
{
return 4;
}
//FUNCTION FOR 4rth to get HIGHEST value
public function HighestValue() {
$func_names = ['three','one','two'];
// Call each method and store result.
foreach($func_names as $name) {
$results[$name] = $name();
}
$max = max($results);
$max_funcs = array_keys($results, $max);
return response()->json($max_funcs);
}
}
Error in OUTPUT of public function HighestValue() for API : Call
to undefined function public function one()
AND
Other 3 functions are result by API:
My Question is what should i do? Should I create Object and how ?
This function giving me perfect result of highest value from 3 different.
public function allCmp()
{
$firstTradeValue = $this->one();
$lastTradeValue = $this->two();
$otherTradeValue = $this->three();
//Set all in one array
$allTrades = array("firstHourTrades" => $firstTradeValue, "lastHourTrades" => $lastTradeValue, "otherHoursTrades" => $otherTradeValue );
//Get the highest value
$highestValue = max($allTrades);
//Get the corresponding key
$key = array_search($highestValue, $allTrades);
return response()->json($key);
}

how to store data in an array in a recursive function

I have made a recursive function, and I want to add the data it returns to an array each time the function is called.
This is my current implementation:
public function getParentCategory($categoryId) {
$category = Category::find($categoryId);
if($category != NULL){
$catArray[] = $category->id;
if($category->parent_category_id != NULL) {
$this->getParentCategory($category->parent_category_id);
}
}
}
I want to store data in catArray each time the function is called.
You can just return the data from the function. You also need to pass it to the function, or use a default parameter:
public function getParentCategory($categoryId, $catArray = array()) {
$category = Category::find($categoryId);
if ($category != NULL){
$catArray[] = $category->id;
if ($category->parent_category_id != NULL){
$catArray = $this->getParentCategory($category->parent_category_id, $catArray);
}
}
return $catArray;
}
You can use array_unshift() instead of $catArray[]= to have $catArray in reverse order (and/or add $category->id after the return from the recursion).

Chaining methods in PHP

$db->select("users")->where(array("username", "=", "username"));
$db->update("users", array("username" => "username", "password" => "12345"))->where(array("id", "=", "14"));
Ok, I want to write the statements like above, by chain the where() method onto select, update and delete.
My problem is; how to determine if I used the select, update or delete before the where, so I can bind the right values onto the right statement.
I want something like this:
public function where() {
if($this->select()) {
// so if $db->select("users")->where(array("username", "=", "username"));
// save the where data in the select variable.
}
elseif($this->update()) {
// so if $db->update("users", array("username" => "username", "password" => "12345"))->where(array("id", "=", "14"));
// save the where data in the update variable.
}
elseif($this->delete()) {
// so if $db->delete("users")->where(array("username", "=", "username"));
// save the where data in the delete variable.
}
}
But the code above is of course not valid, and I dont use any frameworks.
public function select($table, $what = null) {
$what == null ? $what = "*" : $what;
$this->_select = "SELECT {$what} FROM {$table}";
return $this;
}
You would have to maintain that state. It's not about telling whether the previous call was a select() or an update(), that's the wrong way to think about the problem. You just need each of select/update/delete to modify $this, so that $this, always knows what kind of query it's building.
A dead simple example:
public function select() {
$this->kind == 'select';
return $this;
}
public function where() {
if ($this->kind == 'select') {
...
return $this;
}
The only thing that your chained methods share is that they each return $this, so that a subsequent method can be chained onto the end. It's all about storing up state in $this until some final method call actually evalates the built-up query.
Something like:
public function select($table, $fields = '*')
{
$this->query = "SELECT {$fields} FROM `{$table}`";
return $this;
}
public function where($conditions = [])
{
if ($this->query)
{
if ($conditions)
{
foreach ($conditions as $key => &$val)
$val = "`{$key}` = '{$val}'";
$this->query .= ' WHERE ' . implode(' AND ', $conditions);
}
$db->query($this->query);
$this->query = '';
return $this;
}
}
This would work, however, you have to notice that this structure would allow you to do things like:
$db->where();
This is perfectly valid even though doesn't make sence to call where() in the database directly.
Also, queries that don't require a WHERE clause would not run, because only where() actually makes the call.
How to solve this?
We can actually use a very interesting mechanic of OOP: The destructor method. PHP destroys objects immediately after they are no longer in use, and we can explore this feature here as a trigger to run the query. We only have to separate the query to a new object.
class dbQuery
{
private $db;
private $conditions = [];
function where($conditions = [])
{
$this->conditions = array_merge($this->conditions, $conditions);
return $this;
}
function __construct($db, $query)
{
$this->db = $db;
$this->query = $query;
}
function __destruct()
{
if ($this->conditions)
{
foreach ($this->conditions as $key => &$val)
$val = "`{$key}` = '{$val}'";
$this->query .= ' WHERE ' . implode(' AND ', $this->conditions);
}
$this->db->result = $db->query($this->query);
}
}
class Database
{
public $result = null;
protected static $instance;
function __construct()
{
if (!self::$instance)
self::$instance = new mysqli('localhost', 'user', 'password', 'dbname');
}
public function query($query)
{
return self::$instance->query($query);
}
public function select($table, $fields = '*')
{
return new dbQuery($this, "SELECT {$fields} FROM `{$table}`");
}
}
This way $db->where() won't work as it doesnt exist, and using $db->select('table') or $db->select('table')->where([...]) will both give results, and even allows extending the syntax to use where() multiple times like:
$db->select('table')->where(['id' => 100])->where(['price' => 1.99]);

how to return model in function with Yii

I want to check if a user with the specified ID was created or not, if not I will create a new user and return it. And if the user already existed, I will return it. When I do this, the server can't load. I have 2 functions:
public function actionCreateNewUser() {
$aID = "4324";
$rs = $this->canCreateNewUser($aID);
}
public function canCreateNewUser($aID) {
$rsUser = User::model()->find('AID=:aID', array('aID' => $aID));
return $rsUser[0];
}
The canCreateNewUser implementation is wrong because find returns either a User model or null. It should be written like this instead:
public function canCreateNewUser($aID) {
return User::model()->find('AID=:aID', array('aID' => $aID)) === null;
}
You can also extend User with a findOrCreate method that returns either an existing instance or creates a new one on the spot:
public function findOrCreate($aID) {
$existing = User::model()->find('AID=:aID', array('aID' => $aID));
if (!$existing) {
User::model()->insert(array('aID' => $aID));
}
return $existing ?: User::model()->find('AID=:aID', array('aID' => $aID));
}
You can do like that to avoid returning invalid index for non object
$result = User::model()->find('AID=:aID', array('aID' => $aID));
return ($result)?$result[0]:NULL;

Categories