yii apply sort to CActiveDataProvider - sorting

I am trying to apply sort from remember filters on my admin function i have
if (isset($_GET[ucfirst($this->id) .'_sort'])) {
$extractSort = $_GET[ucfirst($this->id) .'_sort'];
//Yii::log($extractSort);
Yii::app()->user->setState(ucfirst($this->id) .'_sort', $extractSort);
} else if(Yii::app()->user->hasState(ucfirst($this->id) .'_sort')) {
$_GET['sort'] = Yii::app()->user->getState(ucfirst($this->id) .'_sort');
//Yii::log(Yii::app()->user->getState(ucfirst($this->id) .'_sort'));
}
On my view I have jquery which triggers n update to get the state of a model on another function. however I am having trouble applying the sort.
$model=Yii::app()->user->getState('exportModel');
$dataProvider = $model->weeklystatus(array(),false);
if(Yii::app()->user->hasState(ucfirst($this->id) .'_sort')) {
Yii::log(Yii::app()->user->getState(ucfirst($this->id) .'_sort'));
$explode = explode("Yii::app()->user->getState(ucfirst($this->id) .'_sort')" , ".");
$sort = new CSort();
$sort->attributes = array(
$explode[0]=>array(
'asc'=>$explode[0]." ASC",
'desc'=>$explode[0] . " DESC",
),
'*',
);
$sort->applyOrder($model);
$dataProvider->setSort($sort);
}
My model function search
public function weeklystatus($arr = array(),$ignore = false,$showspline = false)
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
//Yii::log(var_dump($this->getPlannedPOC()));
$criteria=new CDbCriteria;
$criteria->select='*, ((CURDATE() - StartDATE) / (ProjectEndDate - StartDATE ))*100 as PlannedPOC';
if($showspline)
$criteria->addCondition('PROJECT = "' .$this->PROJECT . '"');
else
$criteria->compare('PROJECT',$this->PROJECT,true);
$stradd = '';
if(!empty($arr) && isset($arr['PROJCODE'])){
$str = '';
foreach($arr['PROJCODE'] as $value) {
$str .= "PROJCODE = '$value' || ";
}
$criteria->addCondition(substr($str, 0, -3));
$stradd .= substr($str, 0, -3);
}else
$criteria->compare('PROJCODE',$this->PROJCODE,true);
$criteria->compare('PROJID',$this->PROJID);
$criteria->mergeWith($this->dateRangeSearchCriteria('StartDATE', $this->StartDATE));
$criteria->mergeWith($this->dateRangeSearchCriteria('ProjectEndDate', $this->ProjectEndDate));
$criteria->mergeWith($this->dateRangeSearchCriteria('ActualEndDate', $this->ActualEndDate));
$criteria->mergeWith($this->dateRangeSearchCriteria('ExpectedCompletionDate', $this->ExpectedCompletionDate));
$criteria->compare('PROCESSOR',$this->PROCESSOR,true);
if(!empty($arr) && isset($arr['OFFICE'])){
$stro = '';
foreach($arr['OFFICE'] as $value) {
$stro .= "OFFICE = '$value' || ";
}
$criteria->addCondition(substr($stro, 0, -3));
$stradd .= ") AND ( ".substr($stro, 0, -3);
}else
$criteria->compare('OFFICE',$this->OFFICE,true);
$criteria->compare('DEPTCODE',$this->DEPTCODE,true);
$criteria->compare('PERCENT',$this->PERCENT,true);
$criteria->compare('PERCENTPlanned',$this->PERCENTPlanned,true);
$criteria->compare('KM',$this->KM,true);
$criteria->compare('KMPlanned',$this->KMPlanned,true);
if(!empty($arr) && isset($arr['MC'])){
$str = '';
foreach($arr['MC'] as $value) {
$str .= "MC = '$value'";
}
$criteria->addCondition($str);
if(!empty($stradd)){
$stradd = "($stradd) AND ($str) AND ";
}
}else{
$criteria->compare('MC',$this->MC,true);
}
$criteria->compare('MCSALE',$this->MCSALE);
$criteria->compare('CATEGORY',$this->CATEGORY,true);
$criteria->compare('AREA',$this->AREA,true);
$criteria->compare('COUNTRY',$this->COUNTRY,true);
$criteria->compare('PROJINFO',$this->PROJINFO,true);
$criteria->compare('quality_timing',$this->quality_timing,true);
$criteria->compare('REGION',$this->REGION,true);
$criteria->compare('ASAAREA',$this->ASAAREA,true);
$criteria->compare('LORM',$this->LORM,true);
//$ignore = false;
//echo "1st: $ignore";
if(isset($_REQUEST['ViewWebprojectreport'])){
foreach ($_REQUEST['ViewWebprojectreport'] as $key => $value) {
//print_r($key);
//print_r($value);
if($key != "StartDATE"){
if($value != "")
$ignore = true;
}
//echo "\n";
}
}
//echo "2nd: $ignore";
if(!$ignore && !$showspline){
$date = date('Y-m-d',strtotime("-2 week"));
$criteria->addCondition("StartDATE > '".Yii::app()->params['filterStartDateonReports']."-01-01' AND (PERCENT < 100 || PERCENT is null)");
//$criteria->addCondition("(PERCENT < 100 || PERCENT is null)");
//$criteria->addCondition("StartDATE < '$date' AND PERCENT <100 || StartDATE > '$date' AND PERCENT =100 ");
$criteria->addCondition("$stradd (StartDATE > '$date' AND PERCENT =100) ","OR");
/*AND (StartDATE < '$date' AND PERCENT <100)
|| (StartDATE > '$date' AND PERCENT =100) ");*/
//$criteria->addCondition("PERCENT < 100 AND StartDATE < '$date'");
//$criteria->addCondition('StartDATE > '.$date . ' AND PERCENT > -1' );
}elseif(!$showspline){
$criteria->addCondition("StartDATE > '".Yii::app()->params['filterStartDateonReports']."-01-01'");
}
/*
if(isset($_REQUEST['ViewWebprojectreport_sort'])){
$sort = explode(".",$_REQUEST['ViewWebprojectreport_sort']);
if(isset($sort[1]))
$criteria->order = $sort[0] . " " . $sort[1];
else
$criteria->order = $_REQUEST['ViewWebprojectreport_sort'];
}elseif(Yii::app()->user->hasState("ViewWebprojectreport_sort")){
Yii::log(Yii::app()->user->getState("ViewWebprojectreport_sort"));
$sort = explode(".",Yii::app()->user->getState("ViewWebprojectreport_sort"));
if(isset($sort[1]))
$criteria->order = $sort[0] . " " . $sort[1];
else
$criteria->order = Yii::app()->user->getState("ViewWebprojectreport_sort");
}
//$criteria->order = 'id desc';
*/
$sort = new CSort();
$sort->attributes = array(
'*', // preserve sorting capability
"PROJECT"=>array(
"asc"=>"PROJECT ASC",
"desc"=>"PROJECT DESC"),
'PlannedPOC'=>array(
'asc'=>'PlannedPOC ASC',
'desc'=>'PlannedPOC DESC',
),
);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
"sort"=>$sort,
'pagination'=>array(
'pageSize'=>25,
),
));
}
I have tried which does not work
if(Yii::app()->user->hasState(ucfirst($this->id) .'_sort')) {
$explode = explode(".",Yii::app()->user->getState(ucfirst($this->id) .'_sort'));
$name = $explode[0];
$sort = new CSort();
if(count($explode)==2){
$sort->attributes = array(
/*$name => array(
"desc"=>$name . "DESC"
),*/
'defaultOrder'=>array(
$name=> CSort::SORT_DESC
),
);
}else{
$sort->attributes = array(
/*$name => array(
"asc"=>$name . " ASC",
),*/
'defaultOrder'=>array(
$name=> CSort::SORT_ASC
),
);
}
//Yii::log(print_r($explode,true));
Yii::log(print_r($sort->attributes,true));
$sort->applyOrder($model);
$dataProvider->setSort($sort);
}
following is print out of CSort
CSort Object
(
[multiSort] =>
[modelClass] => ViewWebprojectreport
[attributes] => Array
(
)
[sortVar] => sort
[descTag] => desc
[defaultOrder] => Array
(
[PROJECT] =>
)
[route] =>
[separators] => Array
(
[0] => -
[1] => .
)
[params] =>
[_directions:CSort:private] => Array
(
[PROJECT] =>
)
[_e:CComponent:private] =>
[_m:CComponent:private] =>
)

