Ordering in find() - find

I have a model Org.
In a model Org I have $hasAndBelongsToMany = array('Patient','Project','Category');
In orgs controller action view I get data from database with
$this->set('org', $this->Org->find('first',array('condition'=> array('id'=>$id))));
Result is ok but I want change the order.
I want order result Patient by name, Project by name and Category by id.
How use ORDER BY for Patient,Project,Category in find() ?

Assuming this is Cake, the ordering of associated models should be done in the model when you declare the HABTM relationship:
<?php
class Org extends AppModel {
var $hasAndBelongsToMany = array(
'Patient' => array(
'order' => array(
'Patient.name ASC'
)
),
'Project' => array(
'order' => array(
'Project.name ASC'
)
),
'Category' => array(
'order' => array(
'Category.id ASC'
)
)
);
}
?>
If you're wanting to sort the actual result set by the associated models you can pass an order array to the find method:
<?php
$org = $this->Org->find('all', array(
'conditions' => array(
'Org.column_name' => $yourVar
),
'order' => array(
'Patient.name ASC',
'Project.name ASC',
'Category.id ASC'
)
));
?>
If you're doing a find first by a unique field (like an ID) you can use the built in findByFIELDNAME helper:
<?php
$org = $this->Org->findById($id);
$this->set(compact(array('org')));

Related

Handle Request: ChoicesType

So I have this ChoiceType Form that will sort the items:
$sort = $this->createForm(ChoiceType::class, NULL, array(
'choices' => array(
'...' => 'default',
'A-Z' => 'title_up',
'Z-A' => 'title_down',
'Price low to high' => 'price_up',
'Price high to low' => 'price_down',
),
));
I want to use the Choices so that when one of them is selected from the dropdown menu will do this: $products = "SELECT a FROM AppBundle:Product a ORDER BY a.title ASC".
I tried this:
$sort->handleRequest($request);
if($sort->isSubmitted() && $sort->isValid()) {
if (isset($default)) {
$products = "SELECT a FROM AppBundle:Product a ORDER BY a.title ASC";
return $this->render('AppBundle:main:index.html.twig', array('products' => $products, ));
}
}
But $default is not working, since is not defined. I dont know how to access the choices, so I can pass them to an if statement.
I think you need to write something like this:
$sort = $this->createFormBuilder()
->setAction($this->generateUrl('your_process_route_here'))
->setMethod('POST')
->add('select', ChoiceType::class, [
'placeholder' => 'Please select',
'choices' => [
'...' => 'default',
'A-Z' => 'title_up',
'Z-A' => 'title_down',
'Price low to high' => 'price_up',
'Price high to low' => 'price_down',
]
])
To get the value inside the <select> element:
$select = $request->request->get('select'); // this will contain whatever value you've selected from the dropdown
Check if the value is what you expect, and then create the query:
if ('default' == $select){ // or you can use a switch
// create a custom method inside your Repository class containing the SELECT, and call it here
}
That select from ->add('select', ...) will be the name attribute for your <select> html element.

Zend framework 2 form element normalization

I am migrating an application from Zend 1 to Zend 2 and starting to desperate with one issue. The application works with different locales and therefore, I need to store the data in a normalized way in the database. In Zend 1 I used this code:
public function normalizeNumber( $value )
{
// get the locale to change the date format
$this->_locale = Zend_Registry::get('Zend_Locale' );
return Zend_Locale_Format::getNumber($value, array('precision' => 2, 'locale' => $this->_locale));
}
Unfortunately Zend 2 does not has this Zend_Locale_Format::getNumber any more and I was not able to figure out what function did replace it. I have tried with NumberFormat, but I get only localized data not normalized. I need this function to normalize data I receive from a form via POST. Can someone give some advice?
thanks
Just to complete my question. The Form element definition I am using is the following:
namespace Profile\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class Profile Extends Form implements InputFilterProviderInterface
{
protected $model;
public function __construct( $model, $name = 'assignmentprofile')
{
parent::__construct( $name );
$this->setAttribute( 'method', 'post');
$this->model = $model;
...
$this->add( array(
'name' =>'CommutingRate',
'type' =>'Zend\Form\Element\Text',
'options' => array( // list of options to add to the element
'label' => 'Commuting rate to be charged:',
'pattern' => '/[0-9.,]/',
),
'attributes' => array( // Attributes to be passed to the HTML lement
'type' =>'text',
'required' => 'required',
'placeholder' => '',
),
));
}
public function getInputFilterSpecification()
{
return array(
...
'CommutingRate' => array(
'required' => true,
'filters' => array(
array( 'name' => 'StripTags', ),
array( 'name' => 'StringTrim'),
array( 'name' => 'NumberFormat', 'options' => array('locale' => 'en_US', 'style' => 'NumberFormatter::DECIMAL', 'type' => 'NumberFormatter::TYPE_DOUBLE',
))
),
'validators' => array(
array( 'name' => 'Float',
'options' => array( 'messages' => array('notFloat' => 'A valid numeric entry is required')),
),
),),
...
);
}
}
As mentioned before, I am able to localized the data and validate it in the localized manner, but i am failing to convert it back to a normalized manner...

