企业级电子商务与供应链解决方案供应商.
联系我们

+86-13006619568

info@cnopencart.com

深圳,苏州,成都,上海,杭州

扫二维码加微信
wechat

深圳,苏州

+86-16606168892

Top

opencart网站升级数据搬迁

opencart网站升级数据搬迁

使用opencart比较早的朋友应该用的都是比较老版本的opencart系统,随着时代的变化,为了让网站能够有更大的数据承受能力,优化用户体验,opencart的版本也在不断的...

文章目录 [+]

使用opencart比较早的朋友应该用的都是比较老版本的opencart系统,随着时代的变化,为了让网站能够有更大的数据承受能力,优化用户体验,opencart的版本也在不断的更新,

很多老用户都想让自己的网站升级到opencart的最新版本,升级版本其实最和谐的就是搬迁原网站的数据,但是对于opencart最新版本数据表的一些变化却又不是很清楚,不知道改如何将旧版的opencart数

据搬迁到最新版本的opencart系统中,下面就为大家示范一次如何将opencart1.5.6.4版本数据搬迁到opencart3.0.3.2版本中。

它的整理逻辑流程是:让新版本opencart系统同时连接新旧版本的数据库-->比对需要搬迁信息数据表的字段 --> 找出数据表差异后 查询旧版本数据库数据,修改后 用opencart新版本自带的方法导入数据。

第一步,我们先搭建一个最新版本opencart网站在本地(自己的电脑上)。然后把自己opencart旧版本的整个数据库下载出来,新建一个空的数据库并导入进去。