Would you try :
$model = Yii::app()->user->getState('exportModel');
$dataProvider = $model->weeklystatus(array(),false);
if(Yii::app()->user->hasState(ucfirst($this->id) .'_sort')) {
Yii::log(Yii::app()->user->getState(ucfirst($this->id) .'_sort'));
$explode = explode(Yii::app()->user->getState(ucfirst($this->id) .'_sort'), ".");
$sort = new CSort();
$sort->attributes = array(
$explode[0] => array(
'asc' => $explode[1] . " ASC",
'desc' => $explode[1] . " DESC",
),
'*',
);
$sort->applyOrder($model);
$dataProvider->setSort($sort);
}

Related

Larave CSRF protection do not work ( It do not ban the submittion when user backwards to previous page )

I have a form I'm using ajax to submit that. When I submit and go to message page for successful action if user backward to previous page and submit the form without changing it ( Or even when it changes ), CSRF protection does not deny the reload and submit and it makes that - in my transfer page - in this situation one submit is recording 2 or 3 times or more in database.
I think it is a CSRF problem but have no idea to fix it nor idea what is the problem.
I'm verifying CSRF-TOKEN using ajaxsetup like this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Update
My request code:
public function post(TransfersClientForm $request)
{
$inputs = $request->validated();
$currency = Wallet::find($inputs['origin'])->currency_id;
$main_wallet = MainWallet::query()->where(['currency_id' => $currency])->first();
$currency_symbol = Currency::find($inputs['origin'])->symbol;
$key_min = 'transfer_min_' . $currency_symbol;
$key_max = 'transfer_max_' . $currency_symbol;
$limitation_max = Limitation::where(['key' => $key_max])->first()->value;
$limitation_min = Limitation::where(['key' => $key_min])->first()->value;
if ($inputs['amount'] < $limitation_min) {
return response()->json(['error' => __('Minimum allowed transfer amount') . ': ' . $limitation_min . ' ' . __($currency_symbol)], 403);
}
if ($inputs['amount'] > $limitation_max) {
return response()->json(['error' => __('Maximum allowed transfer amount') . ': ' . $limitation_max . ' ' . __($currency_symbol)], 403);
}
if ($inputs['type'] != 2 && $inputs['transfer_date'])
return response()->json(
[
'error' => __('You only can set time through timeend transger type!')
]
, 403);
/* #var $origin_wallet Wallet */
$origin_wallet = \Auth::user()->wallets()->where(['currency_id' => $inputs['origin']])->first();
$destination_wallet = Wallet::query()->where(['account_number' => $inputs['destination']])->first();
if ($origin_wallet->currency_id != $destination_wallet->currency_id)
return response()->json(['error' => __('Origin and destination wallet currencies are not the same')], 403);
$value = [];
foreach (Exchange::query()->where(['origin' => Currency::query()->find($inputs['origin'])->symbol])->get() as $key => $item) {
$value[$item->destination] = $item->value;
}
switch (Currency::query()->find($inputs['origin'])->symbol) {
case 'euro':
case 'dollar':
$wage = Wage::query()->where(['key' => 'transfer_dollar'])->first()->value;
break;
case 'toman':
$wage = Wage::query()->where(['key' => 'transfer_toman'])->first()->value;
break;
case 'bitcoin':
$wage = Wage::query()->where(['key' => 'transfer_bitcoin'])->first()->value;
break;
}
$origin_balance = $origin_wallet->balance;
$origin_total = $origin_wallet->total;
$origin_balance -= $inputs['amount'];
$origin_total -= $inputs['amount'];
$transaction = new Transfer();
$transaction->currency_id = $origin_wallet->currency_id;
$transaction->amount = $inputs['amount'];
$transaction->value = $value;
$transaction->description = $inputs['description'];
$transaction->unique_id = Str::random(16);
$transaction->status = 0;
$transaction->wage = $wage;
$transaction->type = $inputs['type'];
$transaction->origin_wallet_id = $origin_wallet->id;
$transaction->destination_wallet_id = $destination_wallet->id;
if ($origin_balance - $wage < 0)
return response()->json(['error' => __('Not enough money')], 403);
if ($inputs['type'] == 1) {
$origin_wallet->update(['balance' => $origin_balance - $wage, 'total' => $origin_total - $wage]);
$destination_balance = $destination_wallet->balance;
$destination_total = $destination_wallet->total;
$destination_balance += $inputs['amount'];
$destination_total += $inputs['amount'];
$destination_wallet->update(['balance' => $destination_balance, 'total' => $destination_total]);
$transaction->status = 1;
$transaction->transfer_date = Carbon::now();
$transaction->save();
}
if ($inputs['type'] == 2) {
$origin_balance = $origin_wallet->balance;
$origin_balance -= $inputs['amount'];
$origin_total = $origin_wallet->total;
$origin_total -= $wage;
$origin_hold = $origin_wallet->hold + $inputs['amount'];
$origin_wallet->update(['balance' => $origin_balance - $wage, 'hold' => $origin_hold, 'total' => $origin_total]);
$destination_balance = $destination_wallet->total;
$destination_balance += $inputs['amount'];
$destination_hold = $destination_wallet->hold + $inputs['amount'];
$destination_wallet->update(['total' => $destination_balance, 'hold' => $destination_hold]);
$path = '';
if ($request->hasFile('file_image'))
$path = $this->storeFile($request->file('file_image'));
$transaction->src = $path;
if (\Auth::user()->userInformation->national_phone_number_code == "+98") {
$now = Carbon::createFromDate(Jalalian::now()->getYear(), Jalalian::now()->getMonth(), Jalalian::now()->getDay(), null);
$transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
$transaction->time_end_deadline = $now->diffInDays($transfer_date);
$transaction->transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
} else {
$now = Carbon::now();
$transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'en', null);
$transaction->time_end_deadline = $now->diffInDays($transfer_date);
$transaction->transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
}
$transaction->status = 1;
$transaction->save();
}
if ($inputs['type'] == 3) {
$origin_balance = $origin_wallet->balance;
$origin_balance -= $inputs['amount'];
$origin_total = $origin_wallet->total;
$origin_total -= $inputs['amount'];
$origin_wallet->update(['balance' => $origin_balance - $wage, 'total' => $origin_total - $wage]);
$destination_balance = $destination_wallet->balance;
$destination_balance += $inputs['amount'];
$destination_total = $destination_wallet->total;
$destination_total += $inputs['amount'];
$destination_wallet->update(['total' => $destination_total, 'balance' => $destination_balance]);
$path = '';
if ($request->hasFile('file_image'))
$path = $this->storeFile($request->file('file_image'));
$transaction->src = $path;
$transaction->time_end_deadline = 60;
if (\Auth::user()->userInformation->national_phone_number_code == "+98")
$transaction->transfer_date = Jalalian::now()->addMonths(2);
else
$transaction->transfer_date = Carbon::now()->addMonths(2);
$transaction->status = 1;
$transaction->save();
}
$history = new History();
if ($transaction->status) {
$currency = Wallet::find($inputs['origin'])->currency_id;
$main_wallet = MainWallet::query()->where(['currency_id' => $currency])->first();
$main_wallet->update(['balance' => $main_wallet->balance + $wage, 'total' => $main_wallet->total + $wage]);
$history->action = 'successful transaction';
$history->user_id = \Auth::id();
$history->content = $inputs['amount'] . " "
. Currency::query()->find($origin_wallet->currency_id)->symbol .
" has been transfered to" . $destination_wallet->user->userInformation->first_name .
" " . $destination_wallet->user->userInformation->last_name . "[" . $transaction->transfer_id . "]";
$history->save();
$transfer = [];
$transfer['transfer'] = $transaction;
$transfer['origin'] = $origin_wallet->account_number;
$transfer['origin_info'] = ['user' => $origin_wallet->user, 'info' => $origin_wallet->user->userInformation];
$transfer['destination_info'] = ['user' => $destination_wallet->user, 'info' => $origin_wallet->user->userInformation];
$transfer['destination'] = $destination_wallet->account_number;
$transfer['currency'] = $origin_wallet->currency->symbol;
return redirect()->route('client.message')
->with('transfer_success', __('The transfer done successfully'))
->with('transfer_receipt', $transfer)->ajax();
} else {
$history->action = 'failed transaction';
$history->user_id = \Auth::id();
$history->content = "The transaction failed [" . $transaction->transfer_id . "]";
$history->save();
return response()->json(['error' => __('The transfer failed')], 403);
}
}

