zend Pagination without fetching query again for each page - performance

Is it possible to use zend pagination without calling the query every time i request a page from the pager?
When I hit a page number from the pager a request to the zzAction below is done and the query is fetched again. My query is huge and I don't want to fetch the query all over again. Am I missing something in the code.
Code:
Controller:
public function getOnePageOfEntries($array, $page=1) {
$paginator = Zend_Paginator::factory($array);
$paginator->setItemCountPerPage(6);
$paginator->setCurrentPageNumber($page);
return $paginator;
}
public function zzAction() {
...
$tt= $this->yyObject->xx(....);
$paginator = $this -> getOnePageOfEntries($tt, $page);
$this->view->paginator = $paginator;
}
Model:
public function xx(...){
try{
...
$stmt = $this->prepare("CALL sp_yy(...)");
....
$stmt->execute();
$result = $stmt->fetchAll();
if (is_null($result)) {
return null;
}
return $result;
}catch (ErrorsException $obj){
echo $obj;exit;
}//end try
}
View:
<?php
$config = Zend_Registry::get('appsConfig');
?>
<?php if (count($this->paginator)){ ?>
<?php foreach($this->paginator as $cc){ ?>
<?php echo $cc['id'] . '/';?>
<?php } ?>
<?php } ?>
<?php echo $this->paginationControl($this->paginator,
'Sliding','ff/my_pagination_control.phtml'); ?>

using Zend_Paginator_Adapater_DbSelect();
example:
$adapter = new Zend_Paginator_Adapter_DbSelect($data); //$data is database query
$pagination = new Zend_Paginator($adapter);
See more here:
Zend_Paginator_Adapter_DbSelect

Your current code artificially limits the utility of the array adapter and forces you to execute the whole query for every page. What you need to accomplish in your controller actions that consume this paginator is to only execute the query if the data doesn't already exist. Maybe something similar to:
//consider this to psuedocode as it has not been tested a represents an idea
public function zzAction()
{
//get page number
$page = $this->getRequest()->getParam('page');
//set session namespace, probably better to do this in init() method or bootstrap
$session = new Zend_Session_Namespace('paged')
//test for presence of persisted array
if (!isset($session->paginator)) {
//perform query
$arrayToPage = $this->yyObject->xx(....);
//persist result array
$session->paginator = $arrayToPage;
} else {
//retrieve persisted array
$arrayToPage = $session->paginator;
}
$paginator = $this -> getOnePageOfEntries($arrayToPage, $page);
$this->view->paginator = $paginator;
}
Using the DbTableSelect or DbSelect paginator adapter is often far more effiecient as it only queries for the data need to populate a specific page. This is very useful when your user wants to go form page 1 to page 7 ...
Another consideration when using a paginator is custom entity models. This is fairly easy to deal with in ZF:
<?php
class Record_Model_Paginator_Record extends Zend_Paginator_Adapter_DbTableSelect
{
//override getItems to customize the adapter to use a specific mapper to create entities
public function getItems($offset, $itemCountPerPage)
{
$rows = parent::getItems($offset, $itemCountPerPage);
$record = array();
foreach ($rows as $row) {
//initiate mapper
$recordEntity = new Application_Model_Mapper_Record();
//create entity models
$record[] = $recordEntity->createEntity($row);
}
//returns an array of objects, similar to a Zend_Db_Rowset object
return $record;
}
}
I hope this helps.

Related

How to delete quantity and update in database using laravel?

When I am inserting quantity in database, I want to update the quantity in the another table. This is what I have tried so far,
public function insertData(Request $request)
{
$userProduct = new UserProduct();
$localStorageData = $request->input('localStorageData');
$productData = json_decode($localStorageData);
print_r($productData);
foreach ($productData as $value) {
$data_array['qty'] = $value->productQty;
$data_array['fk_p_id'] = $value->productId;
$data_array['fk_user_id'] = $request->fkUserId;
UserProduct::insert($data_array);
}
}
In product table I have "id","p_qty"
without updating it, you can get the total quantity by doing sum operation for the main object
$localStorageData = $request->input('localStorageData');
$productData = json_decode($localStorageData);
$userProduct = new UserProduct();
$userProduct->p_qty = collect($productData)->sum('productQty')
You can use two methods to accomplish this in Laravel, using model on created and observers:
<?php
namespace App\Observers;
use App\Models\Transaction;
use Illuminate\Support\Str;
class UserProductObserver
{
public function created(UserProduct $userProduct)
{
$product = $userProduct->product;
$product->p_qty= $product->p_qty+ $userProduct->qty
$product->save();
}
}

Running same query in 2 different views: What's the proper way?

