Issues with sfDoctrinePager pagination - symfony1

I am using sfDoctrinePager in my module. I search the table on one or more criteria. First time the result displayed is correct but after it if I click on page 2 or more it again gives me the whole resultset and my search resultset is lost.
I am facing this issue for the first time, even though I have been using sfDoctrinePager since a long time.
I get this Array from my search form
(
[field_type] => log_type
[field_value] => ABC
[is_active] => on
)
I send this array variable to my model:
$getQuery = $objMgr->getSearchQuery($request->getPostParameters());
** The query which runs in model is:
public function getSearchQuery($arrSearchValues)
{
$q = Doctrine_Query::create()
->select('u.*')
->from('SomsConfigValues u');
->where('u.deleted_at IS NULL');
if(isset($arrSearchValues['is_active']) && $arrSearchValues['is_active'] == 'on'){
$q->where('u.is_active = ?', 1);
}
if(isset($arrSearchValues['field_type']) && $arrSearchValues['field_type'] != ""){
$revertChg = ucwords(str_replace("_", " ", $arrSearchValues['field_type']));
$q->andWhere('u.field_type = ?', $revertChg);
}
if(isset($arrSearchValues['field_value']) && $arrSearchValues['field_value'] != ''){
$q->andWhere('u.field_type = ?', $arrSearchValues['field_value']);
}
return $q;
}
First time I get the perfect searched result, but second time (when I click on page 2 it gives me whole resultset).
My action is:
public function executeIndex(sfWebRequest $request)
{
$objMgr = AdminFactory::adminObject();
$getQuerys = $objMgr->getSearchQuery($request->getPostParameters());
$this->config_values = $getQuerys;
$this->pager = new sfDoctrinePager('configValues', sfConfig::get('app_max_row_display'));
$this->pager->setQuery($this->config_values);
$this->pager->setPage($request->getParameter('page', 1));
$this->pager->init();
}
The template where I am using this pagination is:
<div class="grid_footer">
<div style="padding:5px;">
<?php if(count($pager->getLinks())) : ?>
<div class="tableControl">
<div class="pagination_inner">
<?php if(!$pager->isFirstPage()){ ?>
<?php echo link_to1(image_tag('/images/first.png'), 'configValues/index?page='.$pager->getFirstPage()) ?>
<?php echo link_to1(image_tag('/images/previous.png'), 'configValues/index?page='.$pager->getPreviousPage()) ?>
<?php } ?>
<div class="numbers">
<?php if ($pager->haveToPaginate()): ?>
<?php $links = $pager->getLinks(); foreach ($links as $page): ?>
<?php echo ($page == $pager->getPage()) ? $page : link_to($page, 'configValues/index?page='.$page) ?>
<?php endforeach ?>
<?php endif ?>
</div>
<?php if(!$pager->isLastPage()){ ?>
<?php echo link_to1(image_tag('/images/next.png'), 'configValues/index?page='.$pager->getNextPage()) ?>
<?php echo link_to1(image_tag('/images/last.png'), 'configValues/index?page='.$pager->getLastPage()) ?>
<?php } ?>
</div>
</div>
<?php echo $pager->getNbResults() ?> results (page <?php echo $pager->getPage(); ?>/<?php echo count($pager->getLinks()); ?>)
<?php endif; ?>
</div>
</div>

I was having exactly the same problem. The only way around this I found is as you said, to store the query. Instead of using the session, create an attribute in the user to store this.
in the action class put something like...
$this->getUser()->setAttribute('searchQuery', $getQuery);
This value persists through the session, so you can retreive it using e.g.
$storedQuery = $this->getUser()->getAttribute('searchQuery');
You can view the User attributes via the config item on the dev toolbar.

Related

Cakephp how to create a nested foreach

