array named for no reason - arrays

I calling a repository method and passing an array in it for the parameters. But the array is named after the first parameter and I don't understand why.
Here's the call :
/**
* #param $month
* #param $year
* #return Conges[]
*/
public function getAllCongesPayes($year, $month)
{
return $this->congesRepository->getNbCongesByMonth(array('year' => $year, 'month' => $month, 'cngPaye' => true));
}
And in the error I can see that :
array('year' => array('year' => '2016', 'month' => '05', 'cngPaye' => true)))
And of course it's saying "Missing argument 2" because only one array is in it.
Here is the repository method:
public function getNbCongesByMonth($year, $month, $conge){
$qb = $this->createQueryBuilder('e');
$listOfEntities = $qb
->select('count(e) as nb')
// ->leftjoin('e.cngUsrLogin', 'u')
->where(
$qb->expr()->like('e.cngDateDebut',
$qb->expr()->literal($year.'-'.$month.'-%')
)
)
->andWhere('e.congesPayes = :conge')
// ->andWhere('u.usrGestionCra = 1')
// ->groupBy('e')
->setParameter('conge', $conge)
->getQuery()
->getResult();
return $listOfEntities;
}
and the call in the controller :
$this->congesService = $this->get("intranet.conges_service");
$nbCongesPayes = $this->congesService->getAllCongesPayes('2016', '05');
If someone could explain why this happens that would be awesome.
Thanks in advance.

OK, I'm really dumb and figured it 2 minutes after... Sorry for the post...
Here is the answer :
public function getNbCongesByMonth($array){
$qb = $this->createQueryBuilder('e');
$listOfEntities = $qb
->select('count(e) as nb')
// ->leftjoin('e.cngUsrLogin', 'u')
->where(
$qb->expr()->like('e.cngDateDebut',
$qb->expr()->literal($array['year'].'-'.$array['month'].'-%')
)
)
->andWhere('e.cngPaye = :conge')
// ->andWhere('u.usrGestionCra = 1')
// ->groupBy('e')
->setParameter('conge', $array['cngPaye'])
->getQuery()
->getResult();
return $listOfEntities;
}
Needed to pass an array in the parameters. I don't know why I did that.
Anyway it's solved

Related

Object of class could not be converted to string of class CI_DB_mysqli_result

Controller :
function index()
{
$this->load->helper(array('form', 'url','common'));
$this->load->library(array('session','pagination'));
$this->load->model('productsdisplay','',TRUE);
$data=array(
'header' => $this->load->view('frontend/assets/header', '', TRUE),
'footer' => $this->load->view('frontend/assets/footer', '', TRUE),
);
$item= $this->input->get('products', TRUE);
$newarray[]=array();
$item_id =$this->db->query('select id from item where slug=(".$item.")');
$result=$item_id->result();
var_dump($result);
$data['category']=$this->productsdisplay->getAllCategories($item_id);
$data['kvas']=$this->productsdisplay->getAllKva();
$data['items']=$this->productsdisplay->getAllItems();
$data['applications']=$this->productsdisplay->getAllApplication();
$data['products'] = $this->productsdisplay->getAllProduct();
$data['ads'] = $this->productsdisplay->getAllAds();
$insert_id=$this->productsdisplay->addEnquiry($this->input->post());
$this->load->view('frontend/product/index',$data);
}
Model :
function getAllCategories($item_id)
{
if($item_id!=''){
$this->db->select('category_name');
$this->db->order_by("category_name", "ASC");
$query = $this->db->where('product_type',$item_id);
$query = $this->db->get('category');
return $query->result();
}
}
I am not able to understand how to solve this error. Please help me regarding the issue.
I am a beginner in CI.
The query which gets $item_id is wrong. It should be changed as follows
$item_id =$this->db->query('select id from item where slug='.$item);

issues with saveAssociated cakephp