Just getting started into laravel and need to run the same db query for 2 different views, I know I could just create 2 controllers and perform the same query in both passing it to each view.
But, is that the proper way? Or is there a way without repeating my code?
Thanks!
Edit:
I have the following function inside a controller:
protected function getLocation($url)
{
$match = ['url' => $url];
$location = DB::table('location')->where($match)->first();
if (!$location) {
abort(404);
}
return $location;
}
the controller is returning that data to a view:
public function showsubcatandlocation($service)
{
$category = $this->getCat($service);
$location = $this->getLocation($category);
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);
}
What's the proper way to reuse the getLocation function? Or should I just copy it in the new controller? I just need to use it in those 2 views.
maybe scope Query helps?
class Location extends Model
{
public function scopeMatch($query, $url)
{
return $query->where('url', $url);
}
}
And then your two controllel methods will be
$location = Task::match($url)->first();
if (!$location) {
abort(404);
}
return $location;
$category = $this->getCat($service);
$location = Task::match($category['url'])->first();
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);

accessing data linked by foreign key in site view of custom component

In my custom component, in site view, I have a list of countries (view: countries). Clicking on a country, another view is displayed (view: persons) showing all persons living in that country.
Now, in persons view, I want to display the country's name and flag.
So I want to add a function getCountry() in ...site/models/persons.php:
public function getCountry() {
$db = $this->getDBO();
$id = $this->state->get("filter.country");
$sql = "SELECT * FROM #__cnlp_persons_country WHERE id = $id";
$db->setQuery($sql);
$country = $db->loadResult();
// var_dump($country);
return $country;
}
Then, I added to .../site/views/persons/view.html.php:
class Cnlp_personsViewPersons extends JView
{
protected $items;
protected $state;
protected $params;
protected $country; // <--- I added this
...
public function display($tpl = null)
{
$app = JFactory::getApplication();
$this->state = $this->get('State');
$this->items = $this->get('Items');
$this->params = $app->getParams('com_cnlp_trainers');
$this->country = $this->get('Country'); // <--- I added this
(...)
Result: I thought I could then in ---/site/views/persons/tmpl/default.php something like...
<h1><?php echo $this->country->name; ?></h1>
<img src="<?php echo $this->country->flag; ?>" />
...but I get no output...
What did I do wrong?
$db->loadResult(); is used to load a single value results (for example if you would only want to select the country name or something like this), but in your query you're selecting an entire row, so you should use one of theese:
$db->loadRow(); // returns an indexed array from a single record in the table
$db->loadAssoc(); // returns an associated array from a single record in the table
$db->loadObject(); // returns a PHP object from a single record in the table:
You can read more about this here (it's joomla 1.5 documentation, but it's same for 2.5 and 3)

CodeIgniter: How to pass variables to a model while loading

In CI, I have a model...
<?php
class User_crud extends CI_Model {
var $base_url;
var $category;
var $brand;
var $filter;
var $limit;
var $page_number;
public function __construct($category, $brand, $filter, $limit, $page_number) {
$this->base_url = base_url();
$this->category = $category;
$this->brand = $brand;
$this->filter = $filter;
$this->limit = $limit;
$this->page_number = $page_number;
}
public function get_categories() {
// output
$output = "";
// query
$this->db->select("name");
$this->db->from("categories");
$query = $this->db->get();
// zero
if ($query->num_rows() < 1) {
$output .= "No results found";
return $output;
}
// result
$output .= "<li><a class=\"name\">Categories</a></li>\n";
foreach ($query->result_array as $row) {
$output = "<li>{$row['name']}</li>\n";
}
return $output;
}
while I am calling this in my controller...
<?php
class Pages extends CI_Controller {
// home page
public function home() {
}
// products page
public function products($category = "cell phones", $brand = "all", $filter = "latest") {
// loading
$this->load->model("user_crud");
//
}
Now, How can I pass the $category, $brand and $filter variables to the user_crud model while loading/instantiation?
You shouldn't be using your model like this, just pass the items you need for the functions you require:
$this->load->model("user_crud");
$data['categories'] = $this->user_crud->get_categories($id, $category, $etc);
I would suggest (after seeing your code) that you study the fantastic codeigniter userguide as it has really good examples, and you just went a totally different way (treating model like an object). Its more simple sticking to how it was designed vs what you are doing.
You can not. A better idea would be to setup some setters in your model class along with some private vars and set them after loading the model.
if you return $this from the setters you can even chain them together like $this->your_model->set_var1('test')->set_var2('test2');

Codeigniter num_row returns "array" instead of number

Alright, Im trying to count all the rows where "Membership_Status" = Active. The result I get right now is "Array" instead of a number.
Here is my model
class Report_model extends Model
{
function count_members()
{
$query = $this->db->get_where('Membership', array('Membership_Status' => 'Active'));
return $query->num_rows();
}
}
Here is my controller
class Report extends Controller {
function YTD_report()
{
$data['main_content'] = 'report_membership_view';
$this->load->view('includes/template', $data);
}
}
Here is my view
report_model->count_members();
echo $total;
?>
My result is Array, where according to the db info, it should be 4.
What can I do/change to get it to display the proper number?
thanks
the $data array your passing to the view will create one variable for each key to be used by view...
So your controler once the model is loaded, you should do:
$data['total'] = $this->Report_model->count_members();
Then in the view you can use the $total variable like this:
<?php echo $total; ?>

Resources