Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUCD_Data::copy_data() doesn't correctly replace all strings #90

Open
pbiron opened this issue Oct 25, 2019 · 1 comment
Open

MUCD_Data::copy_data() doesn't correctly replace all strings #90

pbiron opened this issue Oct 25, 2019 · 1 comment

Comments

@pbiron
Copy link

pbiron commented Oct 25, 2019

A very simple way to replicate the problem is:

  1. create a sub-directory multisite (e.g., with main site URL https://example.test)
  2. add a post to the main site that contains a gallery block (with "Link To: Attachment page")
  3. add an image to the gallery
  4. save the post
  5. duplicate the main site (e.g., with new site URL https://example.test/new-site)
  6. examine the post_content in the new site and you'll see that while the img/@src has been correctly replaced, the a/@href (and @img/@data-link) has not!

Note: this problem is not a result of plugin/theme custom tables in the main site not being duplicated.

For example, given post_content in the main site such as:

<!-- wp:gallery {"ids":[1592],"imageCrop":false,"linkTo":"attachment"} -->
<figure class="wp-block-gallery columns-1">
  <ul class="blocks-gallery-grid">
    <li class="blocks-gallery-item">
      <figure>
        <a href="https://example.test/my-post/my-image">
          <img src="https://example.test/wp-content/uploads/2019/10/my-image.jpg" alt="" data-id="1592" data-link="https://example.test/my-post/my-image/" class="wp-image-1592"/>
        </a>
        <figcaption class="blocks-gallery-item__caption">My cption</figcaption>
      </figure>
    </li>
  </ul>
</figure>
<!-- /wp:gallery -->

it should result in post_content in the new site such as:

<!-- wp:gallery {"ids":[1592],"imageCrop":false,"linkTo":"attachment"} -->
<figure class="wp-block-gallery columns-1">
  <ul class="blocks-gallery-grid">
    <li class="blocks-gallery-item">
      <figure>
        <a href="https://example.test/new-site/my-post/my-image">
          <img src="https://example.test/new-site/wp-content/uploads/sites/2/2019/10/my-image.jpg" alt="" data-id="1592" data-link="https://example.test/new-site/my-post/my-image/" class="wp-image-1592"/>
        </a>
        <figcaption class="blocks-gallery-item__caption">My cption</figcaption>
      </figure>
    </li>
  </ul>
</figure>
<!-- /wp:gallery -->

However, the actual post_content in the new site is:

<!-- wp:gallery {"ids":[1592],"imageCrop":false,"linkTo":"attachment"} -->
<figure class="wp-block-gallery columns-1">
  <ul class="blocks-gallery-grid">
    <li class="blocks-gallery-item">
      <figure>
        <a href="https://example.test/my-post/my-image">
          <img src="https://example.test/new-site/wp-content/uploads/sites/2/2019/10/my-image.jpg" alt="" data-id="1592" data-link="https://example.test/my-post/my-image/" class="wp-image-1592"/>
        </a>
        <figcaption class="blocks-gallery-item__caption">My cption</figcaption>
      </figure>
    </li>
  </ul>
</figure>
<!-- /wp:gallery -->

As mentioned, this has to do with the way MUCD::replace() is written. What happens is the following:

  1. MUCD_Data::db_update_data() calls MUCD_Data::update() which eventually calls MUCD_Data::replace( 'the post content', 'https://example.test/wp-content/uploads', 'https://example.test/new-site/wp-content/uploads/sites/2 )
    • That replacement happens correctly
  2. MUCD_Data::db_update_data() calls MUCD_Data::update() which eventually calls MUCD_Data::replace( 'the post content', 'https://example.test', 'https://example.test/new-site' )
    • That replacement does not happen correctly
    • the reason is that MUCD::replace() notices that the $val already contains 'https://example.test/new-site' (because of the previous replacement) and so does not do the replacement
    • this particular problem can be fixed in MUCD::db_update_data() by changing the order of the strings in $string_to_replace, putting $from_blog_url => $to_blog_url first
    • that works since $to_blog_url will be shorter than $to_upload_url (unless a site has done something really weird with changing the location of their uploads folder), and therefore, it is much more likely that $to_upload_url will not already exist in the post_content
    • however, I haven't tested enough to know whether changing the order of the replacements causes other problems
@d2roth
Copy link

d2roth commented Apr 21, 2020

I ran into the same problem and made this gist:
https://gist.github.com/d2roth/47ea5af7a2a8f581a631e39b77b19a57

Essentially it is just a plugin which sorts the replacement values so that it replaces the shortest ones first. This does mean the database prefix is the first replacement to run but it also means you don't need to hard-code the source/destination URLs and can just add it to /wp-content/mu-plugins/ so it does the replacement for you everywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants