why i am getting this error trying to get property of non-object? - codeigniter-2

i am trying to update this and shows Trying to get property of non-object .how to solve this can anybody help me
$data['dotdprod'] = $this->Product_model->get_products($data['dotdcat']->id, '5', '0', 'sort_price', 'ASC');
and model is:
function get_products($category_id = false, $limit = false, $offset = false, $by=false, $sort=false)
{
//if we are provided a category_id, then get products according to category
if ($category_id)
{
$this->db->select('category_products.*, products.*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price', false)->from('category_products')->join('products', 'category_products.product_id=products.id')->where(array('category_id'=>$category_id, 'enabled'=>1));
$this->db->order_by($by, $sort);
$result = $this->db->limit($limit)->offset($offset)->get()->result();
return $result;
}
else
{
//sort by alphabetically by default
$this->db->order_by('name', 'ASC');
$result = $this->db->get('products');
return $result->result();
}
}

There error is warning you that you are trying to access a property on something that doesn't have properties.
When you try to access $data['dotdcat']->id, this assumes that $data['dotdcat'] is an object. If it isn't, then the error you see is thrown.
I'm not sure where the error is thrown, but anywhere you are using the arrow operator -> - php assumes the left side of that operator is an object.

Related

Codeigniter get_where() function some of conditions are not working

In the get_all_staff(), I would like to get the company's staffs list based on the cnditions i have defined, but for example 'role !='=>'Management Office', is not working , and if I change its place in the code , it would works but the other condition will not work, what I am trying to say is all the syntax are correct, but all the conditions are not working in the same tiem.
public function get_all_staff($company_name)
{
// $query = $this->db->get_where('user_login', array('company_name' => $company_name,'role !='=>'Manager','delete_flag'=>0,'role !='=>'Management Office' , 'role !='=>'Admin'));
$query = $this->db->get_where('user_login', array('company_name' => $company_name,'role !='=>'Management Office','role !='=>'Manager','delete_flag'=>0 ,'role!='=>'Admin'));
return $query->result();
}
try like this.
public function get_all_staff($company_name)
{
$this->db->where('company_name', $company_name);
$this->db->where('role !=', 'Management Office');
$this->db->where('role !=', 'Manage');
$this->db->where('role !=', 'Admin');
$this->db->where('delete_flag', '0');
return $this->db->get('user_login')->result_array();
//if there is only one row then do it
// return $this->db->get('user_login')->row_array();
}

Fetching a cached Eloquent collection of 10 items times out