I am using cakephp 3. I have to create a view for a Group in which in every Subject, there will be Lessons but in my case:
Group hasMany subjects
Subject hasMany lessons
Here is my code in the GroupsController:
public function mygroup()
{
$this->loadModel('Lessons');
$group = $this->Groups->get($this->Auth->user('group_id'), [
'contain' => ['Subjects', 'Users']
]);
$lesson = $this->Lessons->find('all');
$this->set('lesson', $lesson);
$this->set('_serialize', ['lesson']);
$this->set('group', $group);
$this->set('_serialize', ['group']);
}
I have to load lessons model because it is not associated with group, in mygroup.ctp view:
<?php if (!empty($group->subjects)): ?>
<?php foreach ($group->subjects as $subjects): ?>
<?= h($subjects->subject) ?>
<?= h($subjects->id) ?>
<?= h($subjects->created) ?>
<?php foreach ($lesson as $lesson): ?>
<?php if ($subjects->id == $lesson->subject_id): ?>
<?= h($lesson->lesson) ?>
<?= h($lesson->subject_id) ?>
<?= h($lesson->created) ?></div>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif; ?>
I want to view lesson just below of its subject where it belongs. I don't know but the for each loop for the subject is working but the for each loop of lessons it only work for the first subject it displays:
Something like this:
Subject1
Lesson1 for sub1
Lesson2 for sub1
Lesson3 for sub1
Subject2
Subject3
Subject4
Subject5
The lessons are not showing in the subject 2 to 5 yet there should be.
Can u help me with this? Or is there any other way to do it? If there someone. Very much appreciate it. Thank you

opencart add more more brands link in 3rd level category

using this code
$sisters = array_slice($sisters, 0, 5);
in catalog/controller/module/category.php
I'm displaying only 5 sister categories. I'm having a trouble adding a link stating View More which should link their parent category underneath all sister categories having more than 5 entries.
Any suggestion to solve this?
<?php if ($child['children1']) { $j=0; ?>
<?php foreach ($child['children1'] as $child1) { $j++; ?>
<?php if($j>2) { ?><li class="level-2-cat-list-sub-cat">More...</li><?php break; } else { ?>
<li class="level-2-cat-list-sub-cat" id="<?php echo $i; ?>">
<?php echo strtolower(ucwords($child1['name1'])); ?>
</li>
<?php } ?>
<?php } ?>
<?php } ?>
Make the not on above .tpl file there $j was declared and if it was greater than 2 More... was printed with and anchor tag and ended with "break;" statement

sfWidgetFormDoctrineChoice for NestedSet model

