need help what wrong with my code where this my sql command where successfull run in mysql :
SELECT func_inc_var_session() As row_number ,
vruasjalan2.*
FROM vruasjalan2 Where skid = #skid
ORDER BY kategoriruasjalanid, subkategoriruasjalanid,ruasjalanid;"
but when i want to display in my controller row_number start error say"Call to undefined method Jalan_model::num_rows()"
public function ajax_list()
{
$list = $this->Jalan->get_datatables();
$data = array();
$no = $_POST['start'];
foreach ($list as $Jalan) {
$no++;
$row = array();
$row[] = $no;
$row[] = $Jalan->row_number;
$row[] = $Jalan->ruasjalanid;
$row[] = $Jalan->skid;
$data[] = $row;
}
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->Jalan->count_all(),
"recordsFiltered" => $this->Jalan->count_filtered(),
"data" => $data,
);
//output to json format
echo json_encode($output);
}
}
and this is my model
public function get_list_companys()
{
$this->db->select('vruasjalan2.*');
$this->db->from($this->table);
$this->db->order_by('kategoriruasjalanid','asc');
$query = $this->db->get();
$result = $query->result();
$companys = array();
foreach ($result as $row)
{
$companys[] = $row->kategoriruasjalanid;
}
return $companys;
}
if there any expert know this problems
I searched the web 1000000000000000 times and i can't find a clean solution for this
this is my CertificateType model translation part:
public $actsAs = array('Translate'=>array('title','description')) ;
and the Certificate model:
public $actsAs=array('Translate'=>array('filename')) ;
public $belongsTo = array(
'CertificateType' => array(
'className' => 'CertificateType',
'foreignKey' => 'certificate_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
) ,
);
But in fetch time the belonged model will not translate:
public function admin_index() {
$this->Certificate->locale = $this->Session->read('Config.language');
$this->Certificate->CertificateType->locale = $this->Session->read('Config.language');
$this->Certificate->recursive = 0;
$this->set('certificates', $this->paginate());
debug($this->Certificate->paginate()) ;
}
Why?
I used this and it is working great!
in AppModel.php I wrote these piece of code:
public function getTranslatedModelField($id = 0, $field) {
// retrieve active language
$ActiveLanguageCatalog=CakeSession::read('Config.ActiveLanguageCatalog') ;
$res = false;
$translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
$db = $this->getDataSource();
$tmp = $db->fetchAll(
"SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
array($this->alias, $ActiveLanguageCatalog['locale'], $id, $field)
);
if (!empty($tmp)) {
$res = $tmp[0][$translateTable]['content'];
}
return $res;
}
public function afterFind($results, $primary = false) {
if($primary == false && array_key_exists('Translate', $this->actsAs)) {
foreach ($results as $key => $val) {
if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
foreach($this->actsAs['Translate'] as $translationfield) {
$results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $translationfield);
}
} else if($key == 'id' && is_numeric($val)) {
foreach($this->actsAs['Translate'] as $translationfield) {
$results[$translationfield] = $this->getTranslatedModelField($val, $translationfield);
}
}
}
}
return $results;
}
Add code below to AppModel:
public function afterFind($results, $primary = false) {
if(!empty($this->hasMany)) {
foreach($this->hasMany as $model => $settings) {
if(isset($this->{$model}->actsAs['Translate'])) {
if(!empty($results[0][$model])) {
foreach($results[0][$model] as $row => $result) {
$supplement = $this->{$model}->find('first', array(
'conditions' => array(
$model .'.id' => $result['id']),
'fields' => $this->{$model}->actsAs['Translate'],
'recursive' => -1));
if(!empty($supplement)) {
$results[0][$model][$row] = array_merge($results[0][$model][$row], array_diff($supplement[$model], $result));
}
}
}
}
}
}
if(!empty($this->belongsTo)) {
foreach($this->belongsTo as $model => $settings) {
if(isset($this->{$model}->actsAs['Translate'])) {
if(!empty($results[0][$model])) {
foreach($results[0][$model] as $row => $result) {
$supplement = $this->{$model}->find('first', array(
'conditions' => array(
$model .'.id' => $result),
'fields' => $this->{$model}->actsAs['Translate'],
'recursive' => -1));
if(!empty($supplement)) {
$results[0][$model] = array_merge($results[0][$model], $supplement[$model]);
}
}
}
}
}
}
return $results;
}
This works with relation hasMany and belongsTo
Thanks to Vahid Alimohamadi for the snipped. I had to modify it to work properly in my proJect.
public function getTranslatedModelField($id = 0, $field) {
// retrieve active language
//$ActiveLanguageCatalog=CakeSession::read('Config.ActiveLanguageCatalog') ;
$locale = Configure::read('Config.language');
$res = false;
$translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
$db = $this->getDataSource();
$tmp = $db->fetchAll(
"SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
array($this->alias, $locale/*$ActiveLanguageCatalog['locale']*/, $id, $field)
);
if (!empty($tmp)) {
$res = $tmp[0][$translateTable]['content'];
}
return $res;
}
public function afterFind($results, $primary = false) {
if($primary == false && array_key_exists('Translate', $this->actsAs)) {
foreach ($results as $key => $val) {
if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
//HERE ADDED $field => $translationfield AND PASS IT TO THE getTranslatedModelField
foreach($this->actsAs['Translate'] as $field => $translationfield) {
$results[$key][$this->name][$field] = $this->getTranslatedModelField($val[$this->name]['id'], $field);
}
} else if($key == 'id' && is_numeric($val)) {
//HERE ADDED $field => $translationfield AND PASS IT TO THE getTranslatedModelField
foreach($this->actsAs['Translate'] as $field => $translationfield) {
$results[$field] = $this->getTranslatedModelField($val, $field);
}
}
}
}
return $results;
}
I have some update to working in cakephp 2.5. It working for me now. Hope can help.
public function getTranslatedModelField($id = 0, $field) {
$res = false;
$translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
$db = $this->getDataSource();
$tmp = $db->fetchAll(
"SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
array($this->alias, $this->locale , $id, $field)
);
if (!empty($tmp)) {
$res = $tmp[0][$translateTable]['content'];
}
return $res;
}
public function afterFind($results, $primary = false) {
if($primary == false && array_key_exists('Translate', $this->actsAs)) {
foreach ($results as $key => $val) {
if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
foreach($this->actsAs['Translate'] as $k => $translationfield) {
$results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $k);
}
} else if($key == 'id' && is_numeric($val)) {
foreach($this->actsAs['Translate'] as $k => $translationfield) {
$results[$translationfield] = $this->getTranslatedModelField($val, $k);
}
}
}
}
return $results;
}
I had done a change for getting current language and works perfectly with cacke 2.4.3
public function getTranslatedModelField($id = 0, $field) {
// retrieve active language
$locale = $this->locale ;// gets the current assigned locale
$res = false;
$translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
$db = $this->getDataSource();
$tmp = $db->fetchAll(
"SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
array($this->alias, $locale , $id, $field)
);
if (!empty($tmp)) {
$res = $tmp[0][$translateTable]['content'];
}
return $res;
}
public function afterFind($results, $primary = false) {
if($primary == false && array_key_exists('Translate', $this->actsAs)) {
foreach ($results as $key => $val) {
if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
foreach($this->actsAs['Translate'] as $translationfield) {
$results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $translationfield);
}
} else if($key == 'id' && is_numeric($val)) {
foreach($this->actsAs['Translate'] as $translationfield) {
$results[$translationfield] = $this->getTranslatedModelField($val, $translationfield);
}
}
}
}
return $results;
}
The easiest solution is the following get the ids of the associated models items and make another search like the following:
$ids = array();
foreach ($wpage['Widget'] as &$widget):
$ids[] = $widget['id'];
endforeach;
$widgets = $this->Wpage->Widget->find('all', array(
'conditions' => array('Widget.id' => $ids)
));
$this->set(compact('wpage', 'widgets'));
Thanks,
Aris
Enabling Translate behavior for related models is very easy in Cake way, by using Model->SubModel->Behaviors->load(...)
$this->Certificate->CertificateType->Behaviors->load(
'Translate',
array('title','description')
);
Have a look at http://book.cakephp.org/2.0/en/models/behaviors.html
i using CodeIgniter Session with database for save a array with $_FILES, but don't save. I do this (but the array never increment):
The post of form, redirects to himself.
Function to upload e load the page of upload.
public function getUpload($codtemp, $codmessage){
$this->load->library('session');
$this->layout = '';
$data = array();
$data['codmessage'] = $codmessage;
$data['codtemp'] = $codtemp;$tempfiles= $this->session->userdata('tempfiles');
if (isset($_FILES['attachment']))
{
$files = $this->fixGlobalFilesArray($_FILES['attachment']);
foreach($files as $file)
{
$tempfiles[$codtemp][] = $file;
}
$this->session->set_userdata('tempfiles', $tempfiles);
unset($files);
}
$this->parser->parse('attachment_upload', $data);
}
private static function fixGlobalFilesArray($files) {
$ret = array();
if(isset($files['tmp_name']))
{
if (is_array($files['tmp_name']))
{
foreach($files['name'] as $idx => $name)
{
$ret[$idx] = array(
'name' => $name,
'tmp_name' => $files['tmp_name'][$idx],
'size' => $files['size'][$idx],
'type' => $files['type'][$idx],
'error' => $files['error'][$idx]
);
}
}
else
{
$ret = $files;
}
}
else
{
foreach ($files as $key => $value)
{
$ret[$key] = self::fixGlobalFilesArray($value);
}
}
return $ret;
}
Before save the array, serialize the data and after get the data, unserialize. If data is empty, create a array
Lets say I have the following tables: categories, posts and categories_posts. Category acts as a Tree. There is a habtm between Category and Post.
What I want to do from the Posts Controller is find a specific Post and list the Categories it belongs to in a threaded/nested format.
temporary solution: (my coding is probably rather poor - my apologies)
public function view($id=null) {
$this->Post->id = $id;
if($this->Post->exists()) {
$data = $this->Post->read();
$data['Category'] = $this->_thread($data);
$this->set(compact('data'));
}
}
public function _thread($data, $parent_id=null) {
$out = array();
$parents = Set::extract("/Category[parent_id={$parent_id}]", $data);
foreach($parents as $k => $item) {
$out[$k] = $item;
$out[$k]['Category']['children'] = Set::extract("/Category[parent_id={$item['Category']['id']}]", $data);
foreach($out[$k]['Category']['children'] as $key => $child) {
$out[$k]['Category']['children'][$key]['Category']['children'] = $this->_thread($data, $child['Category']['id']);
}
}
return $out;
}
This may help you out :
$data = $this->Post->find('threaded', array(
'conditions' => array('id' => 1)
));
'conditions' array is for example,you can pass your required conditions if any.
I have the following situation where I want to only display the search results when user search for something. Currrently, as I access my search page, all the search results is being displayed and if user search for a particular thing, it displays that accordingly. The following is the code in my search controller. I added a pagination for it to paginate.
function simple_search() {
$this->User->recursive = 1;
$this->Passion->recursive = 1;
$this->User->unBindModel(array('hasMany' => array('Topic','Post')),false);
$conditions = array();
$options;
$or_conditions = array();
$final_conditions = array();
$search_fields = array('User.firstName', 'User.lastName', 'User.email', 'User.displayName'); //fields to search 'Video.tags','Video.desc'
$this->layout = "mainLayout";
$value='';
if(!empty($this->params["url"]["value"])){
$value = $this->params["url"]["value"];
}
$searches = explode(" ", $value);
foreach ($search_fields as $f) {
array_push($conditions, array("$f Like" => "$value%"));
for ($i = 0; $i < count($searches); $i++) {
if ($searches[$i] != "") {
array_push($conditions, array("$f Like" => "$searches[$i]%"));
}
}
array_push($or_conditions, array('OR' => $conditions));
$conditions = array();
}
$final_conditions = array('OR' => $or_conditions);
$users = $this->User->find('all', $final_conditions);
$this->paginate = array(
'conditions' => $final_conditions,
'limit' => 10
);
$users = $this->paginate('User');
$this->set('search_fields', $users);
}
Why are you doing the find('all')? A few lines later paginate() overrides the result.
empty($this->params['url']['value'] check this and set your results to the view only in the case its not empty.
Follow the coding standard for CakePHP and use camelCased variable names instead of underscores. http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html
Also you might want to take a look at this.
https://github.com/CakeDC/search
And at this (showing a custum find using search plugin)
https://github.com/CakeDC/users/blob/master/controllers/users_controller.php#L316
https://github.com/CakeDC/users/blob/master/models/user.php#L557