Opencart With Yii

Hello All,

I think I have started something which won’t attract much attention, but that’s my current requirement.

I have tried to merge Yii with OpenCart and so failed miserably.

What I want is to have open cart on the frontend and yii merged with the opencart backend.

To achieve this, I have written the following lines in index.php of opencart (both catalog i.e. root and admin)




// yii code

$server = ($_SERVER['HTTP_HOST'] == 'localhost' || preg_match('/^192.168.15.\d{1,3}$/', $_SERVER['HTTP_HOST']) ? 'development' : (($_SERVER['HTTP_HOST'] == 'mywebsite.com') || ($_SERVER['HTTP_HOST'] == 'www.mywebsite.com') ? 'production' : 'unknown'));


// change the following paths if necessary

$yii = dirname(__FILE__) . '/../../yii/framework/yii.php';

$yii_config = dirname(__FILE__) . '/../protected/config/main.php';


// remove the following lines when in production mode

if ($server == 'development') {

    defined('YII_DEBUG') or define('YII_DEBUG', true);

    // specify how many levels of call stack should be shown in each log message

    defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 3);

}


require_once($yii);

Yii::createWebApplication($yii_config);



as you can see, instead of running the app, I just stopped at creating it.

In next step, I edited the not_found.php in catalog/controller/error as




    public function index() {


        try {

            // YII code begins

            //header('Location:' . ($_SERVER['HTTP_HOST'] == 'localhost' ? '/mywebsite.com' : '' ) . '/yii.php/' . $_GET['_route_']);

            //die();

            Yii::app()->run($_GET['_route_']);

            // YII code ends

        } catch (Exception $e) {

            $this->language->load('error/not_found');


            $this->document->setTitle($this->language->get('heading_title'));


            $this->data['breadcrumbs'] = array();


            $this->data['breadcrumbs'][] = array(

                'text' => $this->language->get('text_home'),

                'href' => $this->url->link('common/home'),

                'separator' => false

            );


            if (isset($this->request->get['route'])) {

                $this->data['breadcrumbs'][] = array(

                    'text' => $this->language->get('text_error'),

                    'href' => $this->url->link($this->request->get['route']),

                    'separator' => $this->language->get('text_separator')

                );

            }


            $this->data['heading_title'] = $this->language->get('heading_title');


            $this->data['text_error'] = $this->language->get('text_error');


            $this->data['button_continue'] = $this->language->get('button_continue');


            $this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . '/1.1 404 Not Found');


            $this->data['continue'] = $this->url->link('common/home');


            if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/error/not_found.tpl')) {

                $this->template = $this->config->get('config_template') . '/template/error/not_found.tpl';

            } else {

                $this->template = 'default/template/error/not_found.tpl';

            }


            $this->children = array(

                'common/column_left',

                'common/column_right',

                'common/content_top',

                'common/content_bottom',

                'common/footer',

                'common/header'

            );


            $this->response->setOutput($this->render());

        }

    }



As you can see the committed line




//header('Location:' . ($_SERVER['HTTP_HOST'] == 'localhost' ? '/mywebsite.com' : '' ) . '/yii.php/' . $_GET['_route_']);



which I am using for production server, i.e. redirecting works fine

The problem starts when I commit this line and tries to run any of the following


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

or


Yii::app()->run($_GET['_route_']);

or


Yii::app()->runController($_GET['_route_']);

In all of the above case, I found out that basic component files are not loaded in Yii and Yii returns with the exception

Unable to Resolve the {route}

To further explore the problem, I extended the CWebApplication to WWebApplication and over written the createController() function.

What I found is that all of the Routes modules and controllers are loaded, but none of the components are present, and on CWebApplication.php at line 345 it fails on the check


if(class_exists($className,false) && is_subclass_of($className,'CController'))

The problem is, $className is loaded, and so is Controller BUT CController is not loaded and the it says Controller is not a subClass of CController.

In short, when we execute the line


