2

First things first, the story about this article.

Recently I've created an Wordpress Plugin WordPress - WP - Keywords To Tooltip | CodeCanyon

After a few days, somebody asked me if it's working with Wordpress Multi Site, initially scared, I didn't expect it to be so easy, I've achieved the transition and make it compatible in under an hour.

Why ? Because all the code written was OOP, so it was a piece of cake to modify where needed

public function _activationHook() {
    global $wpdb;

    $query = file_get_contents($this->scriptBasePath . 'model/install.sql');

    $query = str_replace($this->database->_table_prefix ,
                         $wpdb->base_prefix . $this->database->_table_prefix,
                         $query);

    $queries = explode(';', $query);


    foreach($queries as $query)
      if(strlen($query)> 20)
        $response = $wpdb->query($query);
  }

  public function _deactivationHook() {
    global $wpdb;

    $wpdb->query("DROP TABLE IF EXISTS " . $this->database->_keyword_table);
  }

What was needed to make the plugin WP Multi site ? Not too much actually, I had to extend my methods to have another way to interact with two "special case handles" ( specifically on Network Activate si Deactive )

$old_blog = $wpdb->blogid;

$blogids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");

foreach ($blogids as $blog_id) {
    switch_to_blog($blog_id);
    // The action handled now, activate or deactivate.
}

switch_to_blog($old_blog);

Lucky me, writting OOP always and everywhere, I could easily modify everything.

  public function _wpActivationHook($networkwide) {
    $this->_networkPropagationHook('_internalActivationHook', $networkwide);
  }

  public function _wpDeactivationHook($networkwide) {
    $this->_networkPropagationHook('_internalDeactivationHook', $networkwide);
  }

Why did I wrote the proxy function in the first place ?
Because the only difference for the two calls where the next executed function, so I've generalized the code so nice, and added a variable which specifies the next method to be called.

public function _wpActivationHook($networkwide) {
    $this->_networkPropagationHook('_internalActivationHook', $networkwide);
  }

  public function _wpDeactivationHook($networkwide) {
    $this->_networkPropagationHook('_internalDeactivationHook', $networkwide);
  }

  public function _networkPropagationHook($propagationAction, $networkwide) {
    global $wpdb;

    if (function_exists('is_multisite') && is_multisite()) {
      if ($networkwide) {
        $old_blog = $wpdb->blogid;

        $blogids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");

        foreach ($blogids as $blog_id) {
          switch_to_blog($blog_id);
          $this->$propagationAction();
        }

        switch_to_blog($old_blog);
        return;
      }
    }

    $this->$propagationAction();
  }

  public function _internalActivationHook() {
    global $wpdb;

    $query = file_get_contents($this->scriptBasePath . 'model/install.sql');

    $query = str_replace($this->database->_table_prefix ,
                         $wpdb->base_prefix . $this->database->_table_prefix,
                         $query);

    $queries = explode(';', $query);


    foreach($queries as $query)
      if(strlen($query)> 20)
        $response = $wpdb->query($query);
  }

  public function _internalDeactivationHook() {
    global $wpdb;

    $wpdb->query("DROP TABLE IF EXISTS " . $this->database->_keyword_table);
  }

The Conclusion :

WP Multi Site Integration is not something hard, but there's a few things you need to give consideration, luckily $wpdb->_table_prefix is set on the current site, and you can the good prefix for any website if you se the switch_to_blog() function.

There's also one more thing, in the application, the user could select colors for certain elements, I could've added these inline, but I had the CSS selector :after, so I had to create a CSS file or just paste the CSS everytime, but from a Optimize view, I considered a CSS File would do the best.

  private function _getCurrentFrontGeneratedStylePath() {
    return (function_exists('is_multisite') && is_multisite()) ?
            $this->frontGeneratedStylePathPrefix . '-' . get_current_blog_id() . $this->frontGeneratedStylePathPostfix
            : $this->frontGeneratedStylePathPrefix . $this->frontGeneratedStylePathPostfix;

  }

I will check if it's a multi_site ( the current website used by the plugin ), if indeed it is a multi site, I will add -[blog-id] at the file ending ( then the extension "frontGeneratedStylePathPostfix" )

Ok, I hope you enjoyed my article, I wrote this while enjoying my Coffee, I tough it's something I would share with the rest

Feedback & Comments are welcome.

3
Contributors
3
Replies
66
Views
3 Years
Discussion Span
Last Post by Robert Rusu
0

Excellent!

OOP is great for exactly this use-case, but, be cautioned, OOP design should be carefully considered, it can also lead to a whole nightmare of intricate dependencies and completely un-understandable logic and hierachial structures.

Great article, with solid examples.

3

Nice example. Just a rant. I hate WP's "OOP" because of this:

global $wpdb;

This goes against all that OO stands for, and although I understand the ease of use, it's absolutely horrible.

Votes + Comments
Globals are gone in the latest PHP aren't they?
1

@pritaeas

Yes, I know, I've used it only there like that ( was in a rush kind of :) ), but I store that in another model usually in the construct => it's pretty much more clean

public function __construct() {

  $this->wp_db = $wpdb;

  // Example after
  $this->_keyword_table  = 
    $this->wp_db->base_prefix . $this->_table_prefix . $this->_keyword_table;
}

Edited by Robert Rusu: organization of code

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.