I'm experiencing a difficulty in rendering sfWidgetFormDoctrineChoice (set of checkboxes) widget for a NestedSet structure.
class ModelForm extends BaseModelForm
{
public function configure()
{
$this->setWidget('relatedmodel_list', new sfWidgetFormDoctrineChoice(array(
'expanded' => true,
'multiple' => true,
'model' => 'Relatedmodel',
'table_method' => 'fetchTree'
)));
}
}
class RelatedmodelTable extends Doctrine_Table
{
/**
* Gets tree elements in one query (one root only)
*/
public function fetchTree()
{
$q = $this->createQuery('m')
->addOrderBy('m.lft');
$tree = $q->execute(array(), Doctrine_Core::HYDRATE_RECORD_HIERARCHY);
return $tree;
}
}
Now, if I just render form like this: <?php echo $form['relatedmodel_list'] ?>
It will only display form widgets (checkboxes) for first level elements of my hierarchy.
I am looking for an implementation that will allow me to iterate over widget's choices the way I would iterate over collection:
<?php foreach ($form['relatedmodel_list'] as $widget): ?>
<?php echo $widget->render() ?>
<?php foreach ($widget->getChildren() as $child_widget): ?>
<?php echo $child_widget->render() ?>
<?php endforeach; ?>
<?php endforeach; ?>
I'm using sfWidgetFormTree to display my nestedSet. If you really want to display your tree in a flat way don't use HYDRATE_RECORD_HIERARCHY.
The widget linked is very convinient, you just have to provide a choices array like this :
$choices = array(
1=> array('label'=>'test', 'children'=>array(
2=> array('label'=>'test2', 'children'=> array(
3=> array('label'=>'test3'),
4=> array('label'=>'hans')
)),
5=> array('label'=>'wurst')
)),
6=>array('label'=>'letzter')
);
If anyone cares, I think I found a wonderful solution which allows you to recursively iterate over checkboxes in template. The idea behind it is that you configure 'relatedmodel_list' widget as a single checkbox and render it many times in your template (while iterating over relatedmodel collection).
class ModelForm extends BaseBookForm
{
public function configure()
{
$this->setWidget('relatedmodel_list', new myWidgetFormInputCheckbox());
}
}
Checkboxes now have incorrect name and value attributes. This can be fixed very easily:
class myWidgetFormInputCheckbox extends sfWidgetFormInputCheckbox
{
public function render($name, $value = null, $attributes = array(), $errors = array())
{
//fix value checking
if (in_array($attributes['value'], (array)$value))
{
$attributes['checked'] = 'checked';
}
//fix name for multiple
$name = $name . "[]";
return parent::render($name, null, $attributes, $errors);
}
}
Now we can recursively render our form widget in template:
//_form.php
<ul>
// Model::getRelatedTree() is proxy to Relatedmodel::fetchTree()
<?php include_partial('node', array('node' => $form->getObject()->getRelatedTree(), 'form' => $form)) ?>
</ul>
//_node.php
<?php foreach ($node as $item): ?>
<li>
<?php echo $form['pages_list']->render(array('value'=>$item->id)) ?>
<?php echo $form['pages_list']->renderLabel((string)$item) ?>
<?php if (isset($item['__children']) && count($item['__children']) > 0): ?>
<ul>
<?php include_partial('node', array('node' => $item['__children'], 'form' => $form)) ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>

symfony - embedForm and form widgets not saving

I have an embeddedForm that I am trying to configure the widgets for.
Currently I am just outputting the form in a _form.php template like:
<?php echo $form ?>
This is great, but I'd like to have my form fields in a particular order, so I thought I'd try:
<?php echo $form['firstname']->renderRow() ?>
<?php echo $form['lastname']->renderRow() ?>
<?php echo $form['email_address']->renderRow() ?>
This gives me an invalid widget error.
Now I have 2 forms, one is a basic form, that simply embeds another form.
<?php
class labSupportForm extends sfGuardUserAdminForm
{
public function configure()
{
$form = new labSupportProfileForm($this->getObject()->getProfile());
$this->embedForm('profile', $form);
unset($this['is_super_admin'], $this['is_admin'], $this['permissions_list'], $this['groups_list']);
$this->widgetSchema['profile'] = $form->getWidgetSchema();
$this->validatorSchema['profile'] = $form->getValidatorSchema();
}
public function save($con = null)
{
$user = parent::save($con);
if (!$user->hasGroup('Lab Support'))
{
$user->addGroupByName('Lab Support');
$user->save();
}
return $user;
}
}
and:
<?php
class labSupportProfileForm extends sfGuardUserProfileForm
{
public function configure()
{
unset($this['email_new'],
$this['validate_at'],
$this['validate'],
$this['address_1'],
$this['address_2'],
$this['city'],
$this['country'],
$this['postcode'],
$this['created_at'],
$this['updated_at'],
$this['user_id'],
$this['is_super_admin'],
$this['is_admin'],
$this['permissions_list'],
$this['groups_list']);
}
}
But If I add the widget/validator to the labSupportForm and save, the firstname value doesn't save.
Am I doing something wrong here, as I would have thought this value would save.
Thanks
When you render a form by fields, you have to explicitly call $form->renderHiddenFields(). For example:
<?php echo form_tag_for($form, '#url') ?>
<table>
<tfoot>
<tr>
<td colspan="2">
<input type="submit" value="Save" />
<?php echo $form->renderHiddenFields() ?>
</td>
</tr>
</tfoot>
<tbody>
<?php echo $form['username']->renderRow() ?>
<?php echo $form['profile_form']->renderRow() ?>
</tbody>
</table>
</form>
Also, beware calling embedded form name the same as relation name (e.g. 'profile') or you will have troubles when saving it. Just add '_form' suffix and you will be safe:
$this->embedForm('profile_form', $form);
If you want to keep a linear display structure of your form fields, you should render them explicitly according to your widget schema:
<?php echo $form['username']->renderRow() ?>
<?php echo $form['profile_form']['first_name']->renderRow() ?>
<?php echo $form['profile_form']['last_name']->renderRow() ?>
Or you can do it automatically for all fields of an embedded form:
<?php foreach ($form['profile_form'] as $field): ?>
<?php if (!$field->isHidden()): ?>
<?php echo $field->renderRow() ?>
<?php endif; ?>
<?php endforeach; ?>
Call $this->saveEmbeddedForms() in the labSupportForm save method