Yii::createWebApplication($config)->run();

everything works fine.

but if we use it other way round, i.e.


Yii::createWebApplication($config);

and later somewhere


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

The basic components get lost, and Yii cannot decide which class belongs to which.

How to overcome this problem? Any idea?

Well, I have faced another face (or rather phase) of reality.

OpenCart too has a class name Controller, which is not a sub class of CController.

To overcome this problem and for the sake of argument, I renamed the Controller.php in protected/compotents to WController.php and the class name WController. Now it does not give the same error BUT

it now says Call to undefined method

Language::tableName() in yii/framework/db/ar/CActiveRecord.php on line 2262

Here Language is a model class under procted/models/Language.php subclass of CActiveRecord.

I don’t know why it fails now.

Need further help.

Thanks in advance

OpenCart declares its own Language class (system/library/language.php). It might be a good idea to prefix all classnames in your Yii application.

Thanks, that helped a lot, actually my Language Class with system class never collides, but Opencart cart has it’s own Language Class.

So changing to WLanguage and changing the Controller to WController worked perfectly.

Now everything seems to be working fine, and I can smoothly switch from opencart to yii menu (jumping around).

Also running the Yii controllers worked fine.

Soon I will update the content which will help some people who think merging opencart with yii is a good idea

Hello All

Here is the complete step by step guide on how to merge opencart and yyii smoothly.

integrate-opencart-and-yii

Excellent - many thanks, Rehan!

Hi, thanks so much for your contribution, nicely done! :) I encountered some error when I tried to integrate the apps and at last succesfully integrate the apps with a slight modification. I am no expert in Open Cart / Yii, so I dunno if the modification I made is the best solution or not.

When the user logout, it displayed error :





Warning: session_destroy() [function.session-destroy]: Trying to destroy uninitialized session in D:\xampp\htdocs\drive\vqmod\vqcache\vq2-system_library_user.php on line 80


Warning: Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\drive\admin\index.php:105) in D:\xampp\htdocs\drive\vqmod\vqcache\vq2-system_engine_controller.php on line 28


Warning: Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\drive\admin\index.php:105) in D:\xampp\htdocs\drive\vqmod\vqcache\vq2-system_engine_controller.php on line 29




So I modify function logout of vq2-system_library_user.php to be as below :




if(isset(Yii::app()->user->id)) {

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

} else {

   session_destroy();

}



Because every time I call Yii::app()->user->logout(), it will destroy the session. If I call session_destroy() again then it will display warning.

Another error I encountered is when I call Yii::app()->user->login(), Yii CHttpSession started the session again when the session is already started by Open Cart, it displays warning and error :





Notice: A session had already been started - ignoring session_start() in D:\xampp\htdocs\yii\framework\web\CHttpSession.php on line 117


Notice: A session had already been started - ignoring session_start() in D:\xampp\htdocs\yii\framework\web\CHttpSession.php on line 117


Warning: session_regenerate_id() [function.session-regenerate-id]: Cannot regenerate session id - headers already sent in D:\xampp\htdocs\yi[url="http://www.yiiframework.com/forum/index.php/topic/15916-about-license/"]here[/url]\framework\web\CHttpSession.php on line 186


Warning: Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\drive\admin\index.php:105) in D:\xampp\htdocs\drive\vqmod\vqcache\vq2-system_engine_controller.php on line 28


Warning: Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\drive\admin\index.php:105) in D:\xampp\htdocs\drive\vqmod\vqcache\vq2-system_engine_controller.php on line 29




The simplest solution I could think of now is to modify the way CHttpSession create session, it is to add validation before @session_start() on line 115. But I just read here that I may not modify the core code. Please advice what is the best solution ? Many thanks

In your Yii config, something like this…




return array(

    'components' => array(

        'session' => array(

            'class' => 'HttpSession',

        ),

    ),

);



Then create components/HttpSession.php…




class HttpSession extends CHttpSession {

    // extend parent methods, or add your own methods

}