I'm having some issues trying to save an article that has 4 pictures. The thing is that i need to use the article id in order to name the pictures like article_id."-"$i
Since I have only 4 pictures per article this $i should be from 1 to 4 or from 0 to three.
Now the problem is that in order to achieve this i need to create and save Article model so i can have an id to use, but then after performing all the scripting to make the thumbs and form the names, when I go Article->saveAssociated() i have two times the article record created!! i tried to set the id to "-1" before saving but nothing...
Any suggestion will be very much appreciated !!!
Code:
public function add() {
if ($this->request->is ( 'ajax' )) {
$this->layout = 'ajax';
} else {
$this->layout = 'default';
}
if ($this->request->is ( 'post' )) {
$this->Article->create ();
$this->request->data ['Article'] ['time_stamp'] = date ( 'Y-m-d H:i:s', time () );
if ($this->Article->save($this->request->data) ) {
for ($i=0; $i<4; $i++){
$img_path = "./images/";
$extension[$i] = end(explode('.', $this->request->data['Image'][$i]['image']['name']));
$this->request->data['Image'][$i]['image'] = array('name'=>$this->Article->id."-".$i, 'tmp_name' => $this->request->data['Image'][$i]['image']['tmp_name']);
// $this->request->data['Image'][$i]['name'] = $this->Article->id."-".$i;
$this->request->data['Image'][$i]['ext']= $extension[$i];
$target_path[$i] = $img_path . basename($this->request->data['Image'][$i]['image']['name'].".".$extension[$i]);
if(!move_uploaded_file($this->request->data['Image'][$i]['image']['tmp_name'], $target_path[$i])) {
die(__ ( 'Fatal error, we are all going to die.' ));
}else{
$this->Resize->img($target_path[$i]);
$this->Resize->setNewImage($img_path.basename($this->request->data['Image'][$i]['image']['name']."t.".$extension[$i]));
$this->Resize->setProportionalFlag('H');
$this->Resize->setProportional(1);
$this->Resize->setNewSize(90, 90);
$this->Resize->make();
}
}
$this->Article->id;
pr($this->Article->id);
$this->Article->saveAssociated($this->request->data, array('deep' => true));
//$this->redirect ( array ('action' => 'view', $this->Article->id ) );
pr($this->Article->id);
exit;
$this->Session->setFlash ( __ ( 'Article "' . $this->request->data ["Article"] ["name"] . '" has been saved' ) );
} else {
$this->Session->setFlash ( __ ( 'The article could not be saved. Please, try again.' ) );
}
}
$items = $this->Article->Item->find ( 'list' );
$payments = $this->Article->Payment->find ( 'list' );
$shippings = $this->Article->Shipping->find ( 'list' );
$this->set ( compact ( 'items', 'payments', 'shippings' ) );
}
Instead of
$this->Article->saveAssociated();
which would save the Article AGAIN, just save the images separately using something like this:
foreach($this->request->data['Image'] as &$image) {
$image['name'] = 'whatever_you_want' . $this->Article->id;
$image['article_id'] = $this->Article->id;
}
$this->Article->Image->save($this->request->data['Image']);
Another option (not necessarily better - just another option) would just be to append the newly-created Article's id to the existing Article array, then saveAssociated(). If the Article has an id in it's data, it will update instead of create. I would suggest the first answer above, but - just brainstorming other options in case this helps for someone's scenario:
// 1) save the Article and get it's id
// 2) append the `id` into the Article array
// 3) do your image-name manipulation using the id
// 4) saveAssociated(), which updates the Article and creates the Images

How do I use fixed fields in CakeDC's csvUpload behavior in Util plugin

