Carrinho de compras com yii

Alguem ja fez algum carrinho de compras com yii, que poderia compartilhar, ou ate mesmo me ajudar como posso fazer de uma maneira bem simples com o yii.

Tipo eu tenho que fazer um sistema de pedido que o usuario visualiza o catalago acrecenta o seu pedido no carrinho e depois finaliza enviando informaçao como codigo do produto, nome descricao, e quantidade.

Se alguem ja fez ou tem alguma ideia posta ahi o codigo…

Valews

Cara, da uma olhada nessa extensão:

http://www.yiiframework.com/extension/yiishop

Eu nunca usei, mas pela descrição parece ter uma implementação de um carrinho de compras. Talvez não sirva para você, mas pode te ajudar com ideias.

Tipo esta extensao é muito complexa, ha documentaçao é muito basica. Será que alguem nunca fez isso no yii ou alguem poderia ter outra ideia.Tipo tem varios lugares que falam de sessão niguem fez iso no yii para que possa me ajudar?

Edson,

Faz o seguinte, todo pedido feito, tu terá que salvar no banco de dados, para diferenciar um cliente do outro, na tabela ‘carrinho’ ou qualquer outro nome que tu desejar, cria uma coluna ‘session’, nela você vai guardar a $_SESSION[‘PHPSESSID’] ai na página do carrinho no próprio site, tu lista os produto/pedido daquela session.

Até ae tudo bem, ao nos controller, pelos actions() que você vai fazer a inserção do pedidos, alteração, e remoção.

Aguarda mais um pouco caso não tenha achado a solução, chegando em casa hoje no final do dia, eu envio meu script aqui no fórum.

Eu fiz um de pedido online para Representantes de Sementes de Pastagem.

He isso mesmo que eu preciso tenho que fazer um esquema de pedido, estao vou aguardar o script que vc fez…

Mais aguadeço desde já…

O que o Newerton disse nem é difícil de implementar por vc mesmo …

é só usar a sessão como está no exemplo abaixo pra salvar e recuperar valores.

http://www.yiiframework.com/doc/api/1.1/CHttpSession

http://code.google.com/p/yiiext/source/browse/trunk/app/extensions/yiiext/components/shoppingCart/readme_en.txt?r=352

Ow meu irmãos foi mal ae, estava transição da internet aqui e por causa do trampo.

Abaixo segue o que eu fiz:

[sql]CREATE TABLE IF NOT EXISTS carrinho (

codcarrinho int(8) NOT NULL,

codproduto varchar(120) NOT NULL,

quant int(8) NOT NULL,

sessao varchar(27) NOT NULL,

PRIMARY KEY (codcarrinho)

) ENGINE=MyISAM DEFAULT CHARSET=latin1;

[/sql]

CarrinhoController.php




/**

 * Ação que faz a atualização das quantidades de produtos(cada item).

 */

public function actionUpdatebasket() {


        $session = Yii::app()->request->cookies['PHPSESSID']->value;


        foreach ($_POST["quant"] as $key => $value) {

            $model = Carrinho::model()->findByPk($key);

            $model->quant = $value;

            $model->save(false);

        }

        $this->redirect(Yii::app()->createUrl('carrinho'));

    }


/**

 * Ação que somente faz é guardar o pedido

 */