Data is not inserted into database using codeigniter

I have a form where user insert their basic details and after submitting form it will redirect on view page. I trying to submit it redirect on view page without inserting data into database. I debug my code of controller I come to know that $request = $this->getRequest(); code in $request I am getting GET [ 1 ] and post is empty and in if condition here used $this->getRequest()->isPost() to check whether that post is true or false. Please find screenshot of code of controller.
Controller function
public function addAction() {
$captcha = new Zend_Session_Namespace('captcha');
$captcha->captcha = session_id();
$request = $this->getRequest();
if ($this->getRequest()->isPost()) {
if ($form->isValidPartial($request->getPost())) {
$dataform = $request->getPost();
$alphabet =
"abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1;
for ($i = 0; $i < 8; $i++) {
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
$randomPassword = implode($pass); //turn the array into a string
$dataform['password'] = $randomPassword;
if ($dataform['vercode'] != $_SESSION["vercode"]) {
$msg = "Please enter a correct code!";
$this->view->assign('errorMessage', $msg);
return FALSE;
}
if ($dataform['sessionCheck'] != $captcha->captcha) {
$this->view->assign('errorMessage', CSRF_ATTACK);
return FALSE;
}
if($dataform['name'] == 2 && $dataform['statename'] == 0){
$this->view->assign('errorMessage', 'Please select state
for the state officials!');
return;
}
$Contactusobj = new Application_Model_User;
$countdata = $Contactusobj-
>checkuserclient($dataform['username']);
$countemail = $Contactusobj-
>checkemail($dataform['email']);
if(($countdata == 0)){
$match = $Contactusobj->insertuserdetails($dataform);
$description = 'Add New User </br>';
if($dataform[name] && $dataform[name] != 0){
$rolename = $Contactusobj-
>getuserrolename($dataform[name]);
$description .= '<span>Role:
</span>'.$rolename.'</br>';
}
if($dataform[ministry_name] && $dataform[ministry_name]
!= 0){
$ministryname = $Contactusobj-
>Getministryname($dataform[ministry_name]);
$description .= '<span>Ministry:
</span>'.$ministryname .'</br>';
}
if($dataform[statename] && $dataform[statename] != 0){
$statename = $Contactusobj-
>getuserstatename($dataform[statename]);
$description .= '<span>State:
</span>'.$statename.'</br>';
}
if($dataform[cityname] && $dataform[cityname] != 0){
$cityname = $Contactusobj-
>getdistrictname($dataform[cityname]);
$description .= '<span>City:
</span>'.$cityname.'</br>';
}
$description .= '<span>User Name:
</span>'.$dataform[username].'</br>';
$description .= '<span>First Name:
</span>'.$dataform[firstname].'</br>';
$description .= '<span>Last Name:
</span>'.$dataform[lastname].'</br>';
$description .= '<span>Email:
</span>'.$dataform[email].'</br>';
$description .= '<span>Mobile:</span>'.$dataform[mobile];
$auditlog = array("uid" => $userid->userid,
"application_type" => 'User',
"description" => $description
);
$auditobj = new Application_Model_Auditlog;
$auditobj->insertauditlog($auditlog);
/***************audit log end by braj***************/
$mailObj = new Zend_Mail();
$username = $dataform['username'];
$fname = ucfirst($dataform['firstname']);
$weblink = WEB_LINK;
$body = MESSAGE_BODY;
$body = str_replace('{user_name}',$username,$body);
$body = str_replace('{fname}',$fname,$body);
$body =
str_replace('{user_password}',$dataform['password'],$body);
$body = str_replace('{web_link}',$weblink,$body);
$subject= MAIL_SUBJECT;
$to =$dataform['email'];
$from =MAIL_FROM;
$name = MAIL_NAME;
$mailObj->setSubject($subject);
$mailObj->setBodyHtml($body);
$mailObj->addTo($to, $name);
$mailObj->setFrom($from,
$name);//print_r($mailObj);die();
$mailObj->send();
$this->_redirect('/user/add?actmsg=add');
}else{
if($countdata){
$this->view->assign('errorMessage', 'Your
username is already exists in the database.');
return;
} }}}}}}}
Model User.php
public function insertuserdetails($dataform) {
$userid = new Zend_Session_Namespace('userid');
$user_table = new Zend_Db_Table('dbt_users');
$date = date("Y-m-d H:i:s");
$datainsert = "";
$datainsert = array(
'state' => $dataform['statename'],
//'cityname'=> $dataform['cityname'],
'ministry_name' => $dataform['ministry_name'],
'username' => $dataform['username'],
'password' => hash_hmac('sha256', $dataform['password'], ''),
'firstname' => $dataform['firstname'],
'lastname' => $dataform['lastname'],
'organisation' => '',
'mobile' => $dataform['mobile'],
'email' => $dataform['email'],
'telephone' => '',
'address' => '',
'role' => $dataform['name'],
'upload' => '',
'dateAdded' => $date,
'dateModify' => $date,
'status' => 1,
'created_by' => $userid->userid,
'login_time' => 1,
'tmp_password' => md5(uniqid(rand(), TRUE)) . substr(md5($dataform['username']), 2, 10),
'reset_time' => $date
);
$insertdata = $user_table->insert($datainsert);
return $insertdata; }