I'm building a search functionality that returns large collections which are paginated using a LengthAwarePaginator. I'm trying to cache results using a key called $searchFilter_$query_$offsetPages for a single page of returned results (10 items). It goes into the cache just fine. However, it times out when I try to check using Cache::has($key) or fetch using Cache::get($key).
The same problem occurs in the browser as well as in artisan Tinker. Strangely, when I put a random set of 10 items into the cache in Tinker and fetch them back, everything works fine. I'm using Redis as the cache driver.
Here is my controller method:
public function search($filter, $query, $layout, Request $request) {
if($layout == "list-map") {
return view("list-map")->with(['filter' => $filter, 'query' => $query, 'layout' => 'list-map']);
} else {
$offsetPages = $request->input('page', 1) - 1;
$cacheKey = $filter . "_" . $query . "_" . $offsetPages;
if(Cache::has($cacheKey)) {
\Log::info("fetching results from cache");
$data = Cache::get($cacheKey);
$totalCt = $data[0];
$results = $data[1];
} else {
$results = $this->getResults($filter, $query);
$totalCt = $results->count();
$results = $results->slice($offsetPages, $this->resultsPerPage);
\Log::info("caching results");
Cache::put($cacheKey, [$totalCt, $results], 5);
}
$results = new LengthAwarePaginator($results,
$totalCt,
$this->resultsPerPage,
$request->input('page', 1),
['path' => LengthAwarePaginator::resolveCurrentPath()]
);
return view($layout)->with(['filter' => $filter, 'query' => $query, 'layout' => $layout, 'results' => $results]);
}
}
So, the issue was that many of the models in the collection returned from my getResults() method were obtained via relationship queries. When I would dd($results) on the single page of 10 results, I could see that there was a "relations" field on each model. Inside that array were thousands of recursively related models based on the relationship I originally queried. I was unable to find any information about an option to not eager load these related models. Instead I came up with a bit of a hacky workaround to fetch the models directly:
$results = $results->slice($offsetPages, $this->resultsPerPage);
//load models directly so they don't include related models.
$temp = new \Illuminate\Database\Eloquent\Collection;
foreach($results as $result) {
if(get_class($result) == "App\Doctor") {
$result = Doctor::find($result->id);
} else if(get_class($result == "App\Organization")) {
$result = Organization::find($result->id);
}
$temp->push($result);
}
$results = $temp;
\Log::info("caching results");
Cache::put($cacheKey, [$totalCt, $results], 5);
If anyone knows the best practice in this situation, please let me know. Thanks!
Edit:
I've found a better solution instead of the above workaround. If I query my relationships like this: $taxonomy->doctors()->get() rather than $taxonomy->doctors, it does not load in the huge recusive relations.
I dont really see why your code doesn't work. The only potential problems I see are the cache keys, which could contain problematic characters, as well as the way you check for a cached value. As you are using Cache::has($key) before Cache::get($key), you could end up with a race condition where the first call returns true and the latter null because the cached value timed out just between the two calls.
I tried to address both issues in the following snippet:
public function search($filter, $query, $layout, Request $request)
{
if($layout == "list-map") {
return view("list-map")->with(['filter' => $filter, 'query' => $query, 'layout' => 'list-map']);
} else {
$offsetPages = $request->input('page', 1) - 1;
$cacheKey = md5("{$filter}_{$query}_{$offsetPages}");
$duration = 5; // todo: make this configurable or a constant
[$totalCount, $results] = Cache::remember($cacheKey, $duration, function () use ($filter, $query) {
$results = $this->getResults($filter, $query);
$totalCount = $results->count();
$filteredResults = $results->slice($offsetPages, $this->resultsPerPage);
return [$totalCount, $filteredResults];
});
$results = new LengthAwarePaginator($results,
$totalCount,
$this->resultsPerPage,
$request->input('page', 1),
['path' => LengthAwarePaginator::resolveCurrentPath()]
);
return view($layout)->with(compact('filter', 'query', 'layout', 'results'));
}
}
The inbuilt function Cache::remember() doesn't use Cache::has() under the hood. Instead, it will simply call Cache::get(). As this function will return null as default if no cache was hit, the function can easily determine if it has to execute the closure or not.
I also wrapped the $cacheKey in md5(), which gives a consistently valid key.
Looking at the following part of your code
$results = $this->getResults($filter, $query);
$totalCount = $results->count();
$filteredResults = $results->slice($offsetPages, $this->resultsPerPage);
I am quite sure the whole search could be improved (independently of the caching). Because it seems you are loading all results for a specific search into memory, even if you throw away most parts of it. There is certainly a better way to do this.

Laravel ORM relationship returns error when value not present in DB