public function actionEnviarpedido() {


        $model = new Carrinho('search');

        $cliente = new CLIENTE;

        $transportadora = new TRANSPOR;

        $vencimento = new VENCIMENTO;


		/**

		 * Resetar os campos que estão com validação obrigatorio, e não foi utilizado no formulário

		 */

		$_POST['Carrinho']['codcarrinho'] = 0;

		$_POST['Carrinho']['quant'] = 0;

		$_POST['Carrinho']['pesosaca'] = 0;

		$_POST['Carrinho']['valorunitario'] = 0;

		$_POST['Carrinho']['vc'] = 0;

		$_POST['CLIENTE']['filial'] = 0;

		$_POST['CLIENTE']['grupo'] = 0;

		$_POST['CLIENTE']['comis'] = 0;

		$_POST['CLIENTE']['cobtaxa'] = 0;

		$_POST['CLIENTE']['inadimplente'] = 0;

		$_POST['CLIENTE']['situacao'] = 0;

		$_POST['VENCIMENTO']['deslocamento'] = 0;

		$_POST['VENCIMENTO']['duplicata'] = 0;

		

        $this->performAjaxValidation(array($model, $cliente, $transportadora, $vencimento));




        $cliente = CLIENTE::model()->findByPk($_POST['CLIENTE']["codcliente"]);

        $fazenda = FAZENDA::model()->findByPk($_POST['CLIENTE']["codcliente"]);

        $transportadora = TRANSPOR::model()->findByPk($_POST['TRANSPOR']["codtranspor"]);

        //$vencimento = VENCIMENTO::model()->findByPk($_POST["Carrinho"]["codvencimento"]);


        $rebanho = empty($cliente->rebanho) ? 0 : $cliente->rebanho;

        $fax = ($cliente->fax == '(  )     -    ') ? '' : $cliente->fax;


        /**

         * Formatando a data no formado MM/dd/yyyy

         */

        $dataentrega = CDateTimeParser::parse($_POST["Carrinho"]["dataentrega"], 'dd/MM/yyyy');

        $dataentrega = Yii::app()->dateFormatter->format('MM/dd/yyyy', $dataentrega);


        /**

         * Formatando o frete, para que não vai ponto(.)

         */

        $frete = number_format($_POST["Carrinho"]["frete"], 2, '.', '');

        /**

         * Formatar a tranportadora, limit de 30

         */

        $transportadora = substr($transportadora->nome, 0, 30);

        $sql = "EXECUTE PROCEDURE INSERE_PEDIDOS ('1','0','" . Yii::app()->user->codrepresentante . "','{$cliente->nome}','{$cliente->codcliente}','{$fazenda->nome}','{$fazenda->uf}',";

        $sql .= "'{$fazenda->cidade}','NULL','NULL','{$cliente->cpf}','NULL','{$cliente->endereco}','{$cliente->bairro}','{$cliente->uf}',";

        $sql .= "'{$cliente->cidade}','{$cliente->cep}','NULL','{$cliente->fone}','NULL','{$rebanho}','$transportadora',";

        $sql .= "'{$frete}','{$dataentrega}','0','F','{$_POST["Carrinho"]["localentrega"]}','{$_POST["VENCIMENTO"]["codvencimento"]}','{$_POST["Carrinho"]["observacao"]}','T','NULL');";


		//echo $sql;

        //exit();


        /**

         * Estanciando a inserção do PEDIDO

         */

        $dbh = ibase_connect(Yii::app()->params['hostFirebird'], Yii::app()->params['usernameFirebird'], Yii::app()->params['passwordFirebird']);

        $sth = ibase_query($dbh, $sql) or die(ibase_errmsg());

        $row = ibase_fetch_assoc($sth);

        $codpedido_firebird = $row["PEDIDO"];

        //print_r($row["PEDIDO"]);

		//exit();


        $session = Yii::app()->request->cookies['PHPSESSID']->value;

        $produtos = Carrinho::model()->findAll(array('condition'=>"sessao = '{$session}'"));

		

        foreach($produtos as $produto){

            $sql = "EXECUTE PROCEDURE INSERE_ITENS ('{$codpedido_firebird}','{$produto->codproduto}','{$produto->vc}','{$produto->pesosaca}','{$produto->quant}','{$produto->valorunitario}');";

            $sth = ibase_query($dbh, $sql) or die(ibase_errmsg());

			

            /**

             * Inserindo no banco MYSQL

             */

            $pedido = new Pedido;

            $codpedido = Yii::app()->db->createCommand("SELECT MAX(codpedido) FROM pedido")->queryScalar() + 1;

			

            $pedido->codpedido = $codpedido;

            $pedido->codcliente = $cliente->codcliente;

            $pedido->codrepresentante = Yii::app()->user->codrepresentante;

            $pedido->codproduto = $produto->codproduto;

            $pedido->idpedido = $codpedido_firebird;

            $pedido->quant = $produto->quant;

            $pedido->pesosaca = $produto->pesosaca;

            $pedido->valorunitario = $produto->valorunitario;

            $pedido->vc = $produto->vc;

            $pedido->codusuario = Yii::app()->user->codusuario;

            $pedido->datacriacao = date('Y-m-d H:i:s');

            $pedido->save(false);

        }

        

        

        Carrinho::model()->deleteAll(array('condition'=>"sessao = '{$session}'"));

        $this->redirect(Yii::app()->createUrl('pedido', array('alerta'=>'enviado')));


    }



ProdutoController.php (Original: CULTIVARController.php) *Cultivar é um nome que deram para as sementes.




public function actionBasket() {


        $id = utf8_decode($_GET["id"]);

        $session = Yii::app()->request->cookies['PHPSESSID']->value;

        $model = Carrinho::model()->find(array('condition' => "sessao = '{$session}' AND codproduto = '{$id}'"));

        $produto = count($model);


        if ($produto > 0) {

            $model->quant += 1;

            $model->save(false);

        } else if ($produto == 0) {


            $lastResult = 'SELECT MAX(codcarrinho) FROM carrinho';

            $lastResult = (int) Yii::app()->db->createCommand($lastResult)->queryScalar() + 1;

            

            $carrinho = new Carrinho;

            $carrinho->codcarrinho = $lastResult;

            $carrinho->codproduto = $id;

            $carrinho->quant = (int) 1;

            $carrinho->sessao = $session;

            $carrinho->save(false);

        }


        echo count(Carrinho::model()->findAll(array('condition'=>"sessao = '$session'")));

        //$this->redirect(Yii::app()->createUrl('cultivar'));

    }



views\carrinho\index.php




<?php

Html::css(array('form.css', 'forms/' . controller() . '.css'));

echo CHtml::scriptFile(app()->baseUrl . '/js/form.php');

$session = Yii::app()->request->cookies['PHPSESSID']->value;


$this->breadcrumbs = array(

    'Carrinhos' => 'index',

    'Listagem'

);


$this->beginWidget('CActiveForm', array(

    'method' => 'post',

    'action' => Yii::app()->createUrl(controller() . '/updatebasket'),

    'enableAjaxValidation' => false,

));

?>


<?php

echo '<div align="right">';

echo CHtml::htmlButton('<img src="' . app()->baseUrl . '/images/icones/arrow-circle-double.png" align="absmiddle"> Atualizar', array(

    'class' => 'botao botaoAzul',

    'onclick' => "location.href = '" . url('updatebasket') . "'"

));

echo '</div>';

$this->widget('zii.widgets.grid.CGridView', array(

    'id' => 'table-grid',

    'dataProvider' => $model->search(),

    'filter' => $model,

    'selectableRows' => 0,

    'rowCssClass' => array('tdLinhaCinza', 'tdLinhaBranca'),

    'columns' => array(

        array(

            'name' => 'codproduto',

            'filter' => false,

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'name' => 'quant',

            'type' => 'raw',

            'filter' => false,

            'value' => 'CHtml::textField("quant[$data->primaryKey]", $data->quant, array(\'class\'=>\'input w50px\', \'style\'=>\'text-align:center\'))',

            'headerHtmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center'

            ),

        ),

        array(

            'name' => 'Unidade',

            'filter' => false,

            'value' => 'ARTIGO::model()->findByPk(CULTIVAR::model()->find(array(\'condition\' => "nome = \'$data->codproduto\'"))->especie)->unidade',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center'

            ),

        ),

        array(

            'name' => 'pesosaca',

            'type' => 'raw',

            'filter' => false,

            'value' => 'CHtml::textField("pesosaca[$data->primaryKey]", $data->pesosaca, array(\'class\'=>\'input w50px\', \'style\'=>\'text-align:center\'))',

            'headerHtmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center'

            ),

        ),

        array(

            'name' => 'valorunitario',

            'type' => 'raw',

            'filter' => false,

            'value' => 'CHtml::textField("valorunitario[$data->primaryKey]", $data->valorunitario, array(\'class\'=>\'input w50px\', \'style\'=>\'text-align:center\'))',

            'headerHtmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center'

            ),

        ),

        array(

            'name' => 'vc',

            'type' => 'raw',

            'filter' => false,

            'value' => 'CHtml::textField("vc[$data->primaryKey]", $data->vc, array(\'class\'=>\'input w50px\', \'style\'=>\'text-align:center\'))',

            'headerHtmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center'

            ),

        ),

        array(

            'class' => 'CButtonColumn',

            'header' => 'Opções',

            'template' => '{delete}',

            'deleteButtonLabel' => '<img src=\'' . app()->baseUrl . '/images/icones/cross-circle.png\' align=\'absmiddle\'> Remover',

            'deleteButtonImageUrl' => false,

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'width' => '10%',

                'class' => 'ui-widget-header last',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center',

            ),

        ),

    ),

));

