Putting in setup knowledge for a WordPress plugin

by | Mar 6, 2024 | Etcetera | 0 comments

When making a WordPress plugin, one crucial step is to pre-install crucial wisdom, ensuring the plugin operates simply from the get-go. Take, for example, an events manager plugin. Upon arrange, it’s immensely beneficial if the plugin robotically generates a internet web page titled Upcoming Events, showing a listing of longer term events.

This pre-configured internet web page, embedded with a shortcode like [event_list number="10" scope="future" status="publish"], allows shoppers to right away leverage the plugin’s purposes without finding out by means of its documentation.

Putting in place wisdom turns out to be useful not most straightforward when first setting up the plugin, however as well as when because of this truth updating it. For instance, if an change introduces a calendar view feature, the plugin can robotically create a brand spanking new internet web page, Events Calendar, showcasing this addition by means of a shortcode similar to [event_calendar status="publish"].

In most cases, the scope of knowledge arrange spans quite a lot of needs:

  • Generating new pages with particular titles and contents.
  • Together with entries for custom designed put up types (CPTs) created during the plugin.
  • Putting default settings into the wp_options table
  • Assigning new purposes to shopper roles
  • Assigning metadata to shoppers, for new or up-to-the-minute choices provided during the plugin (e.g. shoppers might exchange the advance date format, and a default worth is first added for all shoppers)
  • Creating categories many times used within the plugin’s context, similar to “conferences” or “sports activities actions.”

Putting in place wisdom should be an incremental process, differently we could create copy entries.

For instance, if a plugin style 1.1 introduces an Upcoming Events internet web page and a shopper updates from style 1.0, most straightforward the new wisdom associated with style 1.1 will have to be installed. This incremental change promises that when style 1.2 rolls out with the calendar feature, most straightforward the new Events Calendar internet web page is added, fending off any duplication of the Upcoming Events internet web page.

Due to this fact, when up-to-the-minute, the plugin should retrieve what previous style was once installed, and arrange the guidelines that corresponds to the new style(s) most straightforward.

This newsletter explains easy methods to arrange initial wisdom, and keep together with new wisdom with further updates, in our WordPress plugins.

Providing the prevailing style

To handle the incremental process, the plugin should observe its provide style, maximum continuously declared inside the header of the plugin’s major document. Then again in truth, we can’t reference it right away from there, because it’s inside a PHP commentary. So we moreover define this worth in a variable and provide it to a Plugin elegance accountable for initialization and configuration:

setup();

The Plugin elegance, leveraging PHP 8.0’s Constructor assets promotion characteristic, stores this style, so we can reference it later on:

<?php

elegance Plugin {

  public function __construct(
    protected string $pluginVersion,
  ) {}

  public function setup(): void
  {
    // Initialization just right judgment proper right here...
  }

  // ...
}

Notice how the great judgment to initialize and configure the plugin is added to the setup way, not the constructor. That’s given that constructor should avoid producing undesirable unwanted side effects; differently, we could produce bugs when extending or composing the Plugin elegance.

Let’s see how that would possibly happen. Let’s say we one day add a BetterPlugin elegance that composes capacity from the Plugin elegance:

