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

multi-site #50

Closed
AlexECP opened this issue Jan 25, 2016 · 20 comments
Closed

multi-site #50

AlexECP opened this issue Jan 25, 2016 · 20 comments

Comments

@AlexECP
Copy link

AlexECP commented Jan 25, 2016

Hi,

Thanks for a great project!

If I am connecting to a multi-site wordpress, is there a way for me to change the prefix without needing to run \Corcel\Database::connect($params); again with the new prefix specified? This is for a project where I am connecting to our wordpress and posting articles to hundreds of sites.

@AlexECP
Copy link
Author

AlexECP commented Jan 25, 2016

Let me know if this is the right path:
I changed the connect method to return the capsule, then I can do $capsule->getConnection()->setTablePrefix('new_prefix_here')

Ill try it out in the meantime and let you know...

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

Hi @AlexECP. If you're using Laravel you does not have to call connect method. It's a very good suggestion to return Capsule instance in connect method.

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

Done! ;-) Commit: 5b5798f

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

@AlexECP just an advice. The change was made in dev branch.

@jgrossi jgrossi closed this as completed Jan 25, 2016
@AlexECP
Copy link
Author

AlexECP commented Jan 25, 2016

awesome. For my specific use case I need to connect even though Im on Laravel, since the wordpress DB is external.
Using getConnection()->setTablePrefix('new_prefix_here') worked for me for our multi-site installation... possible someone else might want that advice...
anyways Thanks!

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

Welcome @AlexECP. If you're using Corcel with Laravel you can create a new connection on Laravel config files and set it to your Wordpress models, like Post, for example. Just set protected $connection = 'wordpress' and that's it. As Eloquent is already loaded by Laravel, Corcel only have to call it using the connection you've provided. Welcome!

@AlexECP
Copy link
Author

AlexECP commented Jan 25, 2016

ah I see, then I would just do something like $post->getConnection()->setTablePrefix(...) ? Right?
Thanks

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

Yes and no @AlexECP hehe. It's better to you set the table prefix in the connection configuration array (config folder) so every model you have $connection = 'wordpress' for example you're going to use the table prefix you've just set. Easy ;-)

@AlexECP
Copy link
Author

AlexECP commented Jan 25, 2016

right, but for my case where its a multi-site, I will need to be changing the prefix all the time for example to publish a new post to 200 sites... before each save I will need to alter the prefix, I think

@jgrossi
Copy link
Member

jgrossi commented Jan 25, 2016

Hummm ok ;-) Maybe in the future we can think in a generic solution to this using Corcel :-)

@gbrits
Copy link

gbrits commented May 22, 2017

Can't seem to find any documentation concerning corcel/corcel communicating with a multisite Wordpress installation - has nothing been written yet for this? Currently I have for example site_posts for my initial Wordpress node, and my prefix would then be site_ the first site in the network would then be site_1 ie site_1_posts. So in this instance, that'd be what @AlexECP was suggesting - if you want to reach the posts for a site in your network, it appears, with this solution that you'd have to change the prefix on the fly in order to "select" which site in your network to query from on the fly.

@gbrits
Copy link

gbrits commented May 22, 2017

I've settled with this solution, which seems to work for now:

class Post extends Corcel
{
    protected $connection = 'wordpress';
    protected $postType = 'post';
    public function __construct($whichSite) {
        $this->connection = $whichSite;
    }
}

Then I just set multiple connections inside of config/database.php and call them upon the class invocation.

$main = new \App\Post('wordpress');
$main->published()->get();
$adelaide = new \App\Post('adelaide');
$adelaide->published()->get();

Not sure if this method is just sluggish or going to cause multiple connections / other issues? Would be keen to hear from someone else attempting this.

@AharonFeinstein
Copy link

I think having to setup multiple connection inside of config/database.php is not realistic for a large multisite installation. When I need to edit batches of sites just use do the following:

$post = new \App\Post;
foreach (\App\Website::get() as $website){
   $post->getConnection()->setTablePrefix('wp_'.$website->wordpress_site_id.'_');
   ...logic...
}

I also sometimes create static functions that take the wordpress site id as a parameter, and start with:

 public static function sample($wordpress_site_id){
        $post = new self;
        $post->getConnection()->setTablePrefix('wp_'.$wordpress_site_id.'_'); 
        ...
}

@jgrossi
Copy link
Member

jgrossi commented May 25, 2017

Hy @AharonFeinstein thanks for the contribution. I guess maybe it's better to create a scopeNetwork() for that, receiving an ID or website name:

$posts = Post::network(123)->where(..)->get();

Actually there's no official support for multisite into Corcel but of course, that would be an excellent contribution! Be welcome!

@bluehaoran
Copy link
Contributor

Hi @jgrossi, thanks for writing Corcel!

It's perfect for the project we're about to work on, except that we definitely need multi-site functionality. I will use some of the suggestions above to start with, but I'd also be keen to put some work into extending Corcel to do it natively.

But before I do, I'd love to know your thoughts on how best to do this.

@jgrossi
Copy link
Member

jgrossi commented Apr 19, 2018

Hi @bluehaoran thanks for the kind words. About multi-site, Corcel works as a library, a composer package. There's no way to work with multiple websites using just a single database connection, but you can have as many database connections you want to, changing the prefix for each one. So using something like Post::on('website2')->all().

Would this help?

@bluehaoran
Copy link
Contributor

@jgrossi thanks for taking the time to reply.

As I see it, there are two problems to solve with multi-site:

  1. It feels inefficient to use two connections--one with a 'wp_' prefix and one a wp_X_' prefix. In the same request, I might well want access to wp_users, wp_options, and wp_2_posts and wp_2_postmeta.

I'm thinking that in this circumstance, you'd tweak the logic around generating the $table property of Corcel\Model\Post and Corcel\Model\User etc.

  1. A separate, more difficult but less frequent problem is when I need access to something form wp_2_posts and wp_3_posts in the same request. This is the case where having multiple connections seems most sensible, although I like your suggestion above for using Scopes to apply the getConnection()->setTablePrefix() trick explained above.

Is that sensible?

@jgrossi
Copy link
Member

jgrossi commented Apr 20, 2018

@bluehaoran actually you can access both database connections in the same request. The on() method on Post::on($connection) would access that connection and the wp_posts table for that specific connection:

$posts = Post::on('site_1')->all(); // posts from `wp_posts`
$posts = Post::on('site_2')->all(); // posts from `wp_2_posts`

Just to let things clear, the on() is not a scope actually, it's a Eloquent method that change from which connection you're accessing from.

@bluehaoran
Copy link
Contributor

If you're on this thread, here's a little bug I picked up with Connections in Laravel (laravel/framework#26589). This mainly became an issue for me writing unit tests, but YMMV.

@jgrossi
Copy link
Member

jgrossi commented Nov 23, 2018

@bluehaoran actually, about the laravel/framework#26589 that's the expected behavior. can you explain better which test you wrote?

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

5 participants