In my application there is a dataTable , so there is the search mechanism , and one of the columns in the dataTable has an int datatype. Here is how I made the server-side search :
private function _get_datatables_query()
{
$this->db->from($this->table);
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['sSearch']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item.'::varchar', $_POST['sSearch']);
}
else
{
$this->db->or_like($item.'::varchar', $_POST['sSearch']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['iSortCol_0'])) // here order processing
$this->db->order_by($this->column_order[$_POST['iSortCol_0']], $_POST['sSortDir_0']);
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
At runtime I got error because the cast is written like this : "some_column::varchar" like '%search_data%' ; it should be like this : "some_column"::varchar like '%search_data%'
So how to cast the column when calling $this->db->like ?
I found a trick by making a to_char when the column is the concerned one :
foreach ($this->column_search as $item) // loop column
{
if($_POST['sSearch']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
if ($item == 'ladate')
$item = "ltrim(to_char(ladate,'99999999'))";
$this->db->like($item, $_POST['sSearch']);
}
else
{
if ($item == 'ladate')
$item = "ltrim(to_char(ladate,'99999999'))";
$this->db->or_like($item, $_POST['sSearch']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
Related
Hello I want to access an specific array item based in a condition previously checked. I leave the code here:
elsif (scalar(#{$boss->bosses}) > 1) {
foreach my $pa (#{$boss->bosses}) {
my $p = My::Model::Group->new(id => $pa->group_id);
push(#$groups, $p);
$valid_pass = 1 if ($pa->checkPassword($self->param('password')));
}
if ($valid_pass) {
my $pa_id = $pa->id;
my $pa_partner_id = $pa->group_id;
}
else {
}
}
What I want to do is, if that if in the array that comes, I check if the password is correct, so if it's correct, then I want to take the id and the group_id of the array item to use it in a function to be able to log them in.
Your for loop is doing two things at once: producing a list of My::Model::Group objects in #$groups, and finding the first boss whose password checks out.
I suggest that you split them up into two clear operations, and the List::Util modules first operator is ideal for the second task
Here's how it would look. I've extracted the result of the method call $boss->bosses into a variable $bosses to avoid repeated calls to the method
Note that you don't need to apply scalar to an array when checking its size. The > and all the other comparators impose scalar context anyway
I've taken much of my code from your question, and I'm a little concerned that you extract values for $pa_id and $pa_partner_id and then just discard them. But I imagine that you know what you really want to do here
use List::Util 'first';
my $bosses = $boss->bosses;
if ( ... ) {
...;
}
elsif ( #$bosses > 1 ) {
#$groups = map { My::Model::Group->new( id => $_->group_id ) } #$bosses;
my $password = $self->param( 'password' );
my $pa = first { $_->checkPassword( $password ) } #$bosses;
if ( $pa ) {
my $pa_id = $pa->id;
my $pa_partner_id = $pa->group_id;
}
else {
...;
}
}
I'm working on a project for golfstatistics. Right now I made it so far to enter and edit golfstatistics. I'm working with laravel 5 btw.
My database schema works like this:
Every round you play saves one entry in the round table with information like (date, playid, weather, courseid)
for every hole played an entry in the score table is made. There I have a reference to the roundid and information like (score, fairwayhit, greenhit, putts, penalties, ....)
No I want to create reports where I can filter for date and course etc.
What I did for now is. I created a Statistic class where I can pass the date, playerid, roundid, courseid in the construct. The construct will query all the rounds played, matching those filters.
Then, foreach statistic I made a public function ex. scoring_average, greenhit_percantage, putts_per_round, putts_per_greeninregulation etc. there are about 15 stats.
So my question is: is that right what I'm doing here? because I have about 15 functions just to calculate statistics.
Please give me some advice if you have a better solution.
Thank you
class Statistic {
/**
* The table associated with the model.
*
* #var string
*/
public $rounds = [];
public function __construct($user_id, $roundid = null, $start = "2000-01-01", $end = "2030-01-01", $courseid = 0){
$this->rounds = Round::where('user_id', '=', $user_id)->get();
}
public function score(){
if(count($this->rounds) > 0){
$avg = 0;
foreach($this->rounds as $round){
$scores = Score::where('round_id', '=', $round->id)->get(['score']);
foreach($scores as $score){
$avg += $score->score;
}
}
return $avg / count($this->rounds);
} else {
return "N/A";
}
}
public function fir(){
if(count($this->rounds) > 0){
$fairway = [];
foreach($this->rounds as $round){
$scores = Score::where('round_id', '=', $round->id)->get(['fir']);
foreach($scores as $score){
if($score->fir != 0){
array_push($fairway, $score->fir);
}
}
}
$hits = array_count_values($fairway);
//unset($hits[0]); //unsets par 3 with value 0
return self::percArray($hits);
return $perc;
} else {
return "N/A";
}
}
Given a certain sequence A stored in an array, I have to find if a larger sequence B contains sequence A.
I am stuck at the index part... and i'm getting an error that argument "TGACCA" isn't numeric in array element in line 69 which is:
if (index($record_r1[1], $r2_seq[$check]) != -1)
The code is:
foreach my $check (#r2_seq)
{
if (index($record_r1[1], $r2_seq[$check]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}
foreach my $check (#r2_seq)
$check takes on the value of each element in #r2_seq. It is not the index.
$r2_seq[$check]
This is attempting to use an element of #r2_seq as the index into #r2_seq. It is unlikely what you want. More probably, you want to use
$check
as in
if (index($record_r1[1], $check) != -1)
.
I believe you wanted $check to be index, so then use the following code:
foreach my $index (0..$#r2_seq)
{
if (index($record_r1[1], $r2_seq[$index]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}
I am working with Zend and I needed to check whether a row in the DB already exists (A simple solution to get rid of the duplicate key error I was getting). I tried several things but nothing seemed to work... (for example the Zend_Validate_Db_NoRecordExists method)
So I wrote the following the code and I was wondering if this is a valid way to do it, or if I should do things differently:
In the model:
$where = $condition = array(
'user_id = ' . $user_id,
'page_id = ' . $page_id
);
$check = $this->fetchRow($where);
if(count($check) > 0) {
return null;
}else{
// Here I create a new row, fill it with data, save and return it.
}
And then in my view:
if($this->result != null) { /* do stuff */ }else{ /* do other stuff */ }
It does work but it does seem to take more time (duh, because of the extra query) and I am a bit unsure whether I should stick with this..
Any recommendation is welcome :)
Assuming you have coded your function in your controller
$row = $this->fetchRow($where); //If no row is found then $row is null .
if(!$row)
{
$row = $dbTb->createNew($insert); //$insert an associative array where it keys map cols of table
$row->save();
$this->view->row_not_found = true;
}
return $row;
In your view you can do this
if($this->row_not_found)
{
}else {
}
In Zend Form, if two elements have the same order, then Zend will totally ignores the second element (instead of displaying it under the first). Take the following code as an example. Notice that the City and Zip Code elements have the same order of 4
$address = new Zend_Form_Element_Textarea('address');
$address->setLabel('Address')
->setAttrib('cols', 20)
->setAttrib('rows', 2)
->setOrder(3)
;
$city = new Zend_Form_Element_Text('city');
$city->setLabel('City')
->setOrder(4)
;
$postal = new Zend_Form_Element_Text('postal');
$postal->setLabel('Zip Code')
->setOrder(4);
When this form renders, the Zip Code element is nowhere to be found.
If I want to set elements like a buttons dynamically, but tell it to render at the end of the form, how would I do this and not run into the problem of having two elements with the same order?
public function addSubmitButton($label = "Submit", $order = null)
{
$form_name = $this->getName();
// Convert Label to a lowercase no spaces handle
$handle = strtolower(str_replace(" ","_",$label));
$submit = new Zend_Form_Element_Submit($handle);
$submit->setLabel($label)
->setAttrib('id', $form_name . "_" . $handle)
;
///////// Set the button order to be at the end of the form /////////
$submit->setOrder(??????);
$this->addElement($submit);
}
If you really need to use the setOrder() method, I'd work with order numbers 10, 20, 30, 40, ... This way it will be easy to add elements in between already set Elements.
Furthermore, in order to avoid using order-numbers twice, you could use an array, where you store all the numbers from 1 to X. Whenever you set an order number, you set it via a method called getOrderNumberFromArray() which returns the next higher or lower order number still available in the array and unsets this array element.
Alternatively, and maybe even better, you could do getOrder() on the element you want to have before the new element, then increment this order number by X and then loop through the existing form elements and check that the order number doesn't exist yet.
Or you could just use getOrder() on the Element you want to show before and after the new element and make sure you don't use the same order numbers for the new element.
Sorry to be late to the question. What I did was extend Zend_Form and override the _sort() method as follows:
/**
* Sort items according to their order
*
* #return void
*/
protected function _sort()
{
if ($this->_orderUpdated) {
$items = array();
$index = 0;
foreach ($this->_order as $key => $order) {
if (null === $order) {
if (null === ($order = $this->{$key}->getOrder())) {
while (array_search($index, $this->_order, true)) {
++$index;
}
$items[$index][]= $key;
++$index;
} else {
$items[$order][]= $key;
}
} else {
$items[$order][]= $key;
}
}
ksort($items);
$index = 0;
foreach($items as $i=>$item){
foreach($item as $subItem){
$newItems[$index++]=$subItem;
}
}
$items = array_flip($newItems);
asort($items);
$this->_order = $items;
$this->_orderUpdated = false;
}
}
This differs from the original sort method by putting the items in an array based off of their index and then doing a depth-first traversal to flatten the array.
Try this code:
$elements = array();
$elements[] = new Zend_Form_Element_Textarea('address');
......
$elements[] = new Zend_Form_Element_Text('city');
.......
$elements[] = new Zend_Form_Element_Submit($handle);
.....
$this->addElements($elements);
All you need to do is add them in the order you want them to show
what i would do is - use a temp array for that - in that keep the element names in desired order (don't mind the keys). Then use foreach like this:
foreach(array_values($tempArray) as $order => $name) {
$form->$name->setOrder($order+1);
}
Note the array_values - it will return the values as numbered array ;) Not sure if setOrder(0) works - that's why there is +1