?>

<div align="right">

    <?php

    echo CHtml::htmlButton('<img src="' . app()->baseUrl . '/images/icones/arrow-circle-double.png" align="absmiddle"> Atualizar', array(

        'class' => 'botao botaoAzul',

        'name' => 'acao',

        'value' => 'atualizar',

        'type' => 'submit',

    ));

    ?>

</div>

<?php $this->endWidget(); ?>


<?php

    $produtos = count(Carrinho::model()->findAll(array('condition' => "sessao = '{$session}'")));

    if ($produtos > 0) {

        echo $this->renderPartial('_form', array('model' => $model, 'cliente' => $cliente, 'transportadora' => $transportadora, 'vencimento' => $vencimento));

    }

?>



views\carrinho\_form.php




<?php

Html::css(array('form.css', 'forms/' . controller() . '.css'));

//Html::js(array());


Yii::app()->clientScript->registerScript('jquery', "");

?>

<br />

<div class="flash-notice">

    <?php echo CHtml::image(Yii::app()->baseUrl . '/images/icones/exclamation.png', 'Alerta', array('align' => 'left', 'style' => "margin: 0 6px 0 0")) ?>

    Antes de finalizar o pedido, atualize o Carrinho de Orçamento, qualquer

    quantidade do produto alterada antes de atualizar, não será encaminhada ao

    pedido a quantidade exata mostrada, então, antes de qualquer envio,

    atualize a última vez.

</div>


<?php

    $form = $this->beginWidget('CActiveForm', array(

                'id' => 'index-form',

                'action' => Yii::app()->createUrl('carrinho/enviarpedido'),

                'enableAjaxValidation' => true,

                'clientOptions' => array('validateOnSubmit' => true, 'validateOnChange' => true),

                'htmlOptions' => array(

                    'enctype' => 'multipart/form-data'

                ),

            ));

?>




<?php $this->beginWidget('application.extensions.jui.ETabs', array('name' => 'tabpanel1')); ?>

<?php $this->beginWidget('application.extensions.jui.ETab', array('name' => 'tab1', 'title' => "<img border='0' align='absmiddle' src='" . app()->baseUrl . "/images/icones/application.png' alt=''> Formulário")); ?>


    <div class="form">


        <p class="note"><span class="required">*</span> campos obrigatório.</p>


    <?php //echo $form->errorSummary($model);   ?>


    <div class="row codcliente">

        <?php

        echo $form->labelEx($cliente, 'codcliente');

        $clientes = CLIENTE::model()->findAll(array('condition' => "repre = '" . Yii::app()->user->codrepresentante . "'", 'order' => 'nome ASC'));

        $clientes = CHtml::listData($clientes, 'codcliente', 'nome');

        echo $form->dropDownList($cliente, 'codcliente', $clientes, array('class' => 'select w300px', 'prompt' => 'Selecione um cliente'));

        echo $form->error($cliente, 'codcliente');

        ?>

    </div>

    <div class="row codtranspor">

        <?php

        echo $form->labelEx($transportadora, 'codtranspor');

        $tranportadoras = TRANSPOR::model()->findAll(array('order' => 'nome ASC'));

        $tranportadoras = CHtml::listData($tranportadoras, 'codtranspor', 'nome');

        echo $form->dropDownList($transportadora, 'codtranspor', $tranportadoras, array('class' => 'select w300px', 'prompt' => 'Selecione uma transportadora'));

        echo $form->error($transportadora, 'codtranspor');

        ?>

    </div>

    <div class="row frete">

        <?php

        echo $form->labelEx($model, 'frete');

        echo $form->textField($model, 'frete', array('class' => 'input w100px'));

        echo $form->error($model, 'frete');

        ?>

    </div>

    <div class="row dataentrega">

        <?php

        echo $form->labelEx($model, 'dataentrega');

        $this->widget('zii.widgets.jui.CJuiDatePicker',

                array(

                    'name' => 'Carrinho[dataentrega]',

                    'value' => $_POST["Carrinho"]["dataentrega"],

                    'language' => 'pt-BR',

                    'htmlOptions' => array(

                        'class' => 'input w100px'

                    ),

                    'options' => array(

                        'showOn' => 'both',

                        'buttonImage' => Yii::app()->baseUrl . '/images/icones/calendar.png',

                        'dateFormat' => 'dd/mm/yy',

                        'yearRange' => '-1:+1',

                        'changeMonth' => false,

                        'changeYear' => false,

                    )

                )

        );

        echo $form->error($model, 'dataentrega');

        ?>

    </div>

    <div class="row vencimento">

        <?php

        echo $form->labelEx($vencimento, 'codvencimento');

        $vencimentos = VENCIMENTO::model()->findAll(array('order' => 'nome ASC'));

        $vencimentos = CHtml::listData($vencimentos, 'codvencimento', 'nome');

        echo $form->dropDownList($vencimento, 'codvencimento', $vencimentos, array('class' => 'select w300px', 'prompt' => 'Selecione um vencimento'));

        echo $form->error($vencimento, 'codvencimento');

        ?>

    </div>


    <div class="row observacao">

        <?php

        echo $form->labelEx($model, 'observacao');

        echo $form->textArea($model, 'observacao', array('class' => 'textarea w400px', 'rows' => '10'));

        echo $form->error($model, 'observacao');

        ?>

    </div>


    <div class="row localentrega">

        <?php

        echo $form->labelEx($model, 'localentrega');

        echo $form->textArea($model, 'localentrega', array('class' => 'textarea w400px', 'rows' => '10'));

        echo $form->error($model, 'localentrega');

        ?>

    </div>


    <br clear="all" />

    <div style="margin: 4px 0 0; padding: 4px;" class="ui-widget-header ui-corner-all">

        <?php

        echo CHtml::htmlButton('<img src="' . app()->baseUrl . '/images/icones/mail-send.png" align="absmiddle"> Enviar pedido', array(

            'class' => 'botao botaoVerde',

            'name' => 'acao',

            'value' => 'enviarpedido',

            'type' => 'submit',

        ));

        ?>

    </div>


    <br clear="all" />