ZF2 Form: NumberFormat-filter with localization

hy,
how can I define the NumberFormat-filter for an input in a fieldset which is aware of the current locale? What I want is that numbers like 1000.33 are displayed in the view like this: 1.000,33 (or whatever locale is specified) I have tried it with the InputFilterProviderInterface, but it doesn't has any effect in the view:
<?php
namespace Customer\Form;
use Customer\Entity\OfferDay;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class OfferDayFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct($em)
{
parent::__construct('offerDayFieldset');
$this->setHydrator(new DoctrineHydrator($em))
->setObject(new OfferDay());
$this->add(array(
'name' => 'price',
'type' => 'Text',
'options' => array(
'label' => '',
),
));
}
public function getInputFilterSpecification()
{
return array(
'price' => array(
'required' => false,
'filters' => array(
array(
'name' => 'NumberFormat',
'options' => array(
'locale' => 'de_DE',
),
),
),
),
);
}
}
In the view I output the input via the formRow()-function.
I also know that you can use the NumberFormat-Filter programmatically like this (l18n Filters - Zend Framework 2):
$filter = new \Zend\I18n\Filter\NumberFormat("de_DE");
echo $filter->filter(1234567.8912346);
// Returns "1.234.567,891"
but I wanna use the array-notation.
Has anybody done something like this or something similar?
ok this seems not as trivial as I thought :) but I got a solution.
first define the filter like this:
public function getInputFilterSpecification()
{
return array(
'price' => array(
'required' => false,
'filters' => array(
array(
'name' => 'NumberFormat',
'options' => array(
'locale' => 'de_DE',
'style' => NumberFormatter::DECIMAL,
'type' => NumberFormatter::TYPE_DOUBLE,
),
),
),
),
);
}
whereas locale is the currently used locale. This formats the numbers into the currect format before saving it to the database.
In the view, you can use the filter view helper to convert the numbers to the right format:
<?php
$this->plugin("numberformat")
->setFormatStyle(NumberFormatter::DECIMAL)
->setFormatType(NumberFormatter::TYPE_DOUBLE)
->setLocale("de_DE");
?>
<p>
<?php
$currentElement = $form->get('price');
$currentElement->setValue($this->numberFormat($currentElement->getValue()));
echo $this->formRow($currentElement);
?>
</p>
Result:
Database: 12.345 ->
View: 12,345 -> Database: 12.345

CodeIgniter autoloading form validation rules set not working with parameters