完成后我们打开新版本程序的system/framework.php,在连接数据库的地方(全文件查询// Database,大概在第78行)连接刚刚新建的旧版本数据库。

// Database 
if ($config->get('db_autostart')) {
   $registry->set('db', new DB($config->get('db_engine'), $config->get('db_hostname'), $config->get('db_username'), $config->get('db_password'), $config->get('db_database'), $config->get('db_port')));
   //新建一个连接数据库的方法,这里注意前面 要set(不同方法名),这样待会儿调用旧版本数据库,因为是本地创建的,在同一数据库里,账户密码都一样,这里我们只用输入不同的数据库名称即可。
   $registry->set('edb', new DB($config->get('db_engine'), $config->get('db_hostname'), $config->get('db_username'), $config->get('db_password'), 'testdatabases.1564', $config->get('db_port')));
}

第二步:比对数据库中数据表的字段有什么不一样的,为什么要比对数据库的字段呢,因为opencart的很多数据功能基本上都是基于数据来实现的,所以数据存在的时候,功能就能够正常使用了。下面是我对

比分类数据表的部分示范。(温馨提示:如果大家对opencart数据库表结构还不够可以查看opencart 3.0 版本数据库数据表字典(详细篇) ,其实找到信息相关数据表还有一个规律的,例如你想找商品相关的数据表,在admin后台商品管理页面的路由是route=catalog/product,所以在opencart数据库中搜索product,一般表前缀(一般默认的是oc_)+product开头的都是商品信息相关联的数据表。

   根据上面的提示蓝色文字内容,我们可以知道opencart新旧版本的分类数据相关的表一共有6个(oc_category,oc_category_description,oc_category_filter , oc_category_path ,

  oc_category_to_layout , oc_category_to_store),下面只为大家展示了分类两张表的对比。

下图是对比分类主表, 我们可以看出分类主表新版本与旧版本字段无差别,

下图是对比分类描述表,分类描述数据表中,opencart新版的分类描述数据表中多了一个meta_title的字段。

第三步:删除对应的数据(这一步骤在后台操作,这样删除数据比较全面且方便,如果对表结构了解,可以跳过这一步直接去数据库清空表),并在数据库中操作情况数据(这一步骤在数据库中进行,是必要操作,主要是为了避免导入旧网站数据时 主键冲突)。

后台删除数据

数清空数据库相关数据表的信息

第四步:添加查询opencart旧版本数据库数据的方法(下面的代码片段是搬迁分类相关数据的方法)。

查询方法(controller文件)代码,这个方法我放在了admin\controller\catalog\category.php文件中方便调用。

    public function move() {
      $this->load->model('catalog/old_category');
      $this->load->model('catalog/category');

      //查询所有分类
      $categories = $this->model_catalog_old_category->getCategories($data=array());

      if($categories){
         foreach($categories as $category){
//查询单个分类的详细信息
            $category_info = $this->model_catalog_old_category->getCategory($category['category_id']);

            if($category_info){
            /*将分类的数据放入数组,这里最关键的点 应该是大家不知道用哪些方法才能把分类的所有数据查询出来放入数组中,
            其实这些查询方法在admin\controller\catalog\category.php文件中都是有已经完善了的。我们找到opencart旧版本的
            admin\controller\catalog\category.php文件中getForm()方法,这个方法是显示分类详情页,里面有查询分类的详细方法,
            我们只用把相关的查询方法搬出来用即可。
            */
               $data = $category_info;
               $data['category_description'] = $this->model_catalog_old_category->getCategoryDescriptions($category['category_id']);
               $data['category_filter'] = $this->model_catalog_old_category->getCategoryFilters($category['category_id']);
               $data['category_store'] = $this->model_catalog_old_category->getCategoryStores($category['category_id']);
               $data['category_seo_url'] = $this->model_catalog_old_category->getSeoUrl($category['category_id']);
               $data['category_layout'] = $this->model_catalog_old_category->getCategoryLayouts($category['category_id']);

               $this->model_catalog_old_category->moveCategory($data);

            }

         }

      }

      $category_total = $this->model_catalog_category->getTotalCategories($data=array());
      echo $category_total;
//    print_r($data['category_seo_url']);exit;
   }

查询数据库(model文件),这里就要用上我们之前在system/framework.php系统框架文件中连接的旧版本数据库了。下面代码中注意我在查询旧版本数据库数据的时候用的$this->edb->query(........)方法,

在最下方的数据插入到新版本opencart数据库的时候,用的是$this->db->query(.....)方法,在插入数据时我们还要特别注意的是对应数据表字段不同的地方要赋值。下面所有的查询方法,都是直接从旧版本里对应的方法搬用过。

<?php
class ModelCatalogOldCategory extends Model {
   public function getCategory($category_id) {
      $query = $this->edb->query("SELECT DISTINCT *, (SELECT GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR ' &gt; ') FROM oc_category_path cp LEFT JOIN oc_category_description cd1 ON (cp.path_id = cd1.category_id AND cp.category_id != cp.path_id) WHERE cp.category_id = c.category_id AND cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' GROUP BY cp.category_id) AS path, (SELECT keyword FROM oc_url_alias WHERE query = 'category_id=" . (int)$category_id . "') AS keyword FROM oc_category c LEFT JOIN oc_category_description cd2 ON (c.category_id = cd2.category_id) WHERE c.category_id = '" . (int)$category_id . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'");

      return $query->row;
   } 

   public function getCategories($data) {
      $sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR ' &gt; ') AS name, c.parent_id, c.sort_order FROM oc_category_path cp LEFT JOIN oc_category c ON (cp.path_id = c.category_id) LEFT JOIN oc_category_description cd1 ON (c.category_id = cd1.category_id) LEFT JOIN oc_category_description cd2 ON (cp.category_id = cd2.category_id) WHERE cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'";

      $sql .= " GROUP BY cp.category_id ORDER BY name";

      if (isset($data['start']) || isset($data['limit'])) {
         if ($data['start'] < 0) {
            $data['start'] = 0;
         }           

         if ($data['limit'] < 1) {
            $data['limit'] = 20;
         }  

         $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
      }

      $query = $this->edb->query($sql);

      return $query->rows;
   }

   public function getCategoryDescriptions($category_id) {
      $category_description_data = array();

      $query = $this->edb->query("SELECT * FROM oc_category_description WHERE category_id = '" . (int)$category_id . "'");

      foreach ($query->rows as $result) {
         $category_description_data[$result['language_id']] = array(
            'name'             => $result['name'],
            'meta_keyword'     => $result['meta_keyword'],
            'meta_description' => $result['meta_description'],
            'description'      => $result['description']
         );
      }

      return $category_description_data;
   }  

   public function getCategoryFilters($category_id) {
      $category_filter_data = array();

      $query = $this->edb->query("SELECT * FROM oc_category_filter WHERE category_id = '" . (int)$category_id . "'");

      foreach ($query->rows as $result) {
         $category_filter_data[] = $result['filter_id'];
      }

      return $category_filter_data;
   }

   public function getCategoryStores($category_id) {
      $category_store_data = array();

      $query = $this->edb->query("SELECT * FROM oc_category_to_store WHERE category_id = '" . (int)$category_id . "'");

      foreach ($query->rows as $result) {
         $category_store_data[] = $result['store_id'];
      }

      return $category_store_data;
   }

   public function getCategoryLayouts($category_id) {
      $category_layout_data = array();

      $query = $this->edb->query("SELECT * FROM oc_category_to_layout WHERE category_id = '" . (int)$category_id . "'");

      foreach ($query->rows as $result) {
         $category_layout_data[$result['store_id']] = $result['layout_id'];
      }

      return $category_layout_data;
   }


   public function getSeoUrl($category_id) {
      $category_seo_url = array();

      $query = $this->edb->query("SELECT keyword FROM oc_url_alias WHERE query = 'category_id=" . (int)$category_id . "'");

      if($query->row){

         $this->load->model('localisation/language');

         $languages = $this->model_localisation_language->getLanguages();

         foreach($languages as $language){
            $category_seo_url[0][$language['language_id']] = $query->row['keyword'];
         }

      }

      return $category_seo_url;
   }
/*插入旧版本数据方法,这里我们要注意的是,它和新增数据的方法比,它多了一个主键插入,因为搬迁数据时包含了插入主键,而不是让它自己生成。
这里我再次强调一遍,在插入数据时我们还要特别注意的是对应数据表字段不同的地方要赋值。例如上面对比分类描述数据表的时候,新版opencart分类描述数据库多了一个meta_title字段,这里我们要么给它赋一个其他的值,要么为空。*/
   public function moveCategory($data) {
   
      $this->db->query("INSERT INTO " . DB_PREFIX . "category SET category_id = '" .(int)$data['category_id'].  "', parent_id = '" . (int)$data['parent_id'] . "', `top` = '" . (isset($data['top']) ? (int)$data['top'] : 0) . "', `column` = '" . (int)$data['column'] . "', sort_order = '" . (int)$data['sort_order'] . "', status = '" . (int)$data['status'] . "', date_modified = '" .$data['date_modified'] . "', date_added = '" .$data['date_added'] . "'");

      if (isset($data['image'])) {
         $this->db->query("UPDATE " . DB_PREFIX . "category SET image = '" . $this->db->escape($data['image']) . "' WHERE category_id = '" . (int)$data['category_id'] . "'");
      }

      foreach ($data['category_description'] as $language_id => $value) {
         $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$data['category_id'] . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', description = '" . $this->db->escape($value['description']) . "', meta_title = '" . $this->db->escape($value['name']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "'");
      }

      // MySQL Hierarchical Data Closure Table Pattern
      $level = 0;

      $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE category_id = '" . (int)$data['parent_id'] . "' ORDER BY `level` ASC");

      foreach ($query->rows as $result) {
         $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = '" . (int)$data['category_id'] . "', `path_id` = '" . (int)$result['path_id'] . "', `level` = '" . (int)$level . "'");

         $level++;
      }

      $this->db->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = '" . (int)$data['category_id'] . "', `path_id` = '" . (int)$data['category_id'] . "', `level` = '" . (int)$level . "'");

      if (isset($data['category_filter'])) {
         foreach ($data['category_filter'] as $filter_id) {
            $this->db->query("INSERT INTO " . DB_PREFIX . "category_filter SET category_id = '" . (int)$data['category_id'] . "', filter_id = '" . (int)$filter_id . "'");
         }
      }

      if (isset($data['category_store'])) {
         foreach ($data['category_store'] as $store_id) {
            $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_store SET category_id = '" . (int)$data['category_id'] . "', store_id = '" . (int)$store_id . "'");
         }
      }

      if (isset($data['category_seo_url']) && !empty($data['category_seo_url'])) {
         foreach ($data['category_seo_url'] as $store_id => $language) {
            foreach ($language as $language_id => $keyword) {
               if (!empty($keyword)) {
                  $this->db->query("INSERT INTO " . DB_PREFIX . "seo_url SET store_id = '" . (int)$store_id . "', language_id = '" . (int)$language_id . "', query = 'category_id=" . (int)$data['category_id'] . "', keyword = '" . $this->db->escape($keyword) . "'");
               }
            }
         }
      }

      // Set which layout to use with this category
      if (isset($data['category_layout'])) {
         foreach ($data['category_layout'] as $store_id => $layout_id) {
            $this->db->query("INSERT INTO " . DB_PREFIX . "category_to_layout SET category_id = '" . (int)$data['category_id'] . "', store_id = '" . (int)$store_id . "', layout_id = '" . (int)$layout_id . "'");
         }
      }
   }
}
?>

第五步:访问第四步中的方法,执行导入数据。

网站域名/admin/index.php?route=catalog/category/move&user_token=JHDahsFHJKBASashjkasdKKjGHFVjjCVl

其实上面的步骤看起来略显复杂,但是在操作一遍后就会发现其中的规律,这样的方法也是可以重复利用的。如果大家对上面的功能或者数据库数据表字段功能不清楚的欢迎来提问。