How to set key to query result?

I have the following request in Laravel:
$name = Place::where("status", "1", function ($query) use ($request) {
if (($from = $request->get("from"))) {
$query->where('name', 'like', $from . '%');
}
if (($to = $request->get("to"))) {
$query->where('name', 'like', $to . '%');
}
})->orderBy('name', 'desc')->get();
I get result like as:
{
"id": 2,
"name": "Lena"
},
{
"id": 1,
"name": "Baran"
}
How can I set keys for these two result rows? I want to do:
name_one = {
"id": 2,
"name": "Lena"
},
name_two = {
"id": 1,
"name": "Baran"
}
You can try this code
public function getCollectinos()
{
$collection = collect([
['id' => '1', 'product' => 'Chair'],
['id' => '2', 'product' => 'Desk'],
['id' => '3', 'product' => 'Bookcase'],
]);
$grouped = $collection->groupBy(function ($item, $key) {
return 'name_'.$this->number_to_word($item['id']);
});
$array = $grouped->toArray();
dd($array);
}
public function number_to_word( $num = '' )
{
$num = ( string ) ( ( int ) $num );
if( ( int ) ( $num ) && ctype_digit( $num ) )
{
$words = array( );
$num = str_replace( array( ',' , ' ' ) , '' , trim( $num ) );
$list1 = array('','one','two','three','four','five','six','seven',
'eight','nine','ten','eleven','twelve','thirteen','fourteen',
'fifteen','sixteen','seventeen','eighteen','nineteen');
$list2 = array('','ten','twenty','thirty','forty','fifty','sixty',
'seventy','eighty','ninety','hundred');
$list3 = array('','thousand','million','billion','trillion',
'quadrillion','quintillion','sextillion','septillion',
'octillion','nonillion','decillion','undecillion',
'duodecillion','tredecillion','quattuordecillion',
'quindecillion','sexdecillion','septendecillion',
'octodecillion','novemdecillion','vigintillion');
$num_length = strlen( $num );
$levels = ( int ) ( ( $num_length + 2 ) / 3 );
$max_length = $levels * 3;
$num = substr( '00'.$num , -$max_length );
$num_levels = str_split( $num , 3 );
foreach( $num_levels as $num_part )
{
$levels--;
$hundreds = ( int ) ( $num_part / 100 );
$hundreds = ( $hundreds ? ' ' . $list1[$hundreds] . ' Hundred' . ( $hundreds == 1 ? '' : 's' ) . ' ' : '' );
$tens = ( int ) ( $num_part % 100 );
$singles = '';
if( $tens < 20 )
{
$tens = ( $tens ? ' ' . $list1[$tens] . ' ' : '' );
}
else
{
$tens = ( int ) ( $tens / 10 );
$tens = ' ' . $list2[$tens] . ' ';
$singles = ( int ) ( $num_part % 10 );
$singles = ' ' . $list1[$singles] . ' ';
}
$words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_part ) ) ? ' ' . $list3[$levels] . ' ' : '' );
}
$commas = count( $words );
if( $commas > 1 )
{
$commas = $commas - 1;
}
$words = implode( ', ' , $words );
$words = trim(str_replace( ' ,' , ',' , $this->trim_all( $words ) ) , ', ');
if( $commas )
{
$words = $this->str_replace_last( ',' , ' and' , $words );
}
return $words;
}
else if( ! ( ( int ) $num ) )
{
return 'Zero';
}
return '';
}
public function str_replace_last( $search , $replace , $str )
{
if( ( $pos = strrpos( $str , $search ) ) !== false ) {
$search_length = strlen( $search );
$str = substr_replace( $str , $replace , $pos , $search_length );
}
return $str;
}
public function trim_all( $str , $what = NULL , $with = ' ' )
{
if( $what === NULL )
{
// Character Decimal Use
// "\0" 0 Null Character
// "\t" 9 Tab
// "\n" 10 New line
// "\x0B" 11 Vertical Tab
// "\r" 13 New Line in Mac
// " " 32 Space
$what = "\\x00-\\x20"; //all white-spaces and control chars
}
return trim( preg_replace( "/[".$what."]+/" , $with , $str ) , $what );
}
Output :
you can do a keyBy('name'); after the get() function lookup keyBy example below
$collection = collect([
['product_id' => 'prod-100', 'name' => 'desk'],
['product_id' => 'prod-200', 'name' => 'chair'],
]);
$keyed = $collection->keyBy('product_id');
$keyed->all();
/*
[
'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]
*/