I am using the csvUpload behavior of the Utils plugin by CakeDC, on a CakePHP 2.2.1 install.
I have it working great it's processing a rather large csv successfully. However there are two fields in my table / Model that would be considered fixed, as they are based on ID's from from associated models that are not consistent. So I need to get these fixed values via variables which is easy enough.
So my question is, how do I use the fixed fields aspect of csvUpload? I have tried that following and many little variation, which obviously didn't work.
public function upload_csv($Id = null) {
$unique_add = 69;
if ( $this->request->is('POST') ) {
$records_count = $this->Model->find( 'count' );
try {
$fixed = array('Model' => array('random_id' => $Id, 'unique_add' => $unique_add));
$this->Model->importCSV($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
} catch (Exception $e) {
$import_errors = $this->Model->getImportErrors();
$this->set( 'import_errors', $import_errors );
$this->Session->setFlash( __('Error Importing') . ' ' . $this->request->data['Model']['CsvFile']['name'] . ', ' . __('column name mismatch.') );
$this->redirect( array('action'=>'import') );
}
$new_records_count = $this->Model->find( 'count' ) - $records_count;
$this->Session->setFlash(__('Successfully imported') . ' ' . $new_records_count . ' records from ' . $this->request->data['Model']['CsvFile']['name'] );
$this->redirect(array('plugin'=>'usermgmt', 'controller'=>'users', 'action'=>'dashboard'));
}
}
Any help would be greatly appreciated as I have only found 1 post concerning this behavior when I searching...
I made my custom method to achieve the same task. Define the following method in app\Plugin\Utils\Model\Behavior
public function getCSVData(Model &$Model, $file, $fixed = array())
{
$settings = array(
'delimiter' => ',',
'enclosure' => '"',
'hasHeader' => true
);
$this->setup($Model, $settings);
$handle = new SplFileObject($file, 'rb');
$header = $this->_getHeader($Model, $handle);
$db = $Model->getDataSource();
$db->begin($Model);
$saved = array();
$data = array();
$i = 0;
while (($row = $this->_getCSVLine($Model, $handle)) !== false)
{
foreach ($header as $k => $col)
{
// get the data field from Model.field
$col = str_replace('.', '-', trim($col));
if (strpos($col, '.') !== false)
{
list($model,$field) = explode('.', $col);
$data[$i][$model][$field] = (isset($row[$k])) ? $row[$k] : '';
}
else
{
$col = str_replace(' ','_', $col);
$data[$i][$Model->alias][$col] = (isset($row[$k])) ? $row[$k] : '';
}
}
$is_valid_row = false;
foreach($data[$i][$Model->alias] as $col => $value )
{
if(!empty($data[$i][$Model->alias][$col]))
{
$is_valid_row = true;
}
}
if($is_valid_row == true)
{
$i++;
$data = Set::merge($data, $fixed);
}
else
{
unset($data[$i]);
}
}
return $data;
}
And you can use it using:
$csv_data = $this->Model->getCSVData($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
Here $csv_data will contain an array of all of those records from the csv file which are not empty and with the fixed field in each record index.
So as I was telling Arun, I answered my own question and figured it out. I was looking to broad instead of really examining what was in front of me. I started running some debugging and figured it out.
First of all, $unique_add = 69 is seen as an int, duh. In order for it to be added to the csv it need to viewed as a string. So it simply becomes, $unique_add = '69'.
I couldn't enter the value of $Id directly into the fixed array. So I just had to perform a simple find to get the value I needed.
$needed_id = $this->Model->find('first', array(
'condition'=>array('Model.id'=>$Id)
)
);
$random_id = $needed_id['Model']['id'];
Hopefully this won't be needed to help anyone because hopefully no one else will make this silly mistake. But one plus... Now there's actually more than one post on the internet documenting the use of fixed fields in the CakeDC Utils plugin.

CakePHP 2.0 - Use MySQL ENUM field with form helper to create Select Input

I've been researching a bit and I found that CakePHP's form helper doesn't interpret ENUM fields correctly, so it simply outputs a text input. I found a post that suggested to use a helper for that specific purpose. Does anybody know a better way to achieve this? Or if CakePHP devs intend to correct this some day?
Thanks for reading!
Below is one of the helper extention.
App::uses('FormHelper', 'View/Helper');
/**
* APP/View/Helper/MySqlEnumFormHelper.php
* It extends FormHelper to implement ENUM datatype of MySQL.
*
* http://blog.xao.jp/blog/cakephp/implementation-of-mysql-enum-datatype-in-formhelper/
*
* created Oct. 15, 2012
* CakePHP 2.2.3
*/
class MySqlEnumFormHelper extends FormHelper
{
public function input($fieldName, $options = array())
{
if (!isset($options['type']) && !isset($options['options'])) {
$modelKey = $this->model();
if (preg_match(
'/^enum\((.+)\)$/ui',
$this->fieldset[$modelKey]['fields'][$fieldName]['type'],
$m
)) {
$match = trim($m[1]);
$qOpen = substr($match, 0, 1);
$qClose = substr($match, -1);
$delimiter = $qOpen . ',' . $qClose;
preg_match('/^'.$qOpen.'(.+)'.$qClose.'$/u', $match, $m);
$_options = explode($delimiter, $m[1]);
$options['type'] = 'select';
$options['options'] = array_combine($_options, $_options);
}
}
return parent::input($fieldName, $options);
}
}
Cake attempts to be database agnostic and therefore this issue won't be "corrected" since it's not a bug. For example, SQL server doesn't have an exact equivalent of MySQL's ENUM field type.
I would recommend getting your possible list of enum values like so:
YourController.php
// get column type
$type = $this->Model->getColumnType('field');
// extract values in single quotes separated by comma
preg_match_all("/'(.*?)'/", $type, $enums);
// enums
var_dump($enums[1]);
Then use a select field in your view and pass the enums as options. Your current value you'll already have. How does that sound?
I am new to cakephp I found some old code and pieced together an enum select box for you enjoy
/**
* Behavior with useful functionality around models containing an enum type field
*
* Copyright (c) Debuggable, http://debuggable.com
*
*
*
* #package default
* #access public
*
* reworked by Nathanael Mallow for cakephp 2.0
*
*/
/*
*Use case:Add this (EnumerableBehavior.php) to app/Model/Behavior/
* -->in the Model add public $actsAs = array('Enumerable');
* -->in the *_controller add $enumOptions = $this->Categorie->enumOptions('Section');
* -->in the view add print $this->Form->input('{db_field_name}', array('options' => $enumOptions, 'label' => 'here'));
*
*
*/
class EnumerableBehavior extends ModelBehavior {
/**
* Fetches the enum type options for a specific field
*
* #param string $field
* #return void
* #access public
*/
function enumOptions($model, $field) {
//Cache::clear();
$cacheKey = $model->alias . '_' . $field . '_enum_options';
$options = Cache::read($cacheKey);
if (!$options) {
$sql = "SHOW COLUMNS FROM `{$model->useTable}` LIKE '{$field}'";
$enumData = $model->query($sql);
$options = false;
if (!empty($enumData)) {
$enumData = preg_replace("/(enum|set)\('(.+?)'\)/", '\\2', $enumData[0]['COLUMNS']['Type']);
$options = explode("','", $enumData);
}
Cache::write($cacheKey, $options);
}
return $options;
}
}
?>
If you want to use MySqlEnumFormHelper instead of normal and call it by $this->Form-> instead by $this->MySqlEnumFormHelper . You should add this line in your controller to alias MySqlEnumFormHelper as Form.
public $helpers = array('Form' => array(
'className' => 'MySqlEnumForm'
));
/* comments about previus answers ***
Use case:Add this (EnumerableBehavior.php) to app/Model/Behavior/
-->in the Model add public $actsAs = array('Enumerable');
-->in the action of the *_controller add $enumOptions = $this->YourModelName->enumOptions('db_field_name'); $this->set('enumOptions',$enumOptions);
-->in the view add print $this->Form->input('{db_field_name}', array('options' => $enumOptions, 'label' => 'here'));
*
*/
i think the Behaviour way it's good...but the array keys are integer
so i have modified the function like this
function enumOptions($model, $field) {
//Cache::clear();
$cacheKey = $model->alias . '_' . $field . '_enum_options';
$options = Cache::read($cacheKey);
$enumOptions = array();
if (!$options) {
$sql = "SHOW COLUMNS FROM `{$model->useTable}` LIKE '{$field}'";
$enumData = $model->query($sql);
$options = false;
if (!empty($enumData)) {
$enumData = preg_replace("/(enum|set)\('(.+?)'\)/", '\\2', $enumData[0]['COLUMNS']['Type']);
$options = explode("','", $enumData);
foreach ($options as $option) {
$enumOptions["$option"] = $option;
}
}
Cache::write($cacheKey, $enumOptions);
}
return $enumOptions;
}
in order to be able to save the right value in the db field when the form is submitted
I created a function that goes into AppController to handle this. I combined some of the information provided above.
Usage:
$enumList = getEnumValues($ModelField) where ModelField is in this format: 'Model.Field'
Function that I put in AppController:
function getEnumValues($ModelField){
// split input into Model and Fieldname
$m = explode('.', $ModelField);
if ($m[0] == $ModelField) {
return false;
} else {
(! ClassRegistry::isKeySet($m[0])) ? $this->loadModel($m[0]): false;
$type = $this->$m[0]->getColumnType($m[1]);
preg_match_all("/'(.*?)'/", $type, $enums);
foreach ($enums[1] as $value){$enumList[$value] = $value;}
return $enumList;
}
}

cakephp save data is giving me an error

I am trying to insert the following array
foreach($list as $l)
{
$data = array(
'source_number'=> $l['Csv']['Source'],
'destination_number'=> $l['Csv']['Destination'],
'seconds'=> $l['Csv']['Seconds'],
'callerID'=> $l['Csv']['CallerID'],
'disposition'=> $l['Csv']['Disposition'],
'cost'=> $l['Csv']['Cost'],
'billing_cost'=> $l['Csv']['newCost']
);
//$total[] = $l['Csv']['newCost'];
debug($data);
$this->CallcenterBilling->save($data);
unset($data);
}
But it dives me this error
( ! ) Fatal error: Call to a member function save() on a non-object in C:\wamp\www\wadic\app\Controller\CallcenterBillingsController.php on line 61
Call Stack
# Time Memory Function Location
1 0.0005 708160 {main}( ) ..\index.php:0
2 0.0169 2775744 Dispatcher->dispatch( ) ..\index.php:96
3 0.0279 3946176 Dispatcher->_invoke( ) ..\Dispatcher.php:89
4 0.0293 4016984 Controller->invokeAction( ) ..\Dispatcher.php:107
5 0.0293 4017992 ReflectionMethod->invokeArgs( ) ..\Controller.php:473
6 0.0293 4018024 CallcenterBillingsController->import( ) ..\CallcenterBillingsController.php:0
what am I missing?
thanks
Firstly you may sure that in CallcenterBillingsController you have CallcenterBilling model in uses:
public $uses = array('CallcenterBilling');
Secondary you can optimize this by saving not in loop:
see saveAll method of the model
so you will get something like:
class CallcenterBillingController extends AppController {
public $uses = array('CallcenterBilling');
public function someaction() {
$data = array();
foreach ($list as $l) {
$data[] = array(
'source_number' => $l['Csv']['Source'],
'destination_number' => $l['Csv']['Destination'],
'seconds' => $l['Csv']['Seconds'],
'callerID' => $l['Csv']['CallerID'],
'disposition' => $l['Csv']['Disposition'],
'cost' => $l['Csv']['Cost'],
'billing_cost' => $l['Csv']['newCost']
);
//$total[] = $l['Csv']['newCost'];
}
debug($data);
$this->CallcenterBilling->saveAll($data);
}
}
ps. if this not helps, please show controller code.
You should implement this:
$this->CallcenterBilling->read(null, 1);
$this->CallcenterBilling->set(array(
'source_number'=> $l['Csv']['Source'],
'destination_number'=> $l['Csv']['Destination'],
'seconds'=> $l['Csv']['Seconds'],
'callerID'=> $l['Csv']['CallerID'],
'disposition'=> $l['Csv']['Disposition'],
'cost'=> $l['Csv']['Cost'],
'billing_cost'=> $l['Csv']['newCost']
));
$this->CallcenterBilling->save();
This might works for you.

Resources