代码之家  ›  专栏  ›  技术社区  ›  bikey77

面向所有开发人员的WordPress多站点和单一数据库

  •  3
  • bikey77  · 技术社区  · 7 年前

    我正在为WordPress多站点设置规划开发团队工作流。我们之所以选择multisite,是因为我们想限制更新/升级过程,也是因为我们的绝大多数客户在后端都有相同的网站结构/要求。对于前端,我们正在使用一个“普通”主题,其中包含我们的css/js框架和主要设置、帖子类型、选项等,我们将基于我们的普通主题构建所有网站,并通过子主题为每个客户端扩展它。 我决定将所有内容都置于版本控制(Git)之下,甚至WordPress核心文件也是如此。

    就我们当前的开发环境而言:我们一直在使用一个集中的web服务器,而不是LAMP堆栈或VVV/Docker设置,每个开发人员通过url访问其项目,该url通过每个项目(站点)使用单独的vhost映射到其本地repo。所以,在处理projectA时,John的url是 http://john.projectA.dev ,而Jack的url是 http://jack.projectA.dev .

    为了确保数据一致性、公共设置等,对所有开发人员使用相同的DB最初似乎是一种“合乎逻辑”的方式,但我还无法做到这一点。由于WordPress在wp\U选项表中存储siteurl和homeurl URL的方式,我无法找到通过URL将John映射到他将要处理的站点的方法,也无法允许所有开发人员访问通用多站点的wp管理员,该管理员默认为用户的URL之一(即 http://bob.wpmulisite.dev 其中Bob是最初设置多站点环境的开发人员。 我试图通过在每个开发人员的自定义wp配置中定义URL来覆盖URL,但由于wp\u HOME和wp\u SITEURL在wp multisite中被忽略,所以这还不够。

    我不喜欢必须使用db转储,替换转储中的URL并为每个用户将其导入到数据库中的想法,因为我担心这个过程很快会导致问题,并会造成太多的合并、差异等。然而,我可能错了,我绝对愿意接受任何建议。

    我已经在上面概述了我的主要问题,如果你觉得不清楚,我很乐意重新措辞。目前,我不太确定您可能会对什么级别的详细信息感兴趣,所以请问我,我会深入了解。

    2 回复  |  直到 7 年前
        1
  •  6
  •   cr0ybot    7 年前

    好吧,让我带你去旅行吧。

    您的集中式开发环境听起来非常独特,但我认为我们可以使用它。我设置了一个类似的系统:我们有一个带有公共域/ip的“暂存”服务器供客户端查看,每个开发人员都有一个通过git在本地机器上的完整副本,其中有一个本地Apache服务器。我们将本地开发人员站点指向中央临时服务器数据库,以便内容/设置保持一致。我们使用自定义本地域访问本地开发人员站点,如 http://example.local ,临时站点为 http://example.staging.com ,现场将是 http://example.com .

    作为旁白,我们有 wp-config.php 在里面 .gitignore ,因此我们可以在本地副本上对其进行自定义。通常,我们将临时版本和实时版本保留为不同名称的文件,如 wp-config-live.php 并将其符号链接到 wp配置。php 这样我们也可以在我们的私有git repo中保留配置设置。

    现在,我们想在 example.local 还可以通过子文件夹访问其网络站点( example.local/site2/ )或在vhost设置中使用别名的其他自定义域( example2.local )在每台计算机上。此外,临时站点应该在没有任何 git pull 在服务器上。最重要的是,实时站点应该 而且 使用简单的 git拉动 没有任何数据库编辑。我们如何做到这一点?

    首先,我们 wp-config 所有实时/登台/开发环境都应包含标准的多站点设置:

    define( 'WP_ALLOW_MULTISITE', true );
    define( 'MULTISITE', true );
    define( 'SUBDOMAIN_INSTALL', false );
    define( 'DOMAIN_CURRENT_SITE', 'example.com' );
    define( 'PATH_CURRENT_SITE', '/' );
    define( 'SITE_ID_CURRENT_SITE', 1 );
    define( 'BLOG_ID_CURRENT_SITE', 1 );
    

    请注意 DOMAIN_CURRENT_SITE 居住 领域为了使整个系统正常工作,数据库中定义的域都应该是活动域,我们将使用以下内容处理每个登台/开发站点 wp配置 (仅在开发/暂存配置上,不在实时配置中):

    /** Set this to your local tld setup */
    define( 'WP_HOME', 'http://example.local');
    define( 'WP_SITEURL', 'http://example.local');
    /** Include wp-content/sunrise.php */
    define( 'SUNRISE', true );
    /** This should be the TLD in the database */
    define( 'WP_PROD_TLD', '.com' );
    /** This should be the tld of your local copy */
    define( 'WP_DEV_TLD', '.local');
    

    这个 WP_PROD_TLD WP_DEV_TLD 是我们自己的自定义常量,我们将使用它来检查是否需要更改域(我知道您在设置中也使用子域,但在尝试适合您的具体情况之前,我想描述一种稍微“标准”的方法)。这个 SUNRISE 常量内置于WP multisite中,只表示包含 /wp-content/sunrise.php 如果存在。这是我们的 sunrise.php 文件:

    <?php
    /**
     * File sunrise.php
     *
     * This allows us to copy the production multisite database to staging/dev and still use 
     * it directly without altering domains
     */
    
    /**
     * Filter /wp-includes/ms-load.php get_site_by_path to find production domains
     **/
    function dev_get_site_by_path($_site, $_domain, $_path, $_segments, $_paths) {
        global $wpdb, $path;
    
        // Get our actual domain in the database (should be set to production domain)
        // The domain coming in should be the request domain
        $domain = str_replace( WP_DEV_TLD, WP_PROD_TLD, $_domain);
    
        // Search for a site matching the domain and first path segment
        $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s and path = %s", $domain, $_paths[0] ) );
        $current_path = $_paths[0];
    
        if ($site === null) {
        // Specifically for the main blog - if a site is not found then load the main blog
            $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s and path = %s", $domain, '/' ) );
            $current_path = '/';
        }
    
        // Set path to match the first segment
        $path = $current_path;
    
        return $site;
    }
    add_filter('pre_get_site_by_path', 'dev_get_site_by_path', 1, 5);
    add_filter('pre_get_network_by_path', 'dev_get_site_by_path', 1, 5);
    
    /**
     * Filter the site_url and home options for each site, and
     * filter /wp-includes/link-template.php::network_site_url()
     * and /wp-includes/link-template.php::network_home_url()
     * so that our network site link is correct in the admin menu
     */
    function dev_network_url( $_url = '' ) {
        return str_replace( WP_PROD_TLD, WP_DEV_TLD, $_url );
    }
    add_filter( 'network_site_url', 'dev_network_url' );
    add_filter( 'network_home_url', 'dev_network_url' );
    add_filter( 'option_siteurl', 'dev_network_url' );
    add_filter( 'option_home', 'dev_network_url' );
    

    请注意 日出php 文件为 仅在开发/登台时通过WP-CONFIG包含 ,从不在实时服务器上!这是过滤请求以“按路径”获取网络,这意味着它查看从客户端请求的域和路径,并匹配 wp_blogs 桌子我们正在检查域中的live TLD(在本例中, .com )并将其替换为当前环境的TLD(我们的本地副本为 .local ,临时服务器为 .staging.com ). 它还过滤 WP_HOME WP_SITEURL 底部每个站点的选项。

    就这样!正在为您的本地/临时站点设置动态翻译数据库中的活动域!只要您正在使用子文件夹或在本地vhost设置中设置了别名,这就应该可以工作。

    现在,对于使用子域的情况,您可能需要对域进行更彻底的过滤,而不是仅仅替换TLD。也许您满足于数据库中的“规范”域 multisite.dev 然后在你的 日出php 文件只需附加本地用户的子域,而不是替换TLD,然后在准备迁移后在数据库中替换活动域。

    感谢“laubsterboy”让我开始使用此解决方案: https://www.laubsterboy.com/blog/2014/08/running-development-copy-wordpress-multisite-update/

        2
  •  0
  •   John Dee    7 年前

    此建议适用于插件开发。不是“设计”或特定于客户的主题开发:

    如果您是从头开始建立WordPress开发商店,我强烈建议您学习如何使用Codeception中的WordPress模块进行行为和测试驱动开发。它可以从不同的角度进行各种测试[验收、WPunit测试、功能测试等]。它可以轻松地在需要整个数据库转储、无转储、URL替换、空白数据库等的测试之间切换,并且可以根据需要进行混合和匹配。

    进行TDD的主要原则之一是,测试之间的依赖性应该最小。你说的这些共享设置是什么?这些应该尽可能地减少。当您这样做时,您可以将设置逐个列出,而不是将其视为某种有机整体。

    例如,假设您正在制作一个插件,无论出于何种原因,它都需要一种特定的永久链接结构。实现这一点的一种方法是您所建议的:即使用某种共享服务,开发人员可以访问一个环境,在这个环境中,他们可以获得所需的永久链接结构。有点像所有猪都去吃的地方。

    另一种方法是将此需求放到单元测试环境中,然后直接放到git repo中。需求随git中的代码一起分发。然后,当您在开发时,您将从一个完全不存在的角度工作,除了您正在处理的需求。该模块从空白WordPress安装开始。在这种情况下,它将是完全空白的,除了我们正在做的事情,这将是一个特定的永久链接结构。但它可以是任何内容:自定义帖子类型、特定数据集、整个数据库、客户机数据等等。

    与其尝试在一系列设置中捕获所有这些设置,不如捕获您正在处理的设置,并将其放在测试的前面和中心。因此,需要这种特定permalink的插件应该可以在任何其他设置中工作。例如,该插件可以与任何主题一起使用。既然您的需求已经构建到测试中,那么您的程序员在什么样的环境中工作都无关紧要了。这允许您使用远程外包商,并使您的团队具有灵活性。如果有人想在笔记本电脑上使用Eclipse,也有人想在基于云的PHPstorm IDE上工作,那没关系。他将项目和相关设置与代码放在一起。这会使您的代码更加稳定,因为它是在任何环境中都能正常工作的情况下设计的。

    以下是使用此结构设置插件的教程: https://wordpress-bdd.com/wp-codeception-tutorial/