elegance BetterPlugin {

  public function printSomething(): string
  {
    $pluginVersion = '1.0';
    $plugin = new Plugin($pluginVersion);
    return '
' . $plugin->printSomething() . '
'; } }

On each and every instance executing new Plugin() inside printSomething, a brand spanking new instance of Plugin is created. If the configuration just right judgment had been added to the constructor, it is going to be completed every time we create a brand spanking new Plugin object. In our case, we need to create the Upcoming Events internet web page most straightforward once, not a few events. By means of together with the great judgment to the setup way, we can avoid this downside.

See also  What is WYSIWYG? How As of late’s On-line Editor Got here to Be

Tracking the previous style

WordPress does not provide a to hand option to retrieve the style of the plugin being modified. Due to this fact, we can must store this worth thru ourselves inside the wp_options table of the database.

Store the style underneath get right of entry to "myplugin_version", where myplugin_ is the determine of the plugin (e.g. eventsmanager_version). It’s vital to all the time prepend all our settings with myplugin_, to avoid conceivable conflicts, as we can’t make sure that each and every different plugin won’t add a style risk.

When loading the plugin on each and every request, Plugin will already know what the prevailing style (from property $pluginVersion earlier on), and will retrieve without equal saved style from the database. This comparison determines the plugin’s status:

  • New arrange: detects if the database lacks a style get right of entry to for the plugin, indicating first-time setup (i.e. $storedPluginVersion is null)
  • Substitute: Known when the prevailing style exceeds the database-stored style, signaling an strengthen requirement.
  • Otherwise, there’s no exchange

On each and every instance there is a exchange, we identify prepareAndInstallPluginSetupData to position in the most efficient wisdom, whether or not or now not for a brand spanking new arrange (during which case it is going to must arrange all wisdom for all diversifications) or an change (arrange wisdom only for the entire new diversifications). The nullable $previousVersion variable indicates which scenario it is ($previousVersion is null => new arrange).

After calling the program, we can must moreover store the prevailing plugin style on the database, becoming the new “final saved” style. This should be carried out after calling prepareAndInstallPluginSetupData so that if the program produces an error (e.g., throwing a RuntimeException) and information is not installed, the previous style remains to be saved on the database, and a brand spanking new round of setting up wisdom it will likely be attempted on the next request.

managePluginDataVersioning();
  }

  /**
   * If the plugin has merely been newly-installed + activated
   * or up-to-the-minute, arrange the most efficient wisdom.
   */
  protected function managePluginDataVersioning(): void
  {
    $myPluginVersionOptionName = 'myplugin_version';
    $storedPluginVersion = get_option($myPluginVersionOptionName, null);

    // Check out if the main plugin has been activated or up-to-the-minute
    $isPluginJustFirstTimeActivated = $storedPluginVersion === null;
    $isPluginJustUpdated = !$isPluginJustFirstTimeActivated && $storedPluginVersion !== $this->pluginVersion;

    // If there were no changes, now not the rest to do
    if (!$isPluginJustFirstTimeActivated && !$isPluginJustUpdated) {
      return;
    }

    add_action(
      'init',
      function () use ($myPluginVersionOptionName, $storedPluginVersion): void {
        $this->prepareAndInstallPluginSetupData($storedPluginVersion);

        // Substitute on the DB
        update_option($myPluginVersionOptionName, $this->pluginVersion);
      }
    );
  }

  protected function prepareAndInstallPluginSetupData(?string $previousVersion): void
  {
    // Arrange just right judgment...
  }
}

Notice that prepareAndInstallPluginSetupData (and the next DB change) is completed on the init motion hook. This is to make certain that all wisdom from the CMS is able for retrieval and manipulation.

In particular, taxonomies (tags and categories) can’t be accessed ahead of the init hook. If the plugin’s arrange process needed to create a CPT get right of entry to and assign a custom designed magnificence to it, this process might most straightforward run from the init hook onwards.

Getting access to without equal saved style from the DB on every request is not perfect from a efficiency stance. To reinforce this, combine the entire possible choices sought after during the plugin into an array, store them in a single get right of entry to, and then get admission to they all with a single identify to the DB.

See also  How to Style a Grid Item in Divi’s Filterable Portfolio Module

For instance, if the plugin moreover needed to store a myplugin_date_format option to display the advance date, we can create a single get right of entry to myplugin_options with homes style and date_format.

To get admission to without equal saved style, the PHP code should be then adapted like this:

pluginVersion;
        update_option($myPluginOptionsOptionName, $myPluginOptions);
      }
    );
  }
}

Keeping off concurrent requests setting up copy wisdom