Following CI user_guide, I have created a configuration file named "form_validation.php" with in it the following sets:
$config = array(
'user/create' => array(
array(
'field' => 'id',
'label' => '',
'rules' => ''
),
array(
'field' => 'first_name',
'label' => 'lang:First name',
'rules' => 'required|max_length[30]'
),...
),
'user/update' => array(
array(
'field' => 'id',
'label' => '',
'rules' => ''
),
array(
'field' => 'first_name',
'label' => 'lang:First name',
'rules' => 'required|max_length[30]'
),...
)
);
In my 'user' controller, when I call the 'create' method, hence with the URL http://localhost/my_ci_application/user/create, the statement $this->form_validation->run() automatically runs the first set of rules defined in my configuration file. This is the expected behaviour from what I read in the user guide.
But when I run the following URL http://localhost/my_ci_application/user/update/1 to update the user whose ID is 1, it does not automatically load the 'user/update' rules set. It seems like because of the parameter, CI expects to find a 'user/update/1' rules set, which of course I cannot create because the ID of my users will vary all the time when calling this method.
Am I understanding this right? If yes, then that's a pity as I thought standard CI URL were formed like: controller/method/parameters... so I would expect the form validation class to only consider the first two URI segments?!
FYI, if I write in my user.update method the following, my validation rules work fine:
$this->form_validation->run('user/update')
So my question is really if I understood the autoloading of rules properly or not, and if there is anything we can do to autoload those rules even with methods having some parameters.
thank you very much in advance.
In your form_validation.php file:
$CI =& get_instance();
$config = array(
'user/update/' . $CI->uri->segment(3) => array(
....
)
);
if i understant this question u will need call validation, for example:
$this->lang->load('form_validation', 'portuguese'); //if u have order language
if($this->form_validation->run('user/update') == FALSE)
{
//msg error
}
else{
//save
}
To get the value for the url dowel u need:
$this->uri->segment(3);
i hope this has helped
You can extend the library to achieve this
application/libraries/MY_Form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
function run($group = '')
{
if($group == '')
{
$group = '/' . implode('/', array_slice($this->CI->uri->rsegment_array(), 0, 2));
}
return parent::run($group);
}
}

Can't save retrieved from database drop down values in zend framework 2

First of all, excuse me for my poor english.
I have read a lot about populating a drop down with values from a database in zend framework 2, the 2 links that help me a lot are these:
http://framework.zend.com/manual/2.2/en/modules/zend.form.collections.html
http://zf2.readthedocs.org/en/release-2.1.4/modules/zend.form.advanced-use-of-forms.html
This is what i did
I create a form, and add a field of type "categoryFieldset"
class ProductForm extends Form
{
public function init()
{
// we want to ignore the name passed
parent::__construct('product');
$this->setName('product');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array(
'name' => 'name',
'type' => 'Text',
'options' => array(
'label' => 'Name',
),
));
$this->add(array(
'name' => 'category',
'type' => 'CategoryFieldSet',
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Add',
'id' => 'submitbutton',
),
));
}
}
i create a class named categoryFieldset that extends from fieldset where I added a select field:
class CategoryFieldset extends Fieldset
{
function _construct(CategoryTable $categoryTable)
{
parent::_construct('category_fieldset');
$this->setHydrator(new ClassMethodsHydrator(false))->setObject(new Category());
$categorySelectOptionsArray = $categoryTable->populateSelectCategory();
$this->add(array(
'name' => 'categoryField',
'type' => 'Select',
'options' => array(
'label' => 'Category',
'value_options' => $categorySelectOptionsArray,
),
));
}
}
Add code to my module file:
public function getFormElementConfig()
{
return array(
'factories' => array(
'CategoryFieldSet' => function($sm) {
$serviceLocator = $sm->getServiceLocator();
$categoryTable = $serviceLocator->get('Administrador\Model\CategoryTable');
$fieldset = new CategoryFieldset($categoryTable);
return $fieldset;
},
)
);
}
My view has this:
$form = $this->form;
$form->setAttribute('action', $this->url('product', array('action' => 'add')));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('name'));
echo "";
$category_fieldset = $form->get('category');
echo $this->formRow($category_fieldset->get('categoryField'));
echo "";
echo $this->formSubmit($form->get('submit'));
echo "";
echo $this->form()->closeTag();
Right now everything is fine, the select elements are showing the values from database, but my problem is when i try to add the data to the database, the field where is the dropdown of categories is saved with the value "0" instead of the id value of the category. I think the problem is the way the view is rendering the select field, when i checked the HTML code i notice that the name of the select field is "category[categoryField]" and it should be "category".
This is the HTML code:
<span>Category</span>
<select name="category[categoryField]">
<option value="1">Category 1</option>
<option value="2">Category 2</option>
<option value="3">Category 3</option>
<option value="4">Category 4</option>
<option value="5">Category 5</option>
</select>
I printed the $request->getPost() array in the viw and this is what it shows:
Zend\Stdlib\Parameters Object ( [storage:ArrayObject:private] => Array ( [id] => [name] => Product1 [category] => Array ( [categoryField] => 2 ) [submit] => Add ) )
What do i need to do to make the field name shows like "category" or to be able to save that record to the database?