I’m using Cart2Cart, which for like $100 will migrate all of our Zen Cart products with additional images as well as creating 301 redirects from the original site to the new one. Kind of cool.
I’m using Docker and specifically Docker-compose for development. I’m using the WP plugin Error Log Monitor to check for php errors and this requires setting up error logging on the development server.
Here’s how ya do that with Docker:
Get the name of the Docker image:
docker ps
Then get into the server:
docker exec -ti my_server_1 bash
Install vim:
apt-get update && apt-get install vim
Create your php error log file:
vim /var/www/php-errors.log
Then you add a couple of lines to your wp-config
file following plugin directions.
I may add a couple of directives to my bash script that creates the Docker-compose instance to map the file to the server:
if [ $# -eq 0 ] ; then
echo usage: directory_name
else
WPDIR="$1"
mkdir "$WPDIR" && cd "$WPDIR"
touch 'php-errors.log'
cat >> docker-compose.yml <<EOL
my-wpdb:
image: mariadb
ports:
- "8081:3306"
environment:
MYSQL_ROOT_PASSWORD: dockerpass
my-wp:
image: wordpress
volumes:
- ./:/var/www/html
- php-errors.log:/var/www/php-errors.log
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: dockerpass
my-wpcli:
image: tatemz/wp-cli
volumes_from:
- my-wp
links:
- my-wpdb:mysql
entrypoint: wp
command: "--info"
EOL
docker-compose up -d
fi
The first challenge is that it was pulling in the small version of the images, when we need that full size images.
So I created some mod_rewrite
rules and conditions with the help of some Stack Overflow here and here. Came up with this:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
# from our domain
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
# isn't one of the large ones, which would create an infinite loop
RewriteCond %{REQUEST_URI} !^/images/large/
# a large version of the document exists
RewriteCond %{DOCUMENT_ROOT}/images/large/$1/$2_LRG.$3 -f
RewriteRule ^images/(.*)/(.*)\.(jpe?g|png)$ images/large/$1/$2_LRG.$3 [E=VAR1:$1,E=VAR2:$2,E=VAR3:$3,L,NC]
RewriteRule ^images/(.*))\.(jpe?g|png)$ images/large/$1_LRG.$2 [E=VAR1:$1,E=VAR2:$2,L,NC]
I also experimented with adding the NC
(No Escape) flag to deal with image files that had spaces in the names.
Images are importing now, but the metadata (_wp_attachment_metadata
) is all wrong. There is an easy way to fix this, fortunately. Fix my posts plugin. Apparently the [Regenerate Thumbnails}(https://wordpress.org/plugins/regenerate-thumbnails/) plugin does this.
Since Cart2Cart is not terribly inexpensive, I plan to backup the database & the uploads directory as soon as it’s complete.
Imported all 500 “Products” to local dev server and checked the box to download and import the images, but none of the images made it to the local dev server. So I replaced the local UPLOADS directory with the one we’d imported to. But I had also forgotten to update the URLs in the wordpress export file. Not only did wordpress not recognize the images because they hadn’t been uploaded through the WP uploader, but when I did upload them that way, they weren’t attached to the products. I used Media Cleaner plugin to remove the images and another one that removes all the WooCommerce product images.
This WPMUDev post had the key for migrating the attachments.
Ended up having added an extra slash in the local URL and had to replace those:
UPDATE wp_posts
SET guid = replace(guid, 'http://localhost:8080//wp-content', 'http://localhost:8080/wp-content')
WHERE guid LIKE '%http://localhost:8080//wp-content%';
This has been tricky and the Bulk Delete plugin is being useful as well. Did I mention Media Cleaner from Meow Apps?
Using the projects-by-woothemes
plugin as a starting point for our Project Archive.
Added a couple of files from WooCommerce to support a gallery for each project:
To migrate the categories from WooCommerce am hoping that the Convert Post Types plugin will do the trick. Also found this sql query:
UPDATE wp_term_taxonomy SET taxonomy='project-category' WHERE taxonomy='product_cat';
So two steps:
- Convert Post Types with plugin from products to projects.
- Run the above sql query.
Now we have Projects in Project Categories. Nice.
Next step I want to migrate the woocommerce breadcrumbs to the Project, which ended up being more work than seemed to make sense, so for now I am using this code:
if( !function_exists( 'inspiry_get_breadcrumbs_items' ) ) :
/**
* Returns a array of breadcrumbs items
*
* Source: https://gist.github.com/saqibsarwar/471cb91a6b17ffc457e2
* @param $post_id int Post id
* @param $breadcrumbs_taxonomy string Taxonomy name
* @return mixed|void
*/
function inspiry_get_breadcrumbs_items( $post_id, $breadcrumbs_taxonomy ) {
// Add home at the beginning of the breadcrumbs
$inspiry_breadcrumbs_items = array(
array(
'name' => __( 'Home', 'inspiry' ),
'url' => esc_url( home_url('/') ),
'class' => '',
)
);
// Get all assigned terms
$the_terms = get_the_terms( $post_id, $breadcrumbs_taxonomy );
if ( $the_terms && ! is_wp_error( $the_terms ) ) :
$deepest_term = $the_terms[0];
$deepest_depth = 0;
// Find the deepest term
foreach( $the_terms as $term ) {
$current_term_depth = inspiry_get_term_depth( $term->term_id, $breadcrumbs_taxonomy );
if ( $current_term_depth > $deepest_depth ) {
$deepest_depth = $current_term_depth;
$deepest_term = $term;
}
}
// work on deepest term
if ( $deepest_term ) {
// Get ancestors if any and add them to breadcrumbs items
$deepest_term_ancestors = get_ancestors( $deepest_term->term_id, $breadcrumbs_taxonomy );
if ( $deepest_term_ancestors && ( 0 < count( $deepest_term_ancestors ) ) ) {
$deepest_term_ancestors = array_reverse( $deepest_term_ancestors ); // reversing the array is important
foreach ( $deepest_term_ancestors as $term_ancestor_id ) {
$ancestor_term = get_term_by( 'id', $term_ancestor_id, $breadcrumbs_taxonomy );
$inspiry_breadcrumbs_items[] = array(
'name' => $ancestor_term->name,
'url' => get_term_link( $ancestor_term, $breadcrumbs_taxonomy ),
'class' => ''
);
}
}
// add deepest term
$inspiry_breadcrumbs_items[] = array(
'name' => $deepest_term->name,
'url' => get_term_link( $deepest_term, $breadcrumbs_taxonomy ),
'class' => ''
);
}
endif;
// Add the current page / property
$inspiry_breadcrumbs_items[] = array(
'name' => get_the_title( $post_id ),
'url' => '',
'class' => 'active',
);
return apply_filters( 'inspiry_breadcrumbs_items', $inspiry_breadcrumbs_items );
}
endif;
if( !function_exists( 'inspiry_get_term_depth' ) ) :
/**
* Returns an integer value that tells the term depth in it's hierarchy
*
* @param $term_id
* @param $term_taxonomy
* @return int
*/
function inspiry_get_term_depth( $term_id, $term_taxonomy ) {
$term_ancestors = get_ancestors( $term_id, $term_taxonomy );
if ( $term_ancestors ) {
return count( $term_ancestors );
}
return 0;
}
endif;
Which is represented in:
//source: https://gist.github.com/saqibsarwar/471cb91a6b17ffc457e2
global $post;
$inspiry_breadcrumbs_items = inspiry_get_breadcrumbs_items( $post->ID, 'project-category' );
if ( is_array( $inspiry_breadcrumbs_items ) && ( 0 < count( $inspiry_breadcrumbs_items ) ) ) {
?>
<nav class="projects-breadcrumb">
<?php
foreach( $inspiry_breadcrumbs_items as $item ) :
$class = ( !empty( $item['class'] ) ) ? 'class="' . $item['class'] . '"' : '';
if ( !empty ( $item['url'] ) ) :
?>
<a href="<?php echo esc_url( $item['url'] ); ?>" <?php echo $class ?>><?php echo $item['name']; ?></a>
<span class="breadcrumb-separator"> / </span>
<?php
else :
?>
<?php echo $item['name']; ?>
<?php
endif;
endforeach;
?>
</nav>
<?php
}
Discovered two bash functions to dump and restore the MySQL database from Docker container:
function dumpdb()
{
# source https://stackoverflow.com/a/46042938/2223106
# source https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb
local wkdir=`basename $PWD`
local container='echo ${wkdir}_my-wpdb_1'
docker exec ${container} mysqldump -uroot --password=password wordpress > backup.sql
}
function restoredb()
{
# source: see above
local wkdir=`basename $PWD`
local container="${wkdir}_my-wpdb_1"
cat backup.sql | docker exec -i ${container} /usr/bin/mysql -u root --password=dockerpass wordpress
}
Also that you can source
a file any time from any where. So I added these to a file within the WP subdirectory where I keep my Docker projects.
Learned that running set -x
before gives you detailed output as the commands are interpolated. Running set +x
turns off the verbose output.
Migrating the Woo categories to Project categories while retaining the hierarchy has been a challenge. I found some good code that looks promising (again). So far haven’t gotten it working, but I came across an old plugin, [Post Type Convertr] (https://wordpress.org/plugins/post-type-convertr/) that’s actually doing the trick.
On the production server, I also needed to run the following SQL query after migrating with the Post Type Convertr plugin:
UPDATE wp_term_taxonomy SET taxonomy='project-category' WHERE taxonomy='product_cat';
.