I have an issue with querying relationships.
I am querying relations between Projects, Companies and Products. However, whenever a Project ID is not present in the database an fatal exception is trown:
Call to a member function companies() on a non-object
public function index($i) {
return $this->returnTop($i, Array(
'projectid' => 5,
'products' => Array(1, 2, 3)
)
);
}
public function returnTop($count = 6, $args = Array()) {
$companies = Project::find($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
}
Now, I know that project id 5 is not present in the DB, and this is likely to be the cause of this error, but I want to return a message instead of the application throwing a fatal error....
Any ideas?
Just check if find() returns null. Something like this:
$project = Project::find($args['projectid']);
if(is_null($project)){
return Response::json(['message' => 'Project not found']);
}
$companies = $project->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
An alternative would be findOrFail which throws a ModelNotFoundException. You could handle the exception globally or catch it inside the controller:
try {
$companies = Project::findOrFail($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e){
return Response::json(['message' => 'Project not found']);
}
You first have to test whether the returned object is actually not null. Blindly assuming a database query succeeds is waiting for sh*t to hit the fan.
public function returnTop($count = 6, $args = Array()) {
$project = Project::find($args['projectid']);
if($project) {
$companies = $project->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
}
else {
return; // .. your error or whatever
}
}
Also the "call to a member function on a non-object" is quite specific, it tells you that a method (member function) could not be called due to the fact that you are trying to call it on a non-object.

Why I am getting error message when using Yii CActiveForm::validate() with array

I have a problem related to CActiveForm::validate(). I have a form and and sending data to database using Ajax, my form contains a multiple selectable drop-down list. In data saving section of controller produced the following error initially
mb_strlen() expects parameter 1 to be string, array given (.../framework/validators/CStringValidator.php:84)
and after updating framework to newer version, that error gone, and got the below validation message instead.
Category Ids is invalid.
If the form is fully filled(I mean all the rules in the model satisfied), it will not produce any such bug or error message.
controller action
public function actionCompany() {
$model = new Company;
if (isset($_POST['Company'])) {
$model->attributes = $_POST['Company'];
$category_ids = "";
if (is_array($_POST['Company']['category_ids']))
$category_ids = implode(',', $_POST['Company']['category_ids']);
$model->category_ids = $category_ids;
if ($model->validate()) {
/*$temp = Company::model()->findByPK($model->id);
if ($temp !== null) {
$model = $temp;
}*/
$model->save();
echo CJSON::encode(array('status' => 'success'));
Yii::app()->end();
} else {
$error = CActiveForm::validate($model);
if ($error != '[]')
echo $error;
}
}
}
Model rules
public function rules()
{
return array(
array('...., category_ids,...', 'required'),
array('..., category_ids, ...', 'length', 'max'=>255),
....
.....
array('...., category_ids,...', 'safe', 'on'=>'search'),
);
}
What is actually I'm missing?
By default, CActiveForm::validate($model) loads the model attributes from $_POST and overrides current attribute values, thus destroying your transformed values. Pass false as the third argument to avoid this.

CodeIgniter Dropdown from query

I am new in codeIgniter and I having a bit of trouble with my database and dropdown menu.
Here is my function to get the information I need...
protected $tbl_name = 'club';
public function get($id = 0, $object = TRUE)
{
// select * from users where id = 0
// check if id is provided
if($id) {
// id provided - retrieve a specific user
$query = $this->db->get_where($this->tbl_name, array('id' => $id));
// check if object type is requested
if($object) {
// object is requested
$data = $query->row();
}
else {
// array is requested
$data = $query->row_array();
}
}
else {
// id not provided - retrieve all users
$query = $this->db->get($this->tbl_name);
// check if object type is requested
if($object) {
// object is requested
$data = $query->result();
}
else {
// array is requested
$data = $query->result_array();
}
}
return $data;
}
Here is where I call it in my controller
$data['clubname'] = $this->club_model->get();
and this is in my view for the dropdown
<tr><td><?php echo form_label('Club Name: ', 'clubname'); ?></td><td><?php echo form_dropdown('clubname', $clubname['name']); ?></td><td><?php echo form_error('clubname'); ?></td></tr>
but I get these errors
A PHP Error was encountered
Severity: Notice
Message: Undefined index: name
Filename: individual/individual_club.php
Line Number: 7
A PHP Error was encountered
Severity: Warning
Message: Invalid argument supplied for foreach()
Filename: helpers/form_helper.php
Line Number: 331
What Am I doing wrong?
The problem lies in your form_dropdown('clubname', $clubname['name']) call. The second parameter is wrong. form_dropdown expects an array. See the documentaiton
From your query's results, you would need to build an array of clubs. Something along the lines of :
// array is requested
$data = array();
foreach ($query->result_array() as $row)
{
$data[$row['club_id']] = $row['club_name'];
}
Replace club_id and club_name with your table's column names for the name and id of the clubs. After that, change your form_dropdown to form_dropdown('clubname', $clubname).
Like this, $clubname is an array of clubs.
Hope this helps!

Resources