Magento How to update bundle product programmatically

I am reading product sku from csv file and my csv file contains bundle product sku. I am traversing through csv data and for each bundle sku I want to add bundle items inside it which I am passing through CSV
Here is the code what I have done
ini_set('auto_detect_line_endings', TRUE);
$magentoPath = getcwd();
require_once ($magentoPath . '/includes/config.php');
require_once ($magentoPath . '/app/Mage.php');
Mage::app();
//read the csv
$bundleCsv = Mage::getBaseDir('var').'/import/bundleImport.csv';
$rows = array_map('str_getcsv', file($bundleCsv));
$header = array_shift($rows);
$csv = array();
foreach ($rows as $row) {
$csv[] = array_combine($header, $row);
}
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
echo Mage::app()->getStore()->getId(); exit;
foreach( $csv as $key => $val ){
if( !isset($val['sku']) || empty($val['sku']) || $val['sku'] == '' ){
echo 'Not Valid Sku';
continue;
}
$_product = Mage::getModel('catalog/product')->loadByAttribute('sku',$val['sku']);
$opt = $val['bundle_options'];
$optArr = explode(':', $opt);
$bundleOptions = array();
$bundleSelections = array();
foreach ( $optArr as $key1 => $val1 ) {
$valTemp = explode( '(', $val1 );
$title = trim($valTemp[0]);
$bundleSub[$key1] = array(
'title' => $title, // option title
'option_id' => $key1,
'delete' => '',
'type' => 'select', // option type
'required' => '1', // is option required
'position' => '1' // option position
);
$skuStr = trim($valTemp[1]);
$skuStrTemp = explode( ')', $skuStr );
$skuStr = trim($skuStrTemp[0]);
$skuTemp = explode( '+', $skuStr );
foreach( $skuTemp as $key2 => $val2 ){
$product = Mage::getModel('catalog/product');
$id = Mage::getModel('catalog/product')->getResource()->getIdBySku($val2);
if( $id ){
$bundleSelectionsSub[$key2] = array ( // selection ID of the option (first product under this option (option ID) would have ID of 0, second an ID of 1, etc)
'product_id' => $id, // if of a product in selection
'delete' => '',
'selection_price_value' => '10',
'selection_price_type' => 0,
'selection_qty' => 1,
'selection_can_change_qty' => 0,
'position' => 0,
'is_default' => 1
);
$product = null;
}else{
continue;
}
}
$bundleSelections[$key1] = $bundleSelectionsSub;
}
$bundleOptions = $bundleSub;
//echo '<pre>'; print_r($bundleOptions); exit;
try{
$_product->setCanSaveCustomOptions ( true );
$_product->setCanSaveBundleSelections ( true );
$_product->setAffectBundleProductSelections ( true );
$_product->setBundleOptionsData ( $bundleOptions );
$_product->setBundleSelectionsData ( $bundleSelections );
$_product->save();
}catch ( Exception $e ) {
Mage::log ( $e->getMessage () );
echo $e->getMessage ();
}
echo 1; exit;
$_product = null;
}
But this gives me following error as
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`aero_dev`.`catalog_product_bundle_option_value`, CONSTRAINT `FK_CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID` FOREIGN KEY (`option_id`) REFERENCES `catalog_product_bundle_option` (`opt), query was: INSERT INTO `catalog_product_bundle_option_value` (`option_id`, `store_id`, `title`) VALUES (?, ?, ?)
Any help would be appreciated.
I could not get it working using above approach so I tried to write custom query to put bundle items in the existing bundle product. When I looked into db I found there are basically 3 tables involved to create bundle items. These are
catalog_product_bundle_option
catalog_product_bundle_option_value
catalog_product_bundle_selection
I went through these tables and tried to looked for what magento puts If I create bundle items from magento admin.
So after some research I have done something like -
foreach( $csv as $key => $val ){
if( !isset($val['sku']) || empty($val['sku']) || $val['sku'] == '' ){
echo 'Not Valid Sku';
continue;
}
$_product = Mage::getModel('catalog/product')->loadByAttribute('sku',trim($val['sku']));
$_product->setCanSaveCustomOptions ( true );
$_product->setCanSaveBundleSelections ( true );
$_product->setAffectBundleProductSelections ( true );
$opt = $val['bundle_options'];
$optArr = explode(':', $opt);
//get the db write connection
$connection = Mage::getSingleton('core/resource')->getConnection('core_write');
$connection->beginTransaction();
foreach ( $optArr as $key1 => $val1 ) {
$valTemp = explode( '(', $val1 );
$title = trim($valTemp[0]);
//insert into catalog_product_bundle_option with parent product id and type
$__fields = array();
$__fields['parent_id'] = $_product->getId();
$__fields['required'] = 1;
$__fields['type'] = 'select';
$__fields['position'] = $key1+1;
$connection->insert($catalog_product_bundle_option, $__fields);
$opt_id = $connection->lastInsertId();
$connection->commit();
//inert into catalog_product_bundle_option_value with option id, store id, title
$__fields = array();
$__fields['option_id'] = $opt_id;
$__fields['store_id'] = 0;
$__fields['title'] = $title;
$connection->insert($catalog_product_bundle_option_value, $__fields);
$val_id = $connection->lastInsertId();
$connection->commit();
$skuStr = trim($valTemp[1]);
$skuStrTemp = explode( ')', $skuStr );
$skuStr = trim($skuStrTemp[0]);
$skuTemp = explode( '+', $skuStr );
$pos = 1;
foreach( $skuTemp as $key2 => $val2 ){
$id = Mage::getModel('catalog/product')->getResource()->getIdBySku($val2);
//insert into catalog_product_bundle_selection with option_id, parent product id, product id, position, is_default, selection_price_type, selection_price_value, selection_qty, selection_can_change_qty
$__fields = array();
$__fields['option_id'] = $opt_id;
$__fields['parent_product_id'] = $_product->getId();
$__fields['product_id'] = $id;
$__fields['position'] = $pos + 1;
$__fields['selection_price_type'] = 0;
$__fields['selection_price_value'] = 10;
$__fields['selection_qty'] = 1;
$__fields['selection_can_change_qty'] = 0;
$connection->insert($catalog_product_bundle_selection, $__fields);
$connection->commit();
$pos++;
}
}
//update product
$_product->save();
$_product = null;
}
my csv contains 2 columns one is sku and another is bundle options
example - sku - 12345678
bundle options - item01(ZIPLOCK18X24+ZIPLOCK16X20):item02(ZIPLOCK14X20+XEROMOCR84208X11)
in which item01 is the option title followed by simple products sku ZIPLOCK18X24, ZIPLOCK16X20 and : seperated incase of multiple options title.
I hope it may help someone.

Exporting and Importing Attributes in Magento

I would love a script or magento extension to allow me to export all the product attributes including values for drop down attributes. Importing would be good too, I've had a look but can't seem to find anything does anyone know how this can be done?
Update: I found a working script in stackexchange and the script worked exactly as it should. All credits to the original poster. I am just copy pasting his reply here for future reference. Link to the original thread: is here.
I've done this to export all attributes and their options (if it is a dropdown attribute) from the source website:
exportAttributes.php in root directory of source website:
<?php
define('MAGENTO', realpath(dirname(__FILE__)));
require_once MAGENTO . '/app/Mage.php';
Mage::app();
$entity_type_id = Mage::getModel('catalog/product')->getResource()->getTypeId();
prepareCollection($entity_type_id);
function prepareCollection($ent_type_id){
$resource = Mage::getSingleton('core/resource');
$connection = $resource->getConnection('core_read');
$select_attribs = $connection->select()
->from(array('ea'=>$resource->getTableName('eav/attribute')))
->join(array('c_ea'=>$resource->getTableName('catalog/eav_attribute')), 'ea.attribute_id = c_ea.attribute_id');
// ->join(array('e_ao'=>$resource->getTableName('eav/attribute_option'), array('option_id')), 'c_ea.attribute_id = e_ao.attribute_id')
// ->join(array('e_aov'=>$resource->getTableName('eav/attribute_option_value'), array('value')), 'e_ao.option_id = e_aov.option_id and store_id = 0')
$select_prod_attribs = $select_attribs->where('ea.entity_type_id = '.$ent_type_id)
->order('ea.attribute_id ASC');
$product_attributes = $connection->fetchAll($select_prod_attribs);
$select_attrib_option = $select_attribs
->join(array('e_ao'=>$resource->getTableName('eav/attribute_option'), array('option_id')), 'c_ea.attribute_id = e_ao.attribute_id')
->join(array('e_aov'=>$resource->getTableName('eav/attribute_option_value'), array('value')), 'e_ao.option_id = e_aov.option_id and store_id = 0')
->order('e_ao.attribute_id ASC');
$product_attribute_options = $connection->fetchAll($select_attrib_option);
$attributesCollection = mergeCollections($product_attributes, $product_attribute_options);
prepareCsv($attributesCollection);
}
function mergeCollections($product_attributes, $product_attribute_options){
foreach($product_attributes as $key => $_prodAttrib){
$values = array();
$attribId = $_prodAttrib['attribute_id'];
foreach($product_attribute_options as $pao){
if($pao['attribute_id'] == $attribId){
$values[] = $pao['value'];
}
}
if(count($values) > 0){
$values = implode(";", $values);
$product_attributes[$key]['_options'] = $values;
}
else{
$product_attributes[$key]['_options'] = "";
}
/*
temp
*/
$product_attributes[$key]['attribute_code'] = $product_attributes[$key]['attribute_code'];
}
return $product_attributes;
}
function prepareCsv($attributesCollection, $filename = "importAttrib.csv", $delimiter = '|', $enclosure = '"'){
$f = fopen('php://memory', 'w');
$first = true;
foreach ($attributesCollection as $line) {
if($first){
$titles = array();
foreach($line as $field => $val){
$titles[] = $field;
}
fputcsv($f, $titles, $delimiter, $enclosure);
$first = false;
}
fputcsv($f, $line, $delimiter, $enclosure);
}
fseek($f, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachement; filename="'.$filename.'"');
fpassthru($f);
}
This will give a csv file [actually i used "|" to separate ;)]
paste this csv file in MAGENTO_ROOT/attribImport directory of the destination website, i.e. website to which attributes need to be imported:
now put the following code in MAGENTO_ROOT/attribImport** directory
of the destination website
<?php
define('MAGENTO', realpath(dirname(__FILE__)));
require_once MAGENTO . '/../app/Mage.php';
Mage::app();
// $fileName = MAGENTO . '/var/import/importAttrib.csv';
$fileName = 'importAttrib.csv';
// getCsv($fileName);
getAttributeCsv($fileName);
function getAttributeCsv($fileName){
// $csv = array_map("str_getcsv", file($fileName,FILE_SKIP_EMPTY_LINES));
$file = fopen($fileName,"r");
while(!feof($file)){
$csv[] = fgetcsv($file, 0, '|');
}
$keys = array_shift($csv);
foreach ($csv as $i=>$row) {
$csv[$i] = array_combine($keys, $row);
}
foreach($csv as $row){
$labelText = $row['frontend_label'];
$attributeCode = $row['attribute_code'];
if($row['_options'] != "")
$options = explode(";", $row['_options']); // add this to createAttribute parameters and call "addAttributeValue" function.
else
$options = -1;
if($row['apply_to'] != "")
$productTypes = explode(",", $row['apply_to']);
else
$productTypes = -1;
unset($row['frontend_label'], $row['attribute_code'], $row['_options'], $row['apply_to'], $row['attribute_id'], $row['entity_type_id'], $row['search_weight']);
createAttribute($labelText, $attributeCode, $row, $productTypes, -1, $options);
}
}
/**
* Create an attribute.
*
* For reference, see Mage_Adminhtml_Catalog_Product_AttributeController::saveAction().
*
* #return int|false
*/
function createAttribute($labelText, $attributeCode, $values = -1, $productTypes = -1, $setInfo = -1, $options = -1)
{
$labelText = trim($labelText);
$attributeCode = trim($attributeCode);
if($labelText == '' || $attributeCode == '')
{
echo "Can't import the attribute with an empty label or code. LABEL= [$labelText] CODE= [$attributeCode]"."<br/>";
return false;
}
if($values === -1)
$values = array();
if($productTypes === -1)
$productTypes = array();
if($setInfo !== -1 && (isset($setInfo['SetID']) == false || isset($setInfo['GroupID']) == false))
{
echo "Please provide both the set-ID and the group-ID of the attribute-set if you'd like to subscribe to one."."<br/>";
return false;
}
echo "Creating attribute [$labelText] with code [$attributeCode]."."<br/>";
//>>>> Build the data structure that will define the attribute. See
// Mage_Adminhtml_Catalog_Product_AttributeController::saveAction().
$data = array(
'is_global' => '0',
'frontend_input' => 'text',
'default_value_text' => '',
'default_value_yesno' => '0',
'default_value_date' => '',
'default_value_textarea' => '',
'is_unique' => '0',
'is_required' => '0',
'frontend_class' => '',
'is_searchable' => '1',
'is_visible_in_advanced_search' => '1',
'is_comparable' => '1',
'is_used_for_promo_rules' => '0',
'is_html_allowed_on_front' => '1',
'is_visible_on_front' => '0',
'used_in_product_listing' => '0',
'used_for_sort_by' => '0',
'is_configurable' => '0',
'is_filterable' => '0',
'is_filterable_in_search' => '0',
'backend_type' => 'varchar',
'default_value' => '',
'is_user_defined' => '0',
'is_visible' => '1',
'is_used_for_price_rules' => '0',
'position' => '0',
'is_wysiwyg_enabled' => '0',
'backend_model' => '',
'attribute_model' => '',
'backend_table' => '',
'frontend_model' => '',
'source_model' => '',
'note' => '',
'frontend_input_renderer' => '',
);
// Now, overlay the incoming values on to the defaults.
foreach($values as $key => $newValue)
if(isset($data[$key]) == false)
{
echo "Attribute feature [$key] is not valid."."<br/>";
return false;
}
else
$data[$key] = $newValue;
// Valid product types: simple, grouped, configurable, virtual, bundle, downloadable, giftcard
$data['apply_to'] = $productTypes;
$data['attribute_code'] = $attributeCode;
$data['frontend_label'] = array(
0 => $labelText,
1 => '',
3 => '',
2 => '',
4 => '',
);
//<<<<
//>>>> Build the model.
$model = Mage::getModel('catalog/resource_eav_attribute');
$model->addData($data);
if($setInfo !== -1)
{
$model->setAttributeSetId($setInfo['SetID']);
$model->setAttributeGroupId($setInfo['GroupID']);
}
$entityTypeID = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
$model->setEntityTypeId($entityTypeID);
$model->setIsUserDefined(1);
//<<<<
// Save.
try
{
$model->save();
}
catch(Exception $ex)
{
echo "Attribute [$labelText] could not be saved: " . $ex->getMessage()."<br/>";
return false;
}
if(is_array($options)){
foreach($options as $_opt){
addAttributeValue($attributeCode, $_opt);
}
}
$id = $model->getId();
echo "Attribute [$labelText] has been saved as ID ($id).<br/>";
// return $id;
}
function addAttributeValue($arg_attribute, $arg_value)
{
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
$attribute = $attribute_model->load($attribute_code);
if(!attributeValueExists($arg_attribute, $arg_value))
{
$value['option'] = array($arg_value,$arg_value);
$result = array('value' => $value);
$attribute->setData('option',$result);
$attribute->save();
}
$attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ;
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
foreach($options as $option)
{
if ($option['label'] == $arg_value)
{
return $option['value'];
}
}
return false;
}
function attributeValueExists($arg_attribute, $arg_value)
{
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_options_model= Mage::getModel('eav/entity_attribute_source_table') ;
$attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
$attribute = $attribute_model->load($attribute_code);
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
foreach($options as $option)
{
if ($option['label'] == $arg_value)
{
return $option['value'];
}
}
return false;
}
NOTE: Allthough exceptions have been handled, Backup your Database
before you import these attributes, to be on safer side. Happy
Importing!
Thanks to :
Programatically create attribute in Magento, useful for the “on the fly” import system
programmatically_adding_attributes_and_attribute_sets
Magento – Programmatically insert new attribute option
I would recommend Boris's uRapidFlow: http://www.unirgy.com/products/urapidflow/ It's one of the better Data Flow Import/Export modules available. Be aware however it does require IonCube Loader, but it is well worth it if you are moving data around a lot.

Resources