There may be the danger that the arrange process may be triggered more than as quickly as though two or additional shoppers get admission to the wp-admin at exactly the identical time. To avoid the identical wisdom being installed two occasions or additional, we use a temporary as a flag to allow most straightforward the main request to position in wisdom:

  • Check out if brief myplugin_installing_plugin_setup_data exists (once all over again, this determine should be prepended with myplugin_); if this is the case, don’t the rest (as another process is setting up the guidelines)
  • Otherwise, store the brief inside the database for an inexpensive maximum time frame to position within the knowledge (e.g., 30 seconds)
  • Arrange the guidelines
  • Delete the brief

This is the code:

installPluginSetupData($previousVersion);
    delete_transient($transientName);
  }

  protected function installPluginSetupData(?string $previousVersion): void
  {
    // Do something...
  }
}

Putting in place wisdom for all diversifications

As mentioned earlier, if updating the plugin, we can must most straightforward arrange the guidelines for the new diversifications, not all of them. That means that we wish to organize what wisdom to position in style thru style.

Throughout the code beneath, array $versionCallbacks indicates what function to execute for each and every style with the function executing the great judgment to position within the knowledge. We iterate the document of all of them, review each and every in opposition to the previous style the usage of version_compare and, if it is higher, execute the corresponding function to position within the corresponding wisdom.

Notice that if $previousVersion is null (i.e., it’s a brand spanking new arrange), then all functions are completed.

elegance Plugin {
  /**
   * Provide the arrange in stages, style thru style, to
   * have the ability to execute it each and every when setting up/activating the plugin,
   * or updating it to a brand spanking new style with setup wisdom.
   *
   * The plugin's setup wisdom it will likely be installed if:
   *
   * - $previousVersion = null => Activating the plugin for first time
   * - $previousVersion  Updating to a brand spanking new style that has wisdom to position in
   */
  protected function installPluginSetupData(?string $previousVersion): void
  {
    $versionCallbacks = [
      '1.1' => $this->installPluginSetupDataForVersion1Dot1(...),
      '1.2' => $this->installPluginSetupDataForVersion1Dot2(...),
      // ... Add more versions
    ];
    foreach ($versionCallbacks as $style => $callback) {
      /**
       * If the previous style is equipped, check out if the corresponding change
       * has already been performed, then skip
       */
      if ($previousVersion !== null && version_compare($previousVersion, $style, '>=')) {
        continue;
      }
      $callback();
    }
  }

  protected function installPluginSetupDataForVersion1Dot1(): void
  {
    // Do something...
  }

  protected function installPluginSetupDataForVersion1Dot2(): void
  {
    // Do something...
  }
}

Putting in place wisdom for each and every particular style

In the end, we can must arrange the real wisdom (create a internet web page, a CPT get right of entry to, add an risk, and so on) for each and every style.

In this code, we add the Upcoming Events internet web page for the events manager plugin, for v1.1:

elegance Plugin {
  
  // ...

  protected function installPluginSetupDataForVersion1Dot1(): void
  {
    wp_insert_post([
      'post_status' => 'publish',
      'post_type' => 'page',
      'post_title' => __('Upcoming Events', 'myplugin'),
      'post_content' => '[event_list number="10" scope="future"]',
    ]);
  }

  // ...
}

Then, we create the Events Calendar internet web page for v1.2 (in this case, the usage of Gutenberg blocks on the internet web page, together with a custom designed block known as event-calendar):

elegance Plugin {
  
  // ...

  protected function installPluginSetupDataForVersion1Dot2(): void
  {
    wp_insert_post([
      'post_status' => 'publish',
      'post_type' => 'page',
      'post_title' => __('Events Calendar', 'myplugin'),
      'post_content' => serialize_blocks([
        [
          'blockName' => 'myplugin/event-calendar',
          'attrs' => [
            'status' => 'publish',
          ],
          'innerContent' => [],
        ],
      ]),
    ]);
  }
}

All code together

We are carried out! The entire PHP code for the Plugin magnificence, containing the great judgment to track the plugin style and arrange the most efficient wisdom, is the following:

managePluginDataVersioning();
  }

  /**
   * If the plugin has merely been newly-installed + activated
   * or up-to-the-minute, arrange the most efficient wisdom.
   */
  protected function managePluginDataVersioning(): void
  {
    $myPluginVersionOptionName = 'myplugin_version';
    $storedPluginVersion = get_option($myPluginVersionOptionName, null);

    // Check out if the main plugin has been activated or up-to-the-minute
    $isPluginJustFirstTimeActivated = $storedPluginVersion === null;
    $isPluginJustUpdated = !$isPluginJustFirstTimeActivated && $storedPluginVersion !== $this->pluginVersion;

    // If there were no changes, now not the rest to do
    if (!$isPluginJustFirstTimeActivated && !$isPluginJustUpdated) {
      return;
    }

    add_action(
      'init',
      function () use ($myPluginVersionOptionName, $storedPluginVersion): void {
        $this->prepareAndInstallPluginSetupData($storedPluginVersion);

        // Substitute on the DB
        update_option($myPluginVersionOptionName, $this->pluginVersion);
      }
    );
  }

  /**
   * Use a short lived to make certain that only one instance
   * will arrange the guidelines. Otherwise, two requests
   * taking place at the same time as might each and every execute
   * this just right judgment
   */
  protected function prepareAndInstallPluginSetupData(?string $previousVersion): void
  {
    $transientName = 'myplugin_installing_plugin_setup_data';
    $brief = get_transient($transientName);
    if ($brief !== false) {
      // Every other instance is executing this code this present day
      return;
    }

    set_transient($transientName, true, 30);
    $this->installPluginSetupData($previousVersion);
    delete_transient($transientName);
  }

  /**
   * Provide the arrange in stages, style thru style, to
   * have the ability to execute it each and every when setting up/activating the plugin,
   * or updating it to a brand spanking new style with setup wisdom.
   *
   * The plugin's setup wisdom it will likely be installed if:
   *
   * - $previousVersion = null => Activating the plugin for first time
   * - $previousVersion  Updating to a brand spanking new style that has wisdom to position in
   */
  protected function installPluginSetupData(?string $previousVersion): void
  {
    $versionCallbacks = [
      '1.1' => $this->installPluginSetupDataForVersion1Dot1(...),
      '1.2' => $this->installPluginSetupDataForVersion1Dot2(...),
      // ... Add more versions
    ];
    foreach ($versionCallbacks as $style => $callback) {
      /**
       * If the previous style is equipped, check out if the corresponding change
       * has already been performed, then skip
       */
      if ($previousVersion !== null && version_compare($previousVersion, $style, '>=')) {
        continue;
      }
      $callback();
    }
  }

  protected function installPluginSetupDataForVersion1Dot1(): void
  {
    wp_insert_post([
      'post_status' => 'publish',
      'post_type' => 'page',
      'post_title' => __('Upcoming Events', 'myplugin'),
      'post_content' => '[event_list number="10" scope="future" status="publish"]',
    ]);
  }

  protected function installPluginSetupDataForVersion1Dot2(): void
  {
    wp_insert_post([
      'post_status' => 'publish',
      'post_type' => 'page',
      'post_title' => __('Events Calendar', 'myplugin'),
      'post_content' => serialize_blocks([
        [
          'blockName' => 'myplugin/event-calendar',
          'attrs' => [
            'status' => 'publish',
          ],
          'innerContent' => [],
        ],
      ]),
    ]);
  }
}

Summary

WordPress plugins often wish to arrange wisdom upon arrange. In addition to, as more moderen diversifications of the plugin provide new choices, the plugin might also wish to arrange wisdom when up-to-the-minute.

See also  15 Commonplace PC Issues and How one can Troubleshoot Them

In this article, we found out easy methods to observe diversifications and arrange the most efficient wisdom for our plugins.

Do you could have a WordPress plugin that can have the advantage of setting up wisdom? Let us know inside the comments.

The put up Putting in setup knowledge for a WordPress plugin seemed first on Kinsta®.

WP Hosting

[ continue ]

WordPress Maintenance Plans | WordPress Hosting

read more

0 Comments

Submit a Comment