</div><!-- form -->


<?php $this->endWidget('application.extensions.jui.ETab'); ?>

<?php $this->endWidget('application.extensions.jui.ETabs'); ?>

<?php $this->endWidget(); ?>



views\produto\index.php (Original: views\cultivar\index.php)




<?php


echo CHtml::scriptFile(app()->baseUrl . '/js/form.php');

$this->breadcrumbs = array(

    'Cultivars' => 'index',

    'Listagem'

);

?>


<?php


Yii::import('application.extensions.FixedCheckBoxColumn');

$this->widget('zii.widgets.grid.CGridView', array(

    'id' => 'table-grid',

    'dataProvider' => $model->search(),

    'filter' => $model,

    'selectableRows' => 0,

    'rowCssClass' => array('tdLinhaCinza', 'tdLinhaBranca'),

    'columns' => array(

        array(

            'name' => 'nome',

            'value' => '$data->nome',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'name' => 'especie',

            'filter' => CHtml::listData(ARTIGO::model()->findAll(), 'codartigo', 'des'),

            'value' => 'ARTIGO::model()->findByPk($data->especie)->des',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'name' => 'Marca',

            'filter' => false,

            'value' => 'MARCA::model()->findByPk(ARTIGO::model()->findByPk($data->especie)->codmarca)->nome',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'name' => 'Unidade',

            'filter' => false,

            'value' => 'ARTIGO::model()->findByPk($data->especie)->unidade',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'name' => 'Grupo',

            'filter' => false,

            'value' => 'GRUPOPRODUTOS::model()->findByPk(ARTIGO::model()->findByPk($data->especie)->grupo)->nome',

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'class' => 'ui-widget-header',

            ),

            'htmlOptions' => array(

                'nowrap' => 'nowrap',

            ),

        ),

        array(

            'class' => 'CButtonColumn',

            'header' => 'Opções',

            'template' => '{carrinho}',

            'buttons' => array(

                'carrinho' => array(

                    'label' => '<img src="' . Yii::app()->baseUrl . '/images/icones/cart_add.png" align="absmiddle"> Adicionar',

                    'url' => 'Yii::app()->controller->createUrl("basket",array("id"=>utf8_encode($data->primaryKey)))',

                    'click' => 'js: function(){

                                     $.ajax({

                                            type:\'GET\',

                                            url:$(this).attr(\'href\'),

                                            beforeSend:function(){

                                                $(\'div[id=table-grid]\').addClass(\'grid-view-loading\');

                                            },

                                            success:function(data) {

                                                    $(\'span[id=quantProdutosCarrinho]\').html(data);

                                                    $(\'div[id=table-grid]\').removeClass(\'grid-view-loading\');

                                            }

                                    });

                                    return false;


                                }',

                ),

            ),

            'headerHtmlOptions' => array(

                'nowrap' => 'nowrap',

                'width' => '10%',

                'class' => 'ui-widget-header last',

            ),

            'htmlOptions' => array(

                'width' => '10%',

                'nowrap' => 'nowrap',

                'align' => 'center',

            ),

        ),

    ),

));

?>



[color="#FF0000"][size="5"]Se tiver faltando dados me avisa que eu mando, não me atentei a remover meus código próprio senão ia demorar, pena que está conectando em firebird(lixo), senão eu compactava e enviava, abaixo ta um print de como fico.[/size][/color]

Cara muito bom o seu codigo, valeu mesmo vou dar um estudada…

Mais valeu messs

Desculpa reabrir o tópico, mas achei melhor do que criar um novo.

Estou passando por uma tarefa semelhante, a criação de um carrinho de compras.

Gostaria de saber mais em relação a segurança que podemos incrementar em uma aplicação desse tipo.

Por exemplo, as sessões, sabemos que existem maneiras de rouba-las.

O que vocês fazem para a aplicação?

kdz,

Eu eliminei o uso de SESSION por segurança, e por uma atualização do Yii que quando chamo logout/login ele limpava a sessão, o que fazia que toda vez que o cliente colocava as compras no carrinho, ele perdia todos os produtos do carrinho quando fazia o login/logout.

Comeceu a usar o setState() do Yii, peguei o modelo de uma extensão

http://www.yiiframework.com/extension/yiishop/

Vou postar abaixo de como fiz, as vezes alguem pode melhorar o código.

controller: IndexController.php




public function actionLogin() {


        $this->pageTitle = pageTitle('Login');


        $login = new FormLogin;


        if (isset($_POST['FormLogin'])) {

            $login->attributes = $_POST['FormLogin'];


            if ($login->login()) {

                Yii::app()->user->setFlash('success', 'Login efetuado com sucesso!');

                $cart = Shop::getCartContent();

                if (count($cart) > 0)

                    $this->redirect(Yii::app()->createAbsoluteUrl('carrinho'));

                else

                    $this->redirect(Yii::app()->createAbsoluteUrl('painel'));

            } else {

                Yii::app()->user->setFlash('login-error', 'Usuário e/ou senha inválido.');

                $this->redirect(Yii::app()->createAbsoluteUrl('index/acesso'));

            }

        } else {

            $this->redirect(Yii::app()->createAbsoluteUrl('index/acesso'));

        }

    }


public function actionLogout() {

        $cart = Shop::getCartContent();

        Yii::app()->user->logout(false);

        Shop::setCartContent($cart);

        $this->redirect(Yii::app()->createUrl('index/acesso'));

    }



class: Shop.php




class Shop {


   public static function getCartContent() {

        if (is_string(Yii::app()->user->getState('carrinho')))

            return json_decode(Yii::app()->user->getState('carrinho'), true);

        else

            return Yii::app()->user->getState('carrinho');

    }


    public static function setCartContent($cart) {

        return Yii::app()->user->setState('carrinho', json_encode($cart));

    }


}



controller: CarrinhoController.php





class CarrinhoController extends Controller {


    private $_model;


    public function actionIndex() {


        $this->pageTitle = pageTitle('Meu Carrinho');


        $model = new Carrinho('shoppingCart');

        $model->unsetAttributes();  // clear any default values


        $this->render('index', array(

            'model' => $model,

        ));

    }


    public function actionAdicionar() {


        $id = (int) base64_decode($_GET["f"]);


        $cart = Shop::getCartContent();

        $cart[] = array('codproduto' => $id, 'quantidade' => 1);


        Shop::setCartcontent($cart);

        $this->redirect(Yii::app()->createAbsoluteUrl('carrinho/index'), true);

    }


    public function actionAtualizar() {


        $cart = Shop::getCartContent();


        if (count($cart) > 0) {

            echo '<div id="produto-carrinho">Meu carrinho: <a href="' . Yii::app()->createAbsoluteUrl('carrinho') . '"><span class="txtCinzao txtBold">' . count($cart) . ' produto(s)</span></a>.</div>';

        }

    }


    public function actionQuantidade() {


        $cart = Shop::getCartContent();


        $itens = urldecode($_GET['itens']);

        $a = explode('&', $itens);

        $i = 0;

        while ($i < count($a)) {

            $b = preg_split('/=/', $a[$i]);

            $position = (int) preg_replace('/quantidade\[|\]/', '', htmlspecialchars(urldecode($b[0])));

            $valor = (int) htmlspecialchars(urldecode($b[1]));


            if (isset($cart[$position]['quantidade']))

                $cart[$position]['quantidade'] = $valor;


            $i++;

        }


        Shop::setCartContent($cart);

    }


    public function actionFinalizar() {


        if (Yii::app()->user->isGuest) {

            $this->redirect(Yii::app()->createUrl('index/acesso'), true);

        } else {


            $cart = json_decode(Yii::app()->user->getState('carrinho'), true);


            $pedido = new Pedido;

            $pedido->codpedidostatus = Pedidostatus::model()->find('titulo LIKE :titulo', array(':titulo' => '%pendente%'))->primaryKey;

            $pedido->codcliente = Yii::app()->user->codcliente;

            if ($pedido->validate() && $pedido->save()) {

                foreach ($cart as $key => $value) {

                    $pedidoitem = new Pedidoitem;

                    $pedidoitem->codpedido = $pedido->primaryKey;

                    $pedidoitem->codproduto = $value['codproduto'];

                    $pedidoitem->quant = $value['quantidade'];

                    if($pedidoitem->validate())

                        $pedidoitem->save();

                }

                Yii::app()->user->setState('carrinho', null);

                Yii::app()->user->setFlash('success', 'Orçamento efetuado com sucesso!');

            } else {

                Yii::app()->user->setFlash('error', 'Erro no momento de criar o pedido, tente novamente.');

            }

            

            $this->redirect(Yii::app()->createUrl('painel'), true);

            

        }

    }


    public function actionDelete() {


        $id = (int) $_GET['id'];

        $cart = json_decode(Yii::app()->user->getState('carrinho'), true);

        unset($cart[$id]);

        Yii::app()->user->setState('carrinho', json_encode($cart));

    }


    public function loadModel() {

        if ($this->_model === null) {

            if (isset($_GET['id']))

                $this->_model = Carrinho::model()->findByPk((int) $_GET['id']);

            if ($this->_model === null)

                throw new CHttpException(404, 'The requested page does not exist.');

        }

        return $this->_model;

    }


    protected function performAjaxValidation($model) {

        if (isset($_POST['ajax']) && $_POST['ajax'] === 'index-form') {

            echo CActiveForm::validate($model);

            Yii::app()->end();

        }

    }


}



class: Carrinho.php




class Carrinho extends CActiveRecord {


    public static function model($className = __CLASS__) {

        return parent::model($className);

    }


    public function tableName() {

        return 'carrinho';

    }


    public function rules() {

        return array(

            array('codcarrinho, codproduto, quant, sessao', 'required'),

            array('codcarrinho, quant, codproduto', 'numerical', 'integerOnly' => true),

            array('sessao', 'length', 'max' => 32),

            array('codcarrinho, codproduto, quant, sessao', 'safe', 'on' => 'search'),

        );

    }


    public function attributeLabels() {

        return array(

            'codcarrinho' => 'Id',

            'codproduto' => 'Produto',

            'quant' => 'Quantidade',

            'sessao' => 'Sessão',

        );

    }


    public function shoppingCart() {


        if (!is_null(Yii::app()->user->getState('carrinho'))) {

            $dados = json_decode(Yii::app()->user->getState('carrinho'));

            

            foreach ($dados as $key => $value) {

                $produto = Produto::model()->findByPk((int) $value->codproduto);

                if (!is_null($produto)) {

                    $row['id'] = $key;

                    $row['codproduto'] = $produto->primaryKey;

                    $row['titulo'] = $produto->titulo;

                    $row['codigo'] = $produto->codigo;

                    $row['quantidade'] = $value->quantidade;

                    $row['url'] = $produto->url;

                    $row['imagem'] = $produto->pasta.$produto->imagem_destaque[0]->mini;

                }

                $rawData[] = $row;

            }

        }

        

        if(is_null($rawData)){

            $rawData = array();

        }


        return new CArrayDataProvider($rawData, array(

                    'id' => 'codproduto',

                    'pagination' => array(

                        'pageSize' => 10,

                    ),

                ));


    }


}