How to get downloadable product links after successfull order

After a successfull order I would like to propose directly the downloadable URL for products buyer bought in the success.phtml file.
I wrote this piece of code to know product's values of the latest order:
// Get the latest Order ID
$order = Mage::getModel('sales/order')->load(Mage::getSingleton('checkout/session')->getLastOrderId());
// Get every products on the latest order
$items = $order->getAllItems();
// Loop the products
foreach ($items as $item){
$product = Mage::getModel('catalog/product')->setStoreId($order->getStoreId())->load($item->getProductId());
// HERE I NEED FUNCTION TO GET DOWNLOADABLE URL LINK
}
I found a solution, here it is:
First, create a new .phtml file in template/downloadable/ , I called mine downloadablelist.phtml
Then copy all of template/downloadable/customer/products/list.phtml in our new downloadablelist.phtml
This will give us a copy of the customer account my downloadable products list.
Call our block in success page :
<?php echo $this->getLayout()->createBlock('downloadable/customer_products_list')->setTemplate('downloadable/checkout/downloadablelist.phtml')->toHtml(); ?>
Now I cleaned up what I don't need from the product list. I removed the table and added a ul instead.
Next is to show only the products that are made from the last order.
<?php
$_items = $this->getItems();
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
if(count($_items)):
$_group_id = Mage::helper('customer')->getCustomer()->getGroupId();
echo '<p><strong>'.$this->__('Downloadable products').' : </strong></p>'; ?>
<ul style="margin-left: 30px; list-style: disc;">
<?php foreach ($_items as $_item):
$itemOrderId = $_item->getPurchased()->getOrderIncrementId();
if($itemOrderId == $orderId) {?>
<li><?php echo $this->htmlEscape($_item->getPurchased()->getProductName()) ?> - <a href="<?php echo $this->getUrl('downloadable/download/link/', array('id' => $_item->getLinkHash(), '_secure' => true)) ?>" title="<?php echo Mage::helper('downloadable')->__('Start Download') ?>" <?php echo $this->getIsOpenInNewWindow()?'onclick="this.target=\'_blank\'"':''; ?>><?php echo $_item->getLinkTitle() ?></a></li>
<?php }
endforeach; ?>
</ul>
<?php endif; ?>
I changed the url the original downloadable file had to :
href="<?php echo $this->getUrl('downloadable/download/link/', array('id' => $_item->getLinkHash(), '_secure' => true)) ?>"
Thank you
This worked for me:
$links = Mage::getModel('downloadable/link_purchased_item')->getCollection()
->addFieldToFilter('order_item_id', $item->getId());
foreach ($links as $link) {
echo Mage::helper('downloadable')->__('download') .
$this->getUrl('downloadable/download/link',
array('id' => $link->getLinkHash(), '_store' => $order()->getStore(),
'_secure' => true, '_nosid' => true));
}

Resources