Retrive data using cakephp - cakephp

I am new to cakephp and i want to find data that has been created
This is my sql function works
Select Trv_No from Ticket_LO
This is my model in cakephp
$ticket = $this->Ticket->find('first', array('conditions' => array('AND' => array('Ticket.TRV_No' => $trv_no)));
if(empty($ticket))
{
$table_name = 'Ticket_L0';
$this->Ticket->setSource($table_name);
//$ticket = $this->Ticket->find('first', array('conditions' => array('Ticket.TRV_No' => $trv_no)));
$ticket = $this->Ticket->find('first', array('conditions' => array('AND' => array('Ticket.TRV_No' => $trv_no, 'Ticket.HIDDEN_STAT LIKE' =>'0'))));
if(empty($ticket)) { return false; } else { return true; }
}
else
{ return true; }
}

First things first,
You don't need to set $this->Ticket->setSource($table_name); in your model.
You can use $this->find
I'm not sure what do you really want. But, I guess you want something like that.
$ticket = $this->find('first', array(
'conditions' => array(
'Ticket.TRV_No' => $trv_no,
'Ticket.HIDDEN_STAT'=> 0 //if you want to find 0 only, you don't need LIKE. But, if you want some string, you can use something like 'Ticket.HIDDEN_STAT LIKE'=>'yourString%'
)
)
);
And, you can add your condition after that.
if(!empty($ticket)) return true;
else return false;

Related

Codeigniter Insert Array to Database

I have created a form in Codeigniter with a phone number field that dynamically is duplicated using javascript. So basically I can have one or more fields like this.
<input name="phone[]" value=""type="text">
<input name="phone[]" value=""type="text">
Then in my controller I have
$form_data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'phone' => $this->input->post('phone[]')
);
Then I am saving this to my dabase like so
function SaveForm($form_data)
{
$this->db->insert('customers', $form_data);
if ($this->db->affected_rows() == '1')
{
return TRUE;
}
return FALSE;
}
but obviously the code for 'phone' is wrong, I just cant figure out how to properly do this.
you can't save array in to database. You can convert it in to string using implode() and whenever you needed then convert it back in array using explode(). Like below
$phone=implode(',',$this->input->post('phone'));
$form_data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'phone' => $phone
);
OR
You can convert it to json string and when you needed convert back to Array Like below:
$phone = json_encode($this->input->post('phone'));
Convert back to array
$phone = json_decode($phone, TRUE);
Modify your function as below and it will works like charm,
function SaveForm($form_data)
{
foreach ($form_data as $contact)
{
$data[] = array(
'first_name' => $contact['first_name'],
'last_name' => $contact['last_name'],
'phone' => $contact['phone']
);
}
$this->db->insert_batch('customers', $data);
if ($this->db->affected_rows() > 0)
{
return TRUE;
}
return FALSE;
}
Modified:
Oh, yes you have to edit para array that you passed to SaveForm function.
Please use following code, ignore above code:
foreach($_POST['first_name'] as $key=>$fname)
{
$form_data[] = array(
'first_name' => $_POST['first_name'][$key],
'last_name' => $_POST['last_name'][$key],
'phone' => $_POST['phone'][$key],
);
}
function SaveForm($form_data)
{
$this->db->insert_batch('customers', $data);
if ($this->db->affected_rows() > 0)
{
return TRUE;
}
return FALSE;
}
In controller
$phone = $_POST['phone'];//this will store data as array. Check image 02
$form_data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'phone' => $phone,//some times it works with '$phone'
);
In Model
function SaveForm($form_data)
{
$this->db->insert('customers', $form_data);
if ($this->db->affected_rows() == '1')
{
return TRUE;
}
else
{
return FALSE;
}
}
Tested
Image 01 (My form)
Image 02 (After Submitted)
mysql doesn’t has any array data type. So we can not store array directly into mysql database.
To do this we have to first convert array into string using php serialize() function then save it into mysql database.
for eg:php code to store array in database
$array = array("foo", "bar", "hello", "world");
$conn=mysql_connect('localhost', 'mysql_user', 'mysql_password');
mysql_select_db("mysql_db",$conn);
$array_string=mysql_escape_string(serialize($array));
To retrieve array from database
$conn=mysql_connect('localhost', 'mysql_user', 'mysql_password');
mysql_select_db("mysql_db",$conn);
$q=mysql_query("select column from table",$conn);
while($rs=mysql_fetch_assoc($q))
{
$array= unserialize($rs['column']);
print_r($array);
}
for array insertion to database use this programme in codeigniter controller=>
$inputdata=$this->input->post();
$phone=array($inputdata['phone']);
foreach($phone as $arr)
{
$phoneNo=$arr;
$f=count($phoneNo);
for($i=0;$i<$f;$i++)
{
$arre=[
'phone'=>$phoneNo[$i],
];
$insertB= $this->user_model->userdata($arre);
}
}
public function add_theme_pages(){
$page_name = $this->input->post('page');
$page_img = $this->input->post('page_img');
for($i=0; $i < count($page_name); $i++){
$pages_data = array(
'theme_id' => $this->input->post('theme_id'),
'theme_page_name' => $page_name[$i],
'theme_page_img' => $page_img[$i]
);
if($this->backendM->add_theme_pages($pages_data)){
$this->session->set_flashdata('message', 'Theme Added Successfully !');
$this->session->set_flashdata('message_class', 'green');
$this->create_template();
}else{
$this->create_template();
}
}
}

CakePHP saveAll repeated and non-repeated entries

Well,
I created a Model with the following restriction
public $validate = array(
'player_id' => array(
'rule' => array(
'checkUnique',
array(
'player_id',
'game_id'
),
true
),
'required' => true,
'allowEmpty' => false,
'on' => 'create',
'message' => 'Same player_id y game_id'
)
);
So each time I try to create a game record in the table it is created only if it is not created yet.
So I created an action in one controller that get recent games of one player and use saveAll to save into the database.
If the database is empty there is no a single problem, of course. But if I receive some games and some of them are already being inserted previously saveAll fails because SOME of the games are already into the database.
public function getRecentGames($server = null, $player = null){
$this->autoRender = false;
if( !empty($server) && !empty($player) ){
$r = $this->_getRecentGames($server, $player, $gamesData);
if ($r['code'] == 200) {
if ($this->Game->saveAll($gamesData, array('deep' => true))) {
pr($gamesData);
prd('Saved');
} else {
pr($this->Game->invalidFields());
prd('Not saved');
}
} else {
}
}
return print_r($gamesData, true);
}
Basically saveAll(..) calls internally validateMany(..) which returns false because not every entry is valid and saveAll does not try to save. This is the normal behavior of CakePHP and the way developers want it to work.
So, what should I do?
Check each game and try to save it?
foreach ($games as $game) {
$this->Model->saveAssociated(..);
}
Modify the behavior of saveAll(..) in order to save the valid games and not the invalid ones. (Do you think this should be the default behavior of CakePHP?)
Other solutions I didn't think(?). Please show me then
Thank you
Well this is the best approach I could think of:
$validations = $this->Game->validateMany( $gamesData, array('deep' => true, 'atomic' => false) );
for ($i=count($gamesData)-1; $i>=0; $i--) {
if (!$validations[$i]) {
unset($gamesData[$i]);
}
}
if (!empty($gamesData)) {
$result = $this->Game->saveAll($gamesData, array('deep' => true, 'validate' => false));
}

Cakephp Custom Find Type Pagination

I created a custom find type, and am trying to paginate the results, but the paginator seems to be ignoring the findType setting. Can someone tell me what I'm doing wrong?
(CakePHP 2.X)
In my Controller:
public function list($username=null) {
$this->Paginator->settings = array(
'Question' => array(
'findType' => 'unanswered',
'conditions' => array('Question.private' => 0),
);
$data = $this->Paginator->paginate('Question');
$this->set('data', $data);
);
Custom find type setup in my Model:
public $findMethods = array('unanswered' => true);
protected function _findUnanswered($state, $query, $results = array()) {
if ($state == 'before') {
$query['order'] = array('Question.created DESC');
$query['conditions'] = array_merge($query['conditions'], array('Question.date_answered' => ''));
return $query;
$this->log($query);
} elseif ($state == 'after') {
return $results;
}
}
Edit
I can paginate the query if I remove $this->Paginate->settings, and replace it with this:
$this->paginate = array('unanswered');
However, I want to add some additional conditions., this doesn't work:
$this->paginate = array('unanswered' => 'conditions' => array('Question.user_id' => $id, 'limit' => 4)) );
Is this possible?
findType was added to the paginator component in CakePHP 2.3, I was on 2.0
http://api.cakephp.org/2.3/class-PaginatorComponent.html

custom datasource find('list') issue

I am creating a custom datasource and I am having problems when i request find('list'). find('all') returns perfectly what I want within my controller but find('list') just returns an empty array.
The funny thing is if I do a die(Debug($results)) in the datasource within the read function then I get my find('list') array correctly but if I return it i then get an empty array in my controller. Any ideas?
Code below:
public function read(Model $model, $queryData = array(), $recursive = null) {
if ($queryData['fields'] == 'COUNT') {
return array(array(array('count' => 1)));
}
$this->modelAlias = $model->alias;
$this->suffix = str_replace('Flexipay', '', $model->alias);
if(empty($model->id)){
$this->url = sprintf('%s%s%s', $this->sourceUrl, 'getAll', Inflector::pluralize($this->suffix));
}
$r = $this->Http->get($this->url, $this->config);
if($r->isOk()){
$results_src = json_decode($r->body, true);
if(is_array($results_src)){
//$this->find('list');
if($model->findQueryType == 'list'){
return $this->findList($queryData, $recursive, $results_src);
}
//$this->find('all');
foreach($results_src['PortalMandantenResponses']['portalMandantenResponses'] as $r){
$results[] = $r;
}
if(!empty($results)){
$e = array($model->alias => $results);
return $e;
}
}
}else{
//
}
return false;
}
My response from die(debug(array($model->alias => $results);
(int) 0 => array(
'Mandant' => array(
'ns2.id' => (int) 79129,
'ns2.name' => 'company a'
)
),
(int) 1 => array(
'Mandant' => array(
'ns2.id' => (int) 70000,
'ns2.name' => 'company b'
)
),
Controller Code is here:
public function test2(){
//$a = $this->User->find('list');
//die(debug($a));
$this->loadModel('Pay.Mandant');
$a = $this->Mandant->find('list', array('fields' => array('ns2.systembenutzernr', 'ns2.systembenutzernrBezeichnung')));
die(debug($a));
}
use,
$a = $this->Mandant->find('list', array('fields' => array('ns2.systembenutzernr', 'ns2.systembenutzernrBezeichnung')));
$this->set(compact('a'));
You can use $a for the dropdown creation in view file.
I just had the same problem writing my custom model though I don't know if the cause in your case is the same, though you should probably look in the same place.
in Model.php there is a function _findList($state, $query, $results), my issue was the fields you specify in the find() call must match the $results structure exactly, otherwise at the end of the _findList() function the call to:
Hash::combine($results, $query['list']['keyPath'], $query['list']['valuePath'], $query['list']['groupPath'])
returns the empty array. The keyPath of {n}.MODELNAME.id, etc must match the name of the model specified in $results, for example
[0] => ['MODELNAME'] = array()
[1] => ['MODELNAME'] = array()
In my case my keyPath and valuePath had a different value for MODELNAME than in the results array
Hope that helps

CakePHP Pagination: how can I sort by multiple columns to achieve "sticky" functionality?

I see that this paginate can't sort two columns at the same time ticket is still open, which leads me to believe that what I'm trying to do is not possible without a workaround. So I guess what I'm looking for is a workaround.
I'm trying to do what many message boards do: have a "sticky" function. I'd like to make it so that no matter which table header link the user clicks on to sort, my model's "sticky" field is always the first thing sorted, followed by whatever column the user clicked on. I know that you can set $this->paginate['Model']['order'] to whatever you want, so you could hack it to put the "sticky" field first and the user's chosen column second. The problem with this method is that pagination doesn't behave properly after you do it. The table header links don't work right and switching pages doesn't work right either. Is there some other workaround?
User ten1 on the CakePHP IRC channel helped me find the solution. I told him that if he posted the answer here then I would mark it as the correct one, but he said I should do it myself since he doesn't have a Stack Overflow account yet.
The trick is to inject the "sticky" field into the query's "order" setting using the model's "beforeFind" callback method, like this:
public function beforeFind($queryData) {
$sticky = array('Model.sticky' => 'DESC');
if (is_array($queryData['order'][0])) {
$queryData['order'][0] = $sticky + $queryData['order'][0];
}
else {
$queryData['order'][0] = $sticky;
}
return $queryData;
}
What you can do is code it in the action. Just create the query you want when some parameters exist on the URL. (parameters has to be sent by GET)
For example:
public function posts(){
$optional= array();
if(!empty($this->params->query['status'])){
if(strlower($this->params->query['status']=='des')){
$optional= array('Post.status DESC');
}
else if(strlower($this->params->query['status']=='asc')){
$optional= array('Post.status ASC');
}
}
if(!empty($this->params->query['department'])){
//same...
}
//order first by the sticky field and then by the optional parameters.
$order = array('Post.stickyField DESC') + $optional;
$this->paginate = array(
'conditions' => $conditions,
'order' => $order,
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));
}
I have used something similar to filter some data using $conditions instead of $order and it works well.
You can use custom field for sorting and update pagination component.
Controller code
$order['Document.DATE'] = 'asc';
$this->paginate = array(
"conditions"=> $conditions ,
"order" => $order ,
"limit" => 10,
**"sortcustom" => array('field' =>'Document.DATE' , 'direction' =>'desc'),**
);
Changes in pagination component.
public function validateSort($object, $options, $whitelist = array()) {
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
$field = key($options['order']);
if (!in_array($field, $whitelist)) {
$options['order'] = null;
}
}
if (!empty($options['order']) && is_array($options['order'])) {
$order = array();
foreach ($options['order'] as $key => $value) {
$field = $key;
$alias = $object->alias;
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
if ($object->hasField($field)) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}
**if(count($options['sortcustom']) > 0 )
{
$order[$options['sortcustom']['field']] = $options['sortcustom']['direction'];
}**
$options['order'] = $order;
}
return $options;
}
Easy insert 'paramType' => 'querystring',
Show Code Example:
$this->paginate = array(
'conditions' => $conditions,
'order' => array(
'Post.name' => 'ASC',
'Post.created' => 'DESC